Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/app/dashboard/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,33 @@ import { EmailSettings } from '@/features/dashboard/account/email-settings'
import { PasswordSettings } from '@/features/dashboard/account/password-settings'
import { DangerZone } from '@/features/dashboard/account/danger-zone'
import { Suspense } from 'react'
import { AccessTokenSettings } from '@/features/dashboard/account/access-token-settings'

export default async function AccountPage() {
return (
<DashboardPageLayout
hideFrame
title="Account"
className="grid grid-cols-12 pb-6 max-md:pt-6 md:gap-6"
className="flex flex-col gap-6"
>
<Suspense fallback={null}>
<NameSettings className="col-span-12 md:col-span-6" />
<NameSettings />
</Suspense>

<Suspense fallback={null}>
<EmailSettings className="col-span-12 md:col-span-6" />
<EmailSettings />
</Suspense>

<Suspense fallback={null}>
<PasswordSettings className="col-span-12 md:col-span-6" />
<AccessTokenSettings />
</Suspense>

<Suspense fallback={null}>
<DangerZone className="col-span-12 h-min md:col-span-6" />
<PasswordSettings />
</Suspense>

<Suspense fallback={null}>
<DangerZone />
</Suspense>
</DashboardPageLayout>
)
Expand Down
1 change: 1 addition & 0 deletions src/app/dashboard/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const TAB_URL_MAP: Record<string, (teamId: string) => string> = {
keys: (teamId) => PROTECTED_URLS.KEYS(teamId),
team: (teamId) => PROTECTED_URLS.TEAM(teamId),
account: (_) => PROTECTED_URLS.ACCOUNT_SETTINGS,
personal: (_) => PROTECTED_URLS.ACCOUNT_SETTINGS,
}

export async function GET(request: NextRequest) {
Expand Down
42 changes: 42 additions & 0 deletions src/features/dashboard/account/access-token-settings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use client'

import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/ui/primitives/card'
import { useUser } from '@/lib/hooks/use-user'
import { cn } from '@/lib/utils'
import UserAccessToken from './user-access-token'

interface AccessTokenSettingsProps {
className?: string
}

export function AccessTokenSettings({ className }: AccessTokenSettingsProps) {
const { user } = useUser()

if (!user) return null

return (
<Card className={cn('overflow-hidden rounded-xs border', className)}>
<CardHeader>
<CardTitle>Access Token</CardTitle>
<CardDescription>Manage your personal access token.</CardDescription>
</CardHeader>

<CardContent>
<UserAccessToken className="max-w-lg" />
</CardContent>

<CardFooter className="bg-bg-100 justify-between gap-6">
<p className="text-fg-500 text-sm">
Keep it safe, as it can be used to authenticate with E2B services.
</p>
</CardFooter>
</Card>
)
}
20 changes: 14 additions & 6 deletions src/features/dashboard/account/danger-zone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/ui/primitives/card'
Expand Down Expand Up @@ -49,22 +50,29 @@ export function DangerZone({ className }: DangerZoneProps) {
)

return (
<Card variant="slate" className={cn(className)}>
<Card
className={cn(
'border-error/50 overflow-hidden rounded-xs border',
className
)}
>
<CardHeader>
<CardTitle>Danger Zone</CardTitle>
<CardDescription>
Delete your account and all associated data.
This action is irreversible. It will delete your account and all
associated data.
</CardDescription>
</CardHeader>

<CardContent>
<CardFooter className="bg-error/5 border-error justify-between gap-6">
<p className="text-error-fg text-sm">Continue with caution.</p>
<AlertDialog
trigger={<Button variant="error">Delete Account</Button>}
title="Delete Account"
description={
<>
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
This will permanently delete your account and remove your data
from our servers.
</>
}
confirm="Delete Account"
Expand All @@ -87,7 +95,7 @@ export function DangerZone({ className }: DangerZoneProps) {
/>
</>
</AlertDialog>
</CardContent>
</CardFooter>
</Card>
)
}
21 changes: 12 additions & 9 deletions src/features/dashboard/account/email-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/ui/primitives/card'
Expand Down Expand Up @@ -102,7 +103,7 @@ export function EmailSettings({ className }: EmailSettingsProps) {
if (!user) return null

return (
<Card variant="slate" className={cn(className)}>
<Card className={cn('overflow-hidden rounded-xs border', className)}>
<CardHeader>
<CardTitle>E-Mail</CardTitle>
<CardDescription>Update your e-mail address.</CardDescription>
Expand Down Expand Up @@ -131,17 +132,19 @@ export function EmailSettings({ className }: EmailSettingsProps) {
</FormItem>
)}
/>
<Button
loading={isPending}
disabled={form.watch('email') === user?.email}
type="submit"
variant="outline"
>
Save
</Button>
</form>
</Form>
</CardContent>
<CardFooter className="bg-bg-100 justify-between">
<p className="text-fg-500 text-sm">Has to be a valid e-mail address.</p>
<Button
loading={isPending}
disabled={form.watch('email') === user?.email}
type="submit"
>
Save
</Button>
</CardFooter>
</Card>
)
}
32 changes: 20 additions & 12 deletions src/features/dashboard/account/name-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/ui/primitives/card'
Expand All @@ -27,7 +28,7 @@ import { useToast } from '@/lib/hooks/use-toast'
import { defaultSuccessToast, defaultErrorToast } from '@/lib/hooks/use-toast'

const formSchema = z.object({
name: z.string().min(1, 'Name cannot be empty'),
name: z.string().min(1, 'Name cannot be empty').max(32, 'Max 32 characters'),
})

type FormValues = z.infer<typeof formSchema>
Expand Down Expand Up @@ -66,10 +67,15 @@ export function NameSettings({ className }: NameSettingsProps) {
if (!user) return null

return (
<Card variant="slate" className={cn(className)} hideUnderline>
<Card
className={cn('overflow-hidden rounded-xs border', className)}
hideUnderline
>
<CardHeader>
<CardTitle>Your Name</CardTitle>
<CardDescription>Will be visible to your team members.</CardDescription>
<CardTitle>Name</CardTitle>
<CardDescription>
Update your account name, which will be visible to your team members.
</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-3">
<Form {...form}>
Expand All @@ -91,17 +97,19 @@ export function NameSettings({ className }: NameSettingsProps) {
</FormItem>
)}
/>
<Button
variant="outline"
loading={isPending}
disabled={form.watch('name') === user?.user_metadata?.name}
type="submit"
>
Save
</Button>
</form>
</Form>
</CardContent>
<CardFooter className="bg-bg-100 justify-between">
<p className="text-fg-500 text-sm">Max 32 characters.</p>
<Button
loading={isPending}
disabled={form.watch('name') === user?.user_metadata?.name}
type="submit"
>
Save
</Button>
</CardFooter>
</Card>
)
}
12 changes: 6 additions & 6 deletions src/features/dashboard/account/password-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@/ui/primitives/card'
Expand Down Expand Up @@ -41,15 +42,14 @@ export function PasswordSettings({ className }: PasswordSettingsProps) {
if (!user) return null

return (
<Card variant="slate" className={cn(className)}>
<Card className={cn('overflow-hidden rounded-xs border', className)}>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>
Change your account password used to sign in.
</CardDescription>
<CardDescription>Change your account password.</CardDescription>
</CardHeader>

<CardContent>
<CardFooter className="bg-bg-100 justify-between gap-6">
<p className="text-fg-500 text-sm">Sends a reset link.</p>
<Button
variant="outline"
onClick={() => {
Expand All @@ -65,7 +65,7 @@ export function PasswordSettings({ className }: PasswordSettingsProps) {
>
Change Password
</Button>
</CardContent>
</CardFooter>
</Card>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,6 @@ export default function UserAccessToken({ className }: UserAccessTokenProps) {

return (
<div className={className}>
<div className="flex h-5 items-center gap-2">
<Label>Access Token</Label>
<HelpTooltip>
Your personal access token for authenticating with E2B services.
</HelpTooltip>
</div>
<div className="mt-2 flex items-center">
<Input
type={isVisible ? 'text' : 'password'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
DialogTrigger,
} from '@/ui/primitives/dialog'
import InfraDomainForm from './infra-domain-form'
import UserAccessToken from './user-access-token'

interface DeveloperSettingsDialogProps extends DialogProps {
apiDomain?: string
Expand All @@ -33,7 +32,6 @@ export default function DeveloperSettingsDialog({
</DialogDescription>
</DialogHeader>
<InfraDomainForm apiDomain={apiDomain} className="py-6" />
<UserAccessToken className="py-6" />
</DialogContent>
</Dialog>
)
Expand Down
14 changes: 14 additions & 0 deletions src/features/dashboard/page-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface DashboardPageLayoutProps {
title: string
className?: string
fullscreen?: boolean
hideFrame?: boolean
classNames?: {
frameWrapper?: string
}
Expand All @@ -22,6 +23,7 @@ export default async function DashboardPageLayout({
className,
classNames,
fullscreen = false,
hideFrame = false,
}: DashboardPageLayoutProps) {
return (
<div
Expand Down Expand Up @@ -49,6 +51,7 @@ export default async function DashboardPageLayout({
fullscreen={fullscreen}
classNames={classNames}
className={className}
hideFrame={hideFrame}
>
{children}
</DesktopContent>
Expand All @@ -65,13 +68,15 @@ interface ContentProps {
}
className?: string
fullscreen?: boolean
hideFrame?: boolean
}

function DesktopContent({
children,
classNames,
className,
fullscreen,
hideFrame,
}: ContentProps) {
return (
<div
Expand All @@ -84,6 +89,15 @@ function DesktopContent({
>
{fullscreen ? (
<div className={cn('h-full', className)}>{children}</div>
) : hideFrame ? (
<div
className={cn(
'relative flex h-fit w-full max-w-[1200px] pb-2',
className
)}
>
{children}
</div>
) : (
<Frame
classNames={{
Expand Down