Files
PDI-MAKER/frontend/app/workspace/[slug]/page.tsx
Sergio Correa 0524656198 🚀 Initial commit - PDIMaker v1.0.0
Sistema completo de gestão de PDI com:
- Autenticação com email/senha e Google OAuth
- Workspaces privados isolados
- Sistema de convites com código único
- Interface profissional com Next.js 14
- Backend NestJS com PostgreSQL
- Docker com Nginx e SSL

Desenvolvido por Sergio Correa
2025-11-19 02:09:04 +00:00

264 lines
9.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// app/workspace/[slug]/page.tsx
import { redirect } from "next/navigation"
import { getServerSession } from "next-auth"
import { authOptions } from "@/lib/auth/config"
import { prisma } from "@/lib/prisma"
import Link from "next/link"
import { CopyButton } from "@/components/CopyButton"
interface WorkspacePageProps {
params: { slug: string }
}
export default async function WorkspacePage({ params }: WorkspacePageProps) {
const session = await getServerSession(authOptions)
if (!session) {
redirect("/login")
}
const workspace = await prisma.workspace.findUnique({
where: { slug: params.slug },
include: {
employee: { select: { id: true, name: true, email: true, avatar: true } },
manager: { select: { id: true, name: true, email: true, avatar: true } },
hr: { select: { id: true, name: true, email: true, avatar: true } }
}
})
if (!workspace) {
redirect("/workspaces")
}
// Verificar se o usuário tem acesso
const hasAccess =
workspace.employeeId === session.user.id ||
workspace.managerId === session.user.id ||
workspace.hrId === session.user.id
if (!hasAccess) {
redirect("/unauthorized")
}
// Determinar o papel do usuário
const userRole =
workspace.employeeId === session.user.id ? "employee" :
workspace.managerId === session.user.id ? "manager" : "hr"
// Buscar código de convite ativo (se for gestor)
let inviteCode = null
if (userRole === "manager") {
const activeInvite = await prisma.invite.findFirst({
where: {
workspaceId: workspace.id,
status: "PENDING",
expiresAt: { gt: new Date() }
},
select: { token: true }
})
inviteCode = activeInvite?.token
}
return (
<div style={{ minHeight: "100vh", background: "#f7fafc" }}>
{/* Header */}
<div style={{ background: "#667eea", color: "white", padding: "1.5rem" }}>
<div style={{ maxWidth: "1200px", margin: "0 auto", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<div>
<h1 style={{ fontSize: "1.5rem", fontWeight: "bold" }}>Workspace</h1>
<p style={{ opacity: 0.9, fontSize: "0.875rem" }}>
Gerencie sua área de colaboração
</p>
</div>
<Link
href="/workspaces"
style={{
padding: "0.5rem 1rem",
background: "rgba(255,255,255,0.2)",
borderRadius: "0.375rem",
textDecoration: "none",
color: "white"
}}
>
Voltar
</Link>
</div>
</div>
<div style={{ maxWidth: "1200px", margin: "0 auto", padding: "2rem" }}>
{/* Código de Convite (apenas para gestores) */}
{userRole === "manager" && inviteCode && (
<div style={{ background: "white", padding: "2rem", borderRadius: "0.5rem", boxShadow: "0 1px 3px rgba(0,0,0,0.1)", marginBottom: "2rem" }}>
<h2 style={{ fontSize: "1.5rem", fontWeight: "bold", marginBottom: "1rem" }}>
Código de Convite
</h2>
<p style={{ color: "#666", marginBottom: "1rem" }}>
Compartilhe este código com seu mentor para que ele possa se juntar ao workspace:
</p>
<div style={{ display: "flex", gap: "1rem", alignItems: "center" }}>
<code style={{
flex: 1,
padding: "1rem",
background: "#f7fafc",
border: "2px solid #e2e8f0",
borderRadius: "0.375rem",
fontSize: "1.25rem",
fontFamily: "monospace",
color: "#667eea"
}}>
{inviteCode}
</code>
<CopyButton text={inviteCode} />
</div>
<div style={{
marginTop: "1rem",
padding: "0.75rem",
background: "#d1fae5",
borderRadius: "0.375rem",
fontSize: "0.875rem",
color: "#047857"
}}>
Mentor conectado! Seu workspace está ativo e pronto para colaboração
</div>
</div>
)}
{/* Membros do Workspace */}
<div style={{ background: "white", padding: "2rem", borderRadius: "0.5rem", boxShadow: "0 1px 3px rgba(0,0,0,0.1)" }}>
<h2 style={{ fontSize: "1.5rem", fontWeight: "bold", marginBottom: "1.5rem" }}>
Membros do Workspace
</h2>
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
{/* Funcionário */}
<div style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "1rem",
background: "#f7fafc",
borderRadius: "0.375rem"
}}>
<div style={{ display: "flex", alignItems: "center", gap: "1rem" }}>
<div style={{
width: "48px",
height: "48px",
borderRadius: "50%",
background: "#667eea",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white",
fontSize: "1.25rem",
fontWeight: "bold"
}}>
{workspace.employee.name[0]}
</div>
<div>
<div style={{ fontWeight: "600" }}>{workspace.employee.name}</div>
<div style={{ fontSize: "0.875rem", color: "#666" }}>{workspace.employee.email}</div>
</div>
</div>
<div style={{
padding: "0.375rem 0.75rem",
background: "#e0e7ff",
borderRadius: "9999px",
fontSize: "0.875rem",
color: "#4c51bf",
fontWeight: "500"
}}>
👨💼 Mentorado
</div>
</div>
{/* Gestor */}
<div style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "1rem",
background: "#f7fafc",
borderRadius: "0.375rem"
}}>
<div style={{ display: "flex", alignItems: "center", gap: "1rem" }}>
<div style={{
width: "48px",
height: "48px",
borderRadius: "50%",
background: "#10b981",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white",
fontSize: "1.25rem",
fontWeight: "bold"
}}>
{workspace.manager.name[0]}
</div>
<div>
<div style={{ fontWeight: "600" }}>{workspace.manager.name}</div>
<div style={{ fontSize: "0.875rem", color: "#666" }}>{workspace.manager.email}</div>
</div>
</div>
<div style={{
padding: "0.375rem 0.75rem",
background: "#d1fae5",
borderRadius: "9999px",
fontSize: "0.875rem",
color: "#047857",
fontWeight: "500"
}}>
🎓 Mentor
</div>
</div>
{/* RH (se existir) */}
{workspace.hr && (
<div style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "1rem",
background: "#f7fafc",
borderRadius: "0.375rem"
}}>
<div style={{ display: "flex", alignItems: "center", gap: "1rem" }}>
<div style={{
width: "48px",
height: "48px",
borderRadius: "50%",
background: "#f59e0b",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white",
fontSize: "1.25rem",
fontWeight: "bold"
}}>
{workspace.hr.name[0]}
</div>
<div>
<div style={{ fontWeight: "600" }}>{workspace.hr.name}</div>
<div style={{ fontSize: "0.875rem", color: "#666" }}>{workspace.hr.email}</div>
</div>
</div>
<div style={{
padding: "0.375rem 0.75rem",
background: "#fef3c7",
borderRadius: "9999px",
fontSize: "0.875rem",
color: "#b45309",
fontWeight: "500"
}}>
👔 RH
</div>
</div>
)}
</div>
</div>
</div>
</div>
)
}