Apply full refactor updates plus pipeline/email UX confirmations
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m33s
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m33s
This commit is contained in:
@@ -1,56 +1,56 @@
|
||||
import { redirect } from 'next/navigation'
|
||||
import { auth } from '@/lib/auth'
|
||||
|
||||
const ROLE_DASHBOARDS: Record<string, string> = {
|
||||
SUPER_ADMIN: '/admin',
|
||||
PROGRAM_ADMIN: '/admin',
|
||||
JURY_MEMBER: '/jury',
|
||||
MENTOR: '/mentor',
|
||||
OBSERVER: '/observer',
|
||||
APPLICANT: '/applicant',
|
||||
}
|
||||
|
||||
export default async function SettingsLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const session = await auth()
|
||||
|
||||
if (!session?.user) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
const dashboardUrl = ROLE_DASHBOARDS[session.user.role] || '/login'
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<header className="sticky top-0 z-40 border-b bg-card">
|
||||
<div className="container mx-auto flex h-16 max-w-3xl items-center px-4">
|
||||
<a
|
||||
href={dashboardUrl}
|
||||
className="flex items-center gap-2 text-sm font-medium text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="m15 18-6-6 6-6" />
|
||||
</svg>
|
||||
Back to Dashboard
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<main className="container mx-auto max-w-3xl px-4 py-6 lg:py-8">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
import { redirect } from 'next/navigation'
|
||||
import { auth } from '@/lib/auth'
|
||||
|
||||
const ROLE_DASHBOARDS: Record<string, string> = {
|
||||
SUPER_ADMIN: '/admin',
|
||||
PROGRAM_ADMIN: '/admin',
|
||||
JURY_MEMBER: '/jury',
|
||||
MENTOR: '/mentor',
|
||||
OBSERVER: '/observer',
|
||||
APPLICANT: '/applicant',
|
||||
}
|
||||
|
||||
export default async function SettingsLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const session = await auth()
|
||||
|
||||
if (!session?.user) {
|
||||
redirect('/login')
|
||||
}
|
||||
|
||||
const dashboardUrl = ROLE_DASHBOARDS[session.user.role] || '/login'
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<header className="sticky top-0 z-40 border-b bg-card">
|
||||
<div className="container mx-auto flex h-16 max-w-3xl items-center px-4">
|
||||
<a
|
||||
href={dashboardUrl}
|
||||
className="flex items-center gap-2 text-sm font-medium text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="m15 18-6-6 6-6" />
|
||||
</svg>
|
||||
Back to Dashboard
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<main className="container mx-auto max-w-3xl px-4 py-6 lg:py-8">
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ export default function ProfileSettingsPage() {
|
||||
|
||||
// Profile form state
|
||||
const [name, setName] = useState('')
|
||||
const [email, setEmail] = useState('')
|
||||
const [bio, setBio] = useState('')
|
||||
const [phoneNumber, setPhoneNumber] = useState('')
|
||||
const [notificationPreference, setNotificationPreference] = useState('EMAIL')
|
||||
@@ -85,6 +86,7 @@ export default function ProfileSettingsPage() {
|
||||
useEffect(() => {
|
||||
if (user && !profileLoaded) {
|
||||
setName(user.name || '')
|
||||
setEmail(user.email || '')
|
||||
const meta = (user.metadataJson as Record<string, unknown>) || {}
|
||||
setBio((meta.bio as string) || '')
|
||||
setPhoneNumber(user.phoneNumber || '')
|
||||
@@ -104,6 +106,7 @@ export default function ProfileSettingsPage() {
|
||||
const handleSaveProfile = async () => {
|
||||
try {
|
||||
await updateProfile.mutateAsync({
|
||||
email: email || undefined,
|
||||
name: name || undefined,
|
||||
bio,
|
||||
phoneNumber: phoneNumber || null,
|
||||
@@ -222,8 +225,16 @@ export default function ProfileSettingsPage() {
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
<Input id="email" value={user.email} disabled />
|
||||
<p className="text-xs text-muted-foreground">Email cannot be changed</p>
|
||||
<Input
|
||||
id="email"
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="you@example.com"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
This will be used for login and all notification emails.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
||||
Reference in New Issue
Block a user