blacksmith-cli 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/index.js +1745 -689
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -1
  4. package/src/templates/frontend/package.json.hbs +4 -4
  5. package/src/templates/frontend/src/__tests__/test-utils.tsx.hbs +5 -4
  6. package/src/templates/frontend/src/app.tsx.hbs +13 -9
  7. package/src/templates/frontend/src/features/auth/adapter.ts.hbs +7 -7
  8. package/src/templates/frontend/src/features/auth/components/auth-provider.tsx.hbs +91 -11
  9. package/src/templates/frontend/src/features/auth/hooks/use-auth.ts.hbs +3 -4
  10. package/src/templates/frontend/src/features/auth/pages/forgot-password-page.tsx.hbs +76 -12
  11. package/src/templates/frontend/src/features/auth/pages/login-page.tsx.hbs +84 -11
  12. package/src/templates/frontend/src/features/auth/pages/register-page.tsx.hbs +85 -14
  13. package/src/templates/frontend/src/features/auth/pages/reset-password-page.tsx.hbs +63 -12
  14. package/src/templates/frontend/src/features/auth/types.ts.hbs +32 -0
  15. package/src/templates/frontend/src/pages/dashboard/components/quick-start-card.tsx.hbs +19 -18
  16. package/src/templates/frontend/src/pages/dashboard/components/stack-cards.tsx.hbs +33 -31
  17. package/src/templates/frontend/src/pages/dashboard/components/welcome-header.tsx.hbs +5 -5
  18. package/src/templates/frontend/src/pages/dashboard/dashboard.tsx.hbs +5 -5
  19. package/src/templates/frontend/src/pages/home/home.tsx.hbs +48 -52
  20. package/src/templates/frontend/src/router/auth-guard.tsx.hbs +10 -7
  21. package/src/templates/frontend/src/router/error-boundary.tsx.hbs +16 -12
  22. package/src/templates/frontend/src/router/layouts/auth-layout.tsx.hbs +12 -12
  23. package/src/templates/frontend/src/router/layouts/main-layout.tsx.hbs +62 -55
  24. package/src/templates/frontend/src/shared/components/loading-spinner.tsx.hbs +6 -6
  25. package/src/templates/frontend/src/shared/components/not-found-page.tsx.hbs +1 -1
  26. package/src/templates/frontend/src/shared/hooks/use-debounce.ts.hbs +18 -2
  27. package/src/templates/frontend/src/styles/globals.css.hbs +3 -1
  28. package/src/templates/frontend/tailwind.config.js.hbs +1 -1
  29. package/src/templates/resource/frontend/components/{{kebab}}-form.tsx.hbs +3 -2
  30. package/src/templates/resource/frontend/pages/{{kebabs}}-page.tsx.hbs +3 -2
  31. package/src/templates/resource/frontend/pages/{{kebab}}-detail-page.tsx.hbs +5 -3
  32. package/src/templates/resource/pages/components/{{kebab}}-form.tsx.hbs +3 -2
  33. package/src/templates/resource/pages/{{kebabs}}-page.tsx.hbs +3 -2
  34. package/src/templates/resource/pages/{{kebab}}-detail-page.tsx.hbs +5 -3
@@ -1,26 +1,42 @@
1
1
  /**
2
2
  * Reset Password Page
3
3
  *
4
- * Uses @blacksmith-ui/auth ResetPasswordForm connected to Django backend.
4
+ * Password reset form built with Chakra UI.
5
5
  * Generated by Blacksmith. You own this file — customize as needed.
6
6
  */
7
7
 
8
- import { ResetPasswordForm } from '@blacksmith-ui/auth'
8
+ import { useState } from 'react'
9
+ import {
10
+ Box,
11
+ Button,
12
+ FormControl,
13
+ FormLabel,
14
+ Input,
15
+ VStack,
16
+ Heading,
17
+ Text,
18
+ Alert,
19
+ AlertIcon,
20
+ AlertDescription,
21
+ Link as ChakraLink,
22
+ } from '@chakra-ui/react'
9
23
  import { useNavigate, useParams } from 'react-router-dom'
10
24
  import { useAuth } from '../hooks/use-auth'
11
- import { useState } from 'react'
12
25
  import { Path } from '@/router/paths'
13
26
 
14
27
  export default function ResetPasswordPage() {
15
28
  const navigate = useNavigate()
16
29
  const { token } = useParams<{ token: string }>()
17
30
  const { confirmPasswordReset, error } = useAuth()
31
+
32
+ const [password, setPassword] = useState('')
18
33
  const [loading, setLoading] = useState(false)
19
34
 
20
- const handleSubmit = async (data: { password: string; code: string }) => {
35
+ const handleSubmit = async (e: React.FormEvent) => {
36
+ e.preventDefault()
21
37
  setLoading(true)
22
38
  try {
23
- const result = await confirmPasswordReset(data.code, data.password)
39
+ const result = await confirmPasswordReset(token || '', password)
24
40
  if (result.success) {
25
41
  navigate(Path.Login, { replace: true })
26
42
  }
@@ -30,12 +46,47 @@ export default function ResetPasswordPage() {
30
46
  }
31
47
 
32
48
  return (
33
- <ResetPasswordForm
34
- onSubmit={handleSubmit}
35
- code={token || ''}
36
- onLoginClick={() => navigate(Path.Login)}
37
- error={error}
38
- loading={loading}
39
- />
49
+ <Box>
50
+ <VStack spacing={2} mb={6} align="start">
51
+ <Heading size="lg">Reset Password</Heading>
52
+ <Text color="gray.500">Enter your new password below.</Text>
53
+ </VStack>
54
+
55
+ {error && (
56
+ <Alert status="error" borderRadius="md" mb={4}>
57
+ <AlertIcon />
58
+ <AlertDescription>{error.message}</AlertDescription>
59
+ </Alert>
60
+ )}
61
+
62
+ <form onSubmit={handleSubmit}>
63
+ <VStack spacing={4}>
64
+ <FormControl isRequired>
65
+ <FormLabel>New Password</FormLabel>
66
+ <Input
67
+ type="password"
68
+ value={password}
69
+ onChange={(e) => setPassword(e.target.value)}
70
+ placeholder="Choose a new password"
71
+ />
72
+ </FormControl>
73
+
74
+ <Button
75
+ type="submit"
76
+ colorScheme="blue"
77
+ width="full"
78
+ isLoading={loading}
79
+ >
80
+ Reset Password
81
+ </Button>
82
+ </VStack>
83
+ </form>
84
+
85
+ <Text fontSize="sm" color="gray.500" mt={6} textAlign="center">
86
+ <ChakraLink color="blue.500" onClick={() => navigate(Path.Login)}>
87
+ Back to Sign In
88
+ </ChakraLink>
89
+ </Text>
90
+ </Box>
40
91
  )
41
92
  }
@@ -0,0 +1,32 @@
1
+ export interface AuthUser {
2
+ id: string
3
+ email: string
4
+ displayName: string | null
5
+ photoURL: string | null
6
+ emailVerified: boolean
7
+ providerId: string
8
+ }
9
+
10
+ export interface AuthError {
11
+ code: string
12
+ message: string
13
+ }
14
+
15
+ export interface AuthResult {
16
+ success: boolean
17
+ user?: AuthUser
18
+ error?: AuthError
19
+ }
20
+
21
+ export type SocialProvider = 'google' | 'github' | 'facebook' | 'apple'
22
+
23
+ export interface AuthAdapter {
24
+ signInWithEmail(email: string, password: string): Promise<AuthResult>
25
+ signUpWithEmail(email: string, password: string, displayName?: string): Promise<AuthResult>
26
+ signInWithSocial(provider: SocialProvider): Promise<AuthResult>
27
+ sendPasswordResetEmail(email: string): Promise<{ success: boolean; error?: AuthError }>
28
+ confirmPasswordReset(code: string, newPassword: string): Promise<{ success: boolean; error?: AuthError }>
29
+ signOut(): Promise<void>
30
+ getCurrentUser(): AuthUser | null
31
+ onAuthStateChanged(callback: (user: AuthUser | null) => void): () => void
32
+ }
@@ -1,36 +1,37 @@
1
1
  import {
2
2
  Card,
3
3
  CardHeader,
4
- CardTitle,
5
- CardDescription,
6
- CardContent,
4
+ CardBody,
7
5
  Badge,
8
- Flex,
6
+ HStack,
9
7
  Text,
10
- } from '@blacksmith-ui/react'
8
+ Heading,
9
+ } from '@chakra-ui/react'
11
10
  import { Rocket, Terminal } from 'lucide-react'
12
11
 
13
12
  export function QuickStartCard() {
14
13
  return (
15
14
  <Card>
16
- <CardHeader className="pb-3">
17
- <Flex align="center" justify="between">
18
- <CardTitle className="text-base">Quick Start</CardTitle>
15
+ <CardHeader pb={3}>
16
+ <HStack justify="space-between">
17
+ <Heading size="sm">Quick Start</Heading>
19
18
  <Badge variant="outline">
20
- <Rocket className="mr-1 h-3 w-3" />
21
- Guide
19
+ <HStack spacing={1}>
20
+ <Rocket className="h-3 w-3" />
21
+ <span>Guide</span>
22
+ </HStack>
22
23
  </Badge>
23
- </Flex>
24
+ </HStack>
24
25
  </CardHeader>
25
- <CardContent>
26
- <CardDescription>
26
+ <CardBody>
27
+ <Text fontSize="sm" color="gray.500">
27
28
  Scaffold a new resource with models, API, and pages in one command.
28
- </CardDescription>
29
- <Flex align="center" gap={2} className="mt-4 rounded-lg bg-muted px-3 py-2">
29
+ </Text>
30
+ <HStack spacing={2} className="mt-4 rounded-lg bg-muted px-3 py-2">
30
31
  <Terminal className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
31
- <Text as="code" size="sm" className="font-mono">blacksmith make:resource Post</Text>
32
- </Flex>
33
- </CardContent>
32
+ <code className="font-mono text-sm">blacksmith make:resource Post</code>
33
+ </HStack>
34
+ </CardBody>
34
35
  </Card>
35
36
  )
36
37
  }
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  Card,
3
3
  CardHeader,
4
- CardTitle,
5
- CardDescription,
6
- CardContent,
4
+ CardBody,
7
5
  Badge,
8
6
  Button,
9
- Flex,
10
- } from '@blacksmith-ui/react'
7
+ HStack,
8
+ Heading,
9
+ Text,
10
+ } from '@chakra-ui/react'
11
11
  import { Database, Layout } from 'lucide-react'
12
12
  import { Link } from 'react-router-dom'
13
13
  import { Path } from '@/router/paths'
@@ -17,27 +17,27 @@ const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8000'
17
17
  export function BackendCard() {
18
18
  return (
19
19
  <Card>
20
- <CardHeader className="pb-3">
21
- <Flex align="center" justify="between">
22
- <CardTitle className="text-base">Backend</CardTitle>
20
+ <CardHeader pb={3}>
21
+ <HStack justify="space-between">
22
+ <Heading size="sm">Backend</Heading>
23
23
  <Badge variant="outline">
24
- <Database className="mr-1 h-3 w-3" />
25
- Django
24
+ <HStack spacing={1}>
25
+ <Database className="h-3 w-3" />
26
+ <span>Django</span>
27
+ </HStack>
26
28
  </Badge>
27
- </Flex>
29
+ </HStack>
28
30
  </CardHeader>
29
- <CardContent>
30
- <CardDescription>
31
+ <CardBody>
32
+ <Text fontSize="sm" color="gray.500">
31
33
  Django REST API with JWT auth, serializers, and auto-generated OpenAPI docs.
32
- </CardDescription>
34
+ </Text>
33
35
  <div className="mt-4">
34
- <Button variant="outline" size="sm" asChild>
35
- <a href={`${API_URL}/api/docs/`} target="_blank" rel="noopener noreferrer">
36
- View API Docs
37
- </a>
36
+ <Button variant="outline" size="sm" as="a" href={`${API_URL}/api/docs/`} target="_blank" rel="noopener noreferrer">
37
+ View API Docs
38
38
  </Button>
39
39
  </div>
40
- </CardContent>
40
+ </CardBody>
41
41
  </Card>
42
42
  )
43
43
  }
@@ -45,25 +45,27 @@ export function BackendCard() {
45
45
  export function FrontendCard() {
46
46
  return (
47
47
  <Card>
48
- <CardHeader className="pb-3">
49
- <Flex align="center" justify="between">
50
- <CardTitle className="text-base">Frontend</CardTitle>
48
+ <CardHeader pb={3}>
49
+ <HStack justify="space-between">
50
+ <Heading size="sm">Frontend</Heading>
51
51
  <Badge variant="outline">
52
- <Layout className="mr-1 h-3 w-3" />
53
- React
52
+ <HStack spacing={1}>
53
+ <Layout className="h-3 w-3" />
54
+ <span>React</span>
55
+ </HStack>
54
56
  </Badge>
55
- </Flex>
57
+ </HStack>
56
58
  </CardHeader>
57
- <CardContent>
58
- <CardDescription>
59
+ <CardBody>
60
+ <Text fontSize="sm" color="gray.500">
59
61
  React + TypeScript with TanStack Query, React Router, and Tailwind CSS.
60
- </CardDescription>
62
+ </Text>
61
63
  <div className="mt-4">
62
- <Button variant="outline" size="sm" asChild>
63
- <Link to={Path.Home}>Home Page</Link>
64
+ <Button variant="outline" size="sm" as={Link} to={Path.Home}>
65
+ Home Page
64
66
  </Button>
65
67
  </div>
66
- </CardContent>
68
+ </CardBody>
67
69
  </Card>
68
70
  )
69
71
  }
@@ -1,4 +1,4 @@
1
- import { Stack, Typography, Text } from '@blacksmith-ui/react'
1
+ import { VStack, Heading, Text } from '@chakra-ui/react'
2
2
 
3
3
  interface WelcomeHeaderProps {
4
4
  displayName: string
@@ -6,9 +6,9 @@ interface WelcomeHeaderProps {
6
6
 
7
7
  export function WelcomeHeader({ displayName }: WelcomeHeaderProps) {
8
8
  return (
9
- <Stack gap={1}>
10
- <Typography variant="h2">Dashboard</Typography>
11
- <Text color="muted">Welcome back, {displayName}.</Text>
12
- </Stack>
9
+ <VStack spacing={1} align="stretch">
10
+ <Heading size="lg">Dashboard</Heading>
11
+ <Text color="gray.500">Welcome back, {displayName}.</Text>
12
+ </VStack>
13
13
  )
14
14
  }
@@ -1,4 +1,4 @@
1
- import { Stack, Divider, Grid } from '@blacksmith-ui/react'
1
+ import { VStack, Divider, SimpleGrid } from '@chakra-ui/react'
2
2
  import { useAuth } from '@/features/auth/hooks/use-auth'
3
3
  import { WelcomeHeader } from './components/welcome-header'
4
4
  import { QuickStartCard } from './components/quick-start-card'
@@ -8,14 +8,14 @@ export default function DashboardPage() {
8
8
  const { user } = useAuth()
9
9
 
10
10
  return (
11
- <Stack gap={8}>
11
+ <VStack spacing={8} align="stretch">
12
12
  <WelcomeHeader displayName={user?.displayName || user?.email || 'there'} />
13
13
  <Divider />
14
- <Grid columns=\{{ base: 1, sm: 2, lg: 3 }} gap={4}>
14
+ <SimpleGrid columns=\{{ base: 1, sm: 2, lg: 3 }} spacing={4}>
15
15
  <QuickStartCard />
16
16
  <BackendCard />
17
17
  <FrontendCard />
18
- </Grid>
19
- </Stack>
18
+ </SimpleGrid>
19
+ </VStack>
20
20
  )
21
21
  }
@@ -1,16 +1,14 @@
1
1
  import {
2
- Stack,
3
- Flex,
4
- Typography,
2
+ VStack,
3
+ HStack,
4
+ Heading,
5
5
  Text,
6
6
  Button,
7
7
  Card,
8
8
  CardHeader,
9
- CardTitle,
10
- CardDescription,
11
- CardContent,
12
- Grid,
13
- } from '@blacksmith-ui/react'
9
+ CardBody,
10
+ SimpleGrid,
11
+ } from '@chakra-ui/react'
14
12
  import { useAuth } from '@/features/auth/hooks/use-auth'
15
13
  import { Link } from 'react-router-dom'
16
14
  import { Path } from '@/router/paths'
@@ -22,56 +20,54 @@ export default function HomePage() {
22
20
  const { isAuthenticated } = useAuth()
23
21
 
24
22
  return (
25
- <Stack gap={10} className="pt-16 pb-12">
26
- <Stack gap={4} align="center">
27
- <Typography variant="h1" className="sm:text-5xl">
23
+ <VStack spacing={10} align="stretch" className="pt-16 pb-12">
24
+ <VStack spacing={4} align="center">
25
+ <Heading as="h1" size="2xl" className="sm:text-5xl">
28
26
  {{projectName}}
29
- </Typography>
30
- <Text size="lg" color="muted" align="center" className="max-w-md">
27
+ </Heading>
28
+ <Text fontSize="lg" color="gray.500" textAlign="center" className="max-w-md">
31
29
  Your app is ready. Sign in to get started or explore the API.
32
30
  </Text>
33
- <Flex justify="center" gap="md" className="pt-2">
31
+ <HStack spacing={4} className="pt-2">
34
32
  {isAuthenticated ? (
35
- <Button size="lg" asChild>
36
- <Link to={Path.Dashboard}>Dashboard</Link>
33
+ <Button size="lg" as={Link} to={Path.Dashboard}>
34
+ Dashboard
37
35
  </Button>
38
36
  ) : (
39
- <Button size="lg" asChild>
40
- <Link to={Path.Login}>Sign In</Link>
37
+ <Button size="lg" as={Link} to={Path.Login}>
38
+ Sign In
41
39
  </Button>
42
40
  )}
43
- <Button variant="outline" size="lg" asChild>
44
- <a href={`${API_URL}/api/docs/`} target="_blank" rel="noopener noreferrer">
45
- API Docs
46
- </a>
41
+ <Button variant="outline" size="lg" as="a" href={`${API_URL}/api/docs/`} target="_blank" rel="noopener noreferrer">
42
+ API Docs
47
43
  </Button>
48
- </Flex>
49
- </Stack>
44
+ </HStack>
45
+ </VStack>
50
46
 
51
- <Grid columns=\{{ base: 1, md: 3 }} gap={4} className="max-w-3xl mx-auto w-full">
47
+ <SimpleGrid columns=\{{ base: 1, md: 3 }} spacing={4} className="max-w-3xl mx-auto w-full">
52
48
  <Card>
53
- <CardHeader className="pb-2">
54
- <Flex align="center" gap={2}>
49
+ <CardHeader pb={2}>
50
+ <HStack spacing={2}>
55
51
  <Terminal className="h-4 w-4 text-primary" />
56
- <CardTitle className="text-sm">CLI</CardTitle>
57
- </Flex>
52
+ <Heading size="xs">CLI</Heading>
53
+ </HStack>
58
54
  </CardHeader>
59
- <CardContent>
60
- <CardDescription>
61
- Run <Text as="code" size="sm" className="font-mono">blacksmith dev</Text> to start the full stack.
62
- </CardDescription>
63
- </CardContent>
55
+ <CardBody>
56
+ <Text fontSize="sm" color="gray.500">
57
+ Run <code className="font-mono text-sm">blacksmith dev</code> to start the full stack.
58
+ </Text>
59
+ </CardBody>
64
60
  </Card>
65
61
 
66
62
  <Card>
67
- <CardHeader className="pb-2">
68
- <Flex align="center" gap={2}>
63
+ <CardHeader pb={2}>
64
+ <HStack spacing={2}>
69
65
  <BookOpen className="h-4 w-4 text-primary" />
70
- <CardTitle className="text-sm">API</CardTitle>
71
- </Flex>
66
+ <Heading size="xs">API</Heading>
67
+ </HStack>
72
68
  </CardHeader>
73
- <CardContent>
74
- <CardDescription>
69
+ <CardBody>
70
+ <Text fontSize="sm" color="gray.500">
75
71
  <a href={`${API_URL}/api/docs/`} target="_blank" rel="noopener noreferrer" className="underline underline-offset-4 hover:text-foreground">
76
72
  Swagger UI
77
73
  </a>
@@ -79,24 +75,24 @@ export default function HomePage() {
79
75
  <a href={`${API_URL}/admin/`} target="_blank" rel="noopener noreferrer" className="underline underline-offset-4 hover:text-foreground">
80
76
  Django Admin
81
77
  </a>
82
- </CardDescription>
83
- </CardContent>
78
+ </Text>
79
+ </CardBody>
84
80
  </Card>
85
81
 
86
82
  <Card>
87
- <CardHeader className="pb-2">
88
- <Flex align="center" gap={2}>
83
+ <CardHeader pb={2}>
84
+ <HStack spacing={2}>
89
85
  <Layout className="h-4 w-4 text-primary" />
90
- <CardTitle className="text-sm">Frontend</CardTitle>
91
- </Flex>
86
+ <Heading size="xs">Frontend</Heading>
87
+ </HStack>
92
88
  </CardHeader>
93
- <CardContent>
94
- <CardDescription>
89
+ <CardBody>
90
+ <Text fontSize="sm" color="gray.500">
95
91
  React, TanStack Query, and Tailwind CSS with typed API hooks.
96
- </CardDescription>
97
- </CardContent>
92
+ </Text>
93
+ </CardBody>
98
94
  </Card>
99
- </Grid>
100
- </Stack>
95
+ </SimpleGrid>
96
+ </VStack>
101
97
  )
102
98
  }
@@ -1,5 +1,5 @@
1
1
  import { Navigate, useLocation } from 'react-router-dom'
2
- import { Spinner, Alert, AlertTitle, AlertDescription, Button } from '@blacksmith-ui/react'
2
+ import { Spinner, Alert, AlertIcon, AlertTitle, AlertDescription, Button, Box } from '@chakra-ui/react'
3
3
  import { ShieldAlert } from 'lucide-react'
4
4
  import { useAuth } from '@/features/auth/hooks/use-auth'
5
5
  import { Path } from '@/router/paths'
@@ -16,7 +16,7 @@ export function AuthGuard({ roles, children }: AuthGuardProps) {
16
16
  if (isLoading) {
17
17
  return (
18
18
  <div className="flex items-center justify-center min-h-[60vh]">
19
- <Spinner className="h-8 w-8" />
19
+ <Spinner size="lg" />
20
20
  </div>
21
21
  )
22
22
  }
@@ -38,11 +38,14 @@ export function AuthGuard({ roles, children }: AuthGuardProps) {
38
38
  <ShieldAlert className="h-8 w-8 text-destructive" />
39
39
  </div>
40
40
  </div>
41
- <Alert variant="destructive">
42
- <AlertTitle>Access Denied</AlertTitle>
43
- <AlertDescription>
44
- You don't have permission to view this page.
45
- </AlertDescription>
41
+ <Alert status="error" borderRadius="md">
42
+ <AlertIcon />
43
+ <Box>
44
+ <AlertTitle>Access Denied</AlertTitle>
45
+ <AlertDescription>
46
+ You don't have permission to view this page.
47
+ </AlertDescription>
48
+ </Box>
46
49
  </Alert>
47
50
  <Button variant="outline" onClick={() => window.history.back()}>
48
51
  Go Back
@@ -2,11 +2,13 @@ import { useRouteError, isRouteErrorResponse, useNavigate } from 'react-router-d
2
2
  import {
3
3
  Button,
4
4
  Alert,
5
+ AlertIcon,
5
6
  AlertTitle,
6
7
  AlertDescription,
7
8
  Card,
8
- CardContent,
9
- } from '@blacksmith-ui/react'
9
+ CardBody,
10
+ Box,
11
+ } from '@chakra-ui/react'
10
12
  import { ArrowLeft, RefreshCw, AlertTriangle } from 'lucide-react'
11
13
 
12
14
  export function RouteErrorBoundary() {
@@ -38,15 +40,17 @@ export function RouteErrorBoundary() {
38
40
  return (
39
41
  <div className="flex items-center justify-center min-h-screen bg-background px-4">
40
42
  <Card className="w-full max-w-md">
41
- <CardContent className="pt-6 space-y-4">
42
- <Alert variant="destructive">
43
- <AlertTriangle className="h-4 w-4" />
44
- <AlertTitle>Something went wrong</AlertTitle>
45
- <AlertDescription>
46
- {error instanceof Error
47
- ? error.message
48
- : 'An unexpected error occurred.'}
49
- </AlertDescription>
43
+ <CardBody className="pt-6 space-y-4">
44
+ <Alert status="error" borderRadius="md">
45
+ <AlertIcon />
46
+ <Box>
47
+ <AlertTitle>Something went wrong</AlertTitle>
48
+ <AlertDescription>
49
+ {error instanceof Error
50
+ ? error.message
51
+ : 'An unexpected error occurred.'}
52
+ </AlertDescription>
53
+ </Box>
50
54
  </Alert>
51
55
  <div className="flex justify-center">
52
56
  <Button onClick={() => window.location.reload()}>
@@ -54,7 +58,7 @@ export function RouteErrorBoundary() {
54
58
  Reload Page
55
59
  </Button>
56
60
  </div>
57
- </CardContent>
61
+ </CardBody>
58
62
  </Card>
59
63
  </div>
60
64
  )
@@ -1,5 +1,5 @@
1
1
  import { Outlet, Link } from 'react-router-dom'
2
- import { Separator, Button } from '@blacksmith-ui/react'
2
+ import { Divider, Button } from '@chakra-ui/react'
3
3
  import { Anvil } from 'lucide-react'
4
4
  import { Path } from '@/router/paths'
5
5
 
@@ -35,8 +35,8 @@ export function AuthLayoutWrapper() {
35
35
  <span className="font-semibold">{{projectName}}</span>
36
36
  </div>
37
37
  <div className="lg:ml-auto">
38
- <Button variant="ghost" size="sm" asChild>
39
- <Link to={Path.Home}>Back to Home</Link>
38
+ <Button variant="ghost" size="sm" as={Link} to={Path.Home}>
39
+ Back to Home
40
40
  </Button>
41
41
  </div>
42
42
  </div>
@@ -47,19 +47,19 @@ export function AuthLayoutWrapper() {
47
47
  </div>
48
48
  </div>
49
49
 
50
- <Separator />
50
+ <Divider />
51
51
 
52
52
  <div className="flex items-center justify-center gap-4 p-6">
53
- <Button variant="link" size="sm" className="text-muted-foreground" asChild>
54
- <Link to="/terms">Terms</Link>
53
+ <Button variant="link" size="sm" className="text-muted-foreground" as={Link} to="/terms">
54
+ Terms
55
55
  </Button>
56
- <Separator orientation="vertical" className="h-4" />
57
- <Button variant="link" size="sm" className="text-muted-foreground" asChild>
58
- <Link to="/privacy">Privacy</Link>
56
+ <Divider orientation="vertical" h={4} />
57
+ <Button variant="link" size="sm" className="text-muted-foreground" as={Link} to="/privacy">
58
+ Privacy
59
59
  </Button>
60
- <Separator orientation="vertical" className="h-4" />
61
- <Button variant="link" size="sm" className="text-muted-foreground" asChild>
62
- <Link to="/support">Support</Link>
60
+ <Divider orientation="vertical" h={4} />
61
+ <Button variant="link" size="sm" className="text-muted-foreground" as={Link} to="/support">
62
+ Support
63
63
  </Button>
64
64
  </div>
65
65
  </div>