blacksmith-cli 0.1.5 → 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.
- package/dist/index.js +1989 -690
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/templates/frontend/package.json.hbs +13 -5
- package/src/templates/frontend/src/__tests__/setup.ts.hbs +21 -0
- package/src/templates/frontend/src/__tests__/test-utils.tsx.hbs +81 -0
- package/src/templates/frontend/src/app.tsx.hbs +13 -9
- package/src/templates/frontend/src/features/auth/adapter.ts.hbs +7 -7
- package/src/templates/frontend/src/features/auth/components/auth-provider.tsx.hbs +91 -11
- package/src/templates/frontend/src/features/auth/hooks/use-auth.ts.hbs +3 -4
- package/src/templates/frontend/src/features/auth/pages/forgot-password-page.tsx.hbs +76 -12
- package/src/templates/frontend/src/features/auth/pages/login-page.tsx.hbs +84 -11
- package/src/templates/frontend/src/features/auth/pages/register-page.tsx.hbs +85 -14
- package/src/templates/frontend/src/features/auth/pages/reset-password-page.tsx.hbs +63 -12
- package/src/templates/frontend/src/features/auth/types.ts.hbs +32 -0
- package/src/templates/frontend/src/pages/dashboard/components/quick-start-card.tsx.hbs +19 -18
- package/src/templates/frontend/src/pages/dashboard/components/stack-cards.tsx.hbs +33 -31
- package/src/templates/frontend/src/pages/dashboard/components/welcome-header.tsx.hbs +5 -5
- package/src/templates/frontend/src/pages/dashboard/dashboard.tsx.hbs +5 -5
- package/src/templates/frontend/src/pages/home/home.tsx.hbs +48 -52
- package/src/templates/frontend/src/router/auth-guard.tsx.hbs +10 -7
- package/src/templates/frontend/src/router/error-boundary.tsx.hbs +16 -12
- package/src/templates/frontend/src/router/layouts/auth-layout.tsx.hbs +12 -12
- package/src/templates/frontend/src/router/layouts/main-layout.tsx.hbs +62 -55
- package/src/templates/frontend/src/shared/components/loading-spinner.tsx.hbs +6 -6
- package/src/templates/frontend/src/shared/components/not-found-page.tsx.hbs +1 -1
- package/src/templates/frontend/src/shared/hooks/use-debounce.ts.hbs +18 -2
- package/src/templates/frontend/src/styles/globals.css.hbs +3 -1
- package/src/templates/frontend/tailwind.config.js.hbs +1 -1
- package/src/templates/frontend/tsconfig.app.json.hbs +1 -0
- package/src/templates/frontend/vite.config.ts.hbs +8 -0
- package/src/templates/resource/frontend/components/{{kebab}}-form.tsx.hbs +3 -2
- package/src/templates/resource/frontend/pages/{{kebabs}}-page.tsx.hbs +3 -2
- package/src/templates/resource/frontend/pages/{{kebab}}-detail-page.tsx.hbs +5 -3
- package/src/templates/resource/pages/components/{{kebab}}-form.tsx.hbs +3 -2
- package/src/templates/resource/pages/{{kebabs}}-page.tsx.hbs +3 -2
- package/src/templates/resource/pages/{{kebab}}-detail-page.tsx.hbs +5 -3
|
@@ -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
|
-
|
|
9
|
-
|
|
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
|
-
<
|
|
42
|
-
<Alert
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
</
|
|
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 {
|
|
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"
|
|
39
|
-
|
|
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
|
-
<
|
|
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"
|
|
54
|
-
|
|
53
|
+
<Button variant="link" size="sm" className="text-muted-foreground" as={Link} to="/terms">
|
|
54
|
+
Terms
|
|
55
55
|
</Button>
|
|
56
|
-
<
|
|
57
|
-
<Button variant="link" size="sm" className="text-muted-foreground"
|
|
58
|
-
|
|
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
|
-
<
|
|
61
|
-
<Button variant="link" size="sm" className="text-muted-foreground"
|
|
62
|
-
|
|
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>
|
|
@@ -2,20 +2,20 @@ import { Outlet, Link, useNavigate } from 'react-router-dom'
|
|
|
2
2
|
import { Path } from '@/router/paths'
|
|
3
3
|
import {
|
|
4
4
|
Button,
|
|
5
|
-
|
|
5
|
+
IconButton,
|
|
6
6
|
Tooltip,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
Menu,
|
|
8
|
+
MenuButton,
|
|
9
|
+
MenuList,
|
|
10
|
+
MenuItem,
|
|
11
|
+
MenuDivider,
|
|
12
|
+
MenuGroup,
|
|
13
13
|
Avatar,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Divider,
|
|
15
|
+
useColorMode,
|
|
16
|
+
} from '@chakra-ui/react'
|
|
16
17
|
import { LogOut, User, Settings, Sun, Moon, Anvil } from 'lucide-react'
|
|
17
18
|
import { useAuth } from '@/features/auth/hooks/use-auth'
|
|
18
|
-
import { useDarkMode } from '@blacksmith-ui/react'
|
|
19
19
|
|
|
20
20
|
function getInitials(user: any): string {
|
|
21
21
|
if (user?.displayName) {
|
|
@@ -29,9 +29,11 @@ function getInitials(user: any): string {
|
|
|
29
29
|
|
|
30
30
|
export function MainLayout() {
|
|
31
31
|
const { user, isAuthenticated, logout } = useAuth()
|
|
32
|
-
const {
|
|
32
|
+
const { colorMode, toggleColorMode } = useColorMode()
|
|
33
33
|
const navigate = useNavigate()
|
|
34
34
|
|
|
35
|
+
const isDark = colorMode === 'dark'
|
|
36
|
+
|
|
35
37
|
const handleLogout = () => {
|
|
36
38
|
logout()
|
|
37
39
|
navigate(Path.Login)
|
|
@@ -49,57 +51,62 @@ export function MainLayout() {
|
|
|
49
51
|
<div className="flex-1" />
|
|
50
52
|
|
|
51
53
|
<div className="flex items-center gap-2">
|
|
52
|
-
<Tooltip
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
<Tooltip label={isDark ? 'Light mode' : 'Dark mode'}>
|
|
55
|
+
<IconButton
|
|
56
|
+
aria-label="Toggle color mode"
|
|
57
|
+
variant="ghost"
|
|
58
|
+
size="sm"
|
|
59
|
+
onClick={toggleColorMode}
|
|
60
|
+
icon={isDark ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
|
61
|
+
/>
|
|
56
62
|
</Tooltip>
|
|
57
63
|
|
|
58
64
|
{isAuthenticated ? (
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
<Menu>
|
|
66
|
+
<MenuButton
|
|
67
|
+
as={Button}
|
|
68
|
+
variant="ghost"
|
|
69
|
+
className="relative h-8 w-8 rounded-full"
|
|
70
|
+
p={0}
|
|
71
|
+
minW="auto"
|
|
72
|
+
>
|
|
73
|
+
<Avatar
|
|
74
|
+
size="sm"
|
|
75
|
+
name={user?.displayName || user?.email || 'U'}
|
|
76
|
+
getInitials={() => getInitials(user)}
|
|
77
|
+
/>
|
|
78
|
+
</MenuButton>
|
|
79
|
+
<MenuList>
|
|
80
|
+
<MenuGroup>
|
|
81
|
+
<div className="px-3 py-2">
|
|
72
82
|
<p className="text-sm font-medium leading-none">
|
|
73
83
|
{user?.displayName || 'User'}
|
|
74
84
|
</p>
|
|
75
|
-
<p className="text-xs leading-none text-muted-foreground">
|
|
85
|
+
<p className="text-xs leading-none text-muted-foreground mt-1">
|
|
76
86
|
{user?.email}
|
|
77
87
|
</p>
|
|
78
88
|
</div>
|
|
79
|
-
</
|
|
80
|
-
<
|
|
81
|
-
<
|
|
82
|
-
<User className="mr-2 h-4 w-4" />
|
|
89
|
+
</MenuGroup>
|
|
90
|
+
<MenuDivider />
|
|
91
|
+
<MenuItem icon={<User className="h-4 w-4" />}>
|
|
83
92
|
Profile
|
|
84
|
-
</
|
|
85
|
-
<
|
|
86
|
-
<Settings className="mr-2 h-4 w-4" />
|
|
93
|
+
</MenuItem>
|
|
94
|
+
<MenuItem icon={<Settings className="h-4 w-4" />}>
|
|
87
95
|
Settings
|
|
88
|
-
</
|
|
89
|
-
<
|
|
90
|
-
<
|
|
91
|
-
<LogOut className="mr-2 h-4 w-4" />
|
|
96
|
+
</MenuItem>
|
|
97
|
+
<MenuDivider />
|
|
98
|
+
<MenuItem icon={<LogOut className="h-4 w-4" />} onClick={handleLogout}>
|
|
92
99
|
Sign Out
|
|
93
|
-
</
|
|
94
|
-
</
|
|
95
|
-
</
|
|
100
|
+
</MenuItem>
|
|
101
|
+
</MenuList>
|
|
102
|
+
</Menu>
|
|
96
103
|
) : (
|
|
97
104
|
<>
|
|
98
|
-
<Button variant="ghost" size="sm"
|
|
99
|
-
|
|
105
|
+
<Button variant="ghost" size="sm" as={Link} to={Path.Login}>
|
|
106
|
+
Sign In
|
|
100
107
|
</Button>
|
|
101
|
-
<Button size="sm"
|
|
102
|
-
|
|
108
|
+
<Button size="sm" colorScheme="blue" as={Link} to={Path.Register}>
|
|
109
|
+
Sign Up
|
|
103
110
|
</Button>
|
|
104
111
|
</>
|
|
105
112
|
)}
|
|
@@ -118,16 +125,16 @@ export function MainLayout() {
|
|
|
118
125
|
<span>© {new Date().getFullYear()} {{projectName}}. All rights reserved.</span>
|
|
119
126
|
</div>
|
|
120
127
|
<div className="flex items-center gap-4">
|
|
121
|
-
<Button variant="link" size="sm" className="text-muted-foreground h-auto p-0"
|
|
122
|
-
|
|
128
|
+
<Button variant="link" size="sm" className="text-muted-foreground h-auto p-0" as={Link} to="/terms">
|
|
129
|
+
Terms
|
|
123
130
|
</Button>
|
|
124
|
-
<
|
|
125
|
-
<Button variant="link" size="sm" className="text-muted-foreground h-auto p-0"
|
|
126
|
-
|
|
131
|
+
<Divider orientation="vertical" h={4} />
|
|
132
|
+
<Button variant="link" size="sm" className="text-muted-foreground h-auto p-0" as={Link} to="/privacy">
|
|
133
|
+
Privacy
|
|
127
134
|
</Button>
|
|
128
|
-
<
|
|
129
|
-
<Button variant="link" size="sm" className="text-muted-foreground h-auto p-0"
|
|
130
|
-
|
|
135
|
+
<Divider orientation="vertical" h={4} />
|
|
136
|
+
<Button variant="link" size="sm" className="text-muted-foreground h-auto p-0" as={Link} to="/support">
|
|
137
|
+
Support
|
|
131
138
|
</Button>
|
|
132
139
|
</div>
|
|
133
140
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Spinner } from '@
|
|
1
|
+
import { Spinner } from '@chakra-ui/react'
|
|
2
2
|
|
|
3
3
|
interface LoadingSpinnerProps {
|
|
4
4
|
size?: 'sm' | 'md' | 'lg'
|
|
@@ -6,15 +6,15 @@ interface LoadingSpinnerProps {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
const sizeMap = {
|
|
9
|
-
sm: '
|
|
10
|
-
md: '
|
|
11
|
-
lg: '
|
|
12
|
-
}
|
|
9
|
+
sm: 'sm',
|
|
10
|
+
md: 'md',
|
|
11
|
+
lg: 'lg',
|
|
12
|
+
} as const
|
|
13
13
|
|
|
14
14
|
export function LoadingSpinner({ size = 'md', className = '' }: LoadingSpinnerProps) {
|
|
15
15
|
return (
|
|
16
16
|
<div className={`flex items-center justify-center ${className}`}>
|
|
17
|
-
<Spinner
|
|
17
|
+
<Spinner size={sizeMap[size]} />
|
|
18
18
|
</div>
|
|
19
19
|
)
|
|
20
20
|
}
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* useDebounce Hook
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Debounces a value by the specified delay.
|
|
5
5
|
* Import from here so your app has a single import path.
|
|
6
6
|
*
|
|
7
7
|
* Generated by Blacksmith. You own this file — customize as needed.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
import { useState, useEffect } from 'react'
|
|
11
|
+
|
|
12
|
+
export function useDebounce<T>(value: T, delay: number = 300): T {
|
|
13
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const timer = setTimeout(() => {
|
|
17
|
+
setDebouncedValue(value)
|
|
18
|
+
}, delay)
|
|
19
|
+
|
|
20
|
+
return () => {
|
|
21
|
+
clearTimeout(timer)
|
|
22
|
+
}
|
|
23
|
+
}, [value, delay])
|
|
24
|
+
|
|
25
|
+
return debouncedValue
|
|
26
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="vitest/config" />
|
|
1
2
|
import { defineConfig } from 'vite'
|
|
2
3
|
import react from '@vitejs/plugin-react'
|
|
3
4
|
import { resolve } from 'path'
|
|
@@ -18,4 +19,11 @@ export default defineConfig({
|
|
|
18
19
|
},
|
|
19
20
|
},
|
|
20
21
|
},
|
|
22
|
+
test: {
|
|
23
|
+
globals: true,
|
|
24
|
+
environment: 'jsdom',
|
|
25
|
+
setupFiles: ['./src/__tests__/setup.ts'],
|
|
26
|
+
include: ['src/**/*.spec.{ts,tsx}'],
|
|
27
|
+
css: true,
|
|
28
|
+
},
|
|
21
29
|
})
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { useForm } from 'react-hook-form'
|
|
10
10
|
import { z } from 'zod'
|
|
11
11
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
12
|
-
import { Alert, AlertDescription } from '@
|
|
12
|
+
import { Alert, AlertIcon, AlertDescription } from '@chakra-ui/react'
|
|
13
13
|
|
|
14
14
|
const {{name}}Schema = z.object({
|
|
15
15
|
title: z.string().min(1, 'Title is required').max(255),
|
|
@@ -55,7 +55,8 @@ export function {{Name}}Form({
|
|
|
55
55
|
return (
|
|
56
56
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
|
57
57
|
{errorMessage && (
|
|
58
|
-
<Alert
|
|
58
|
+
<Alert status="error" borderRadius="md">
|
|
59
|
+
<AlertIcon />
|
|
59
60
|
<AlertDescription>{errorMessage}</AlertDescription>
|
|
60
61
|
</Alert>
|
|
61
62
|
)}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { use{{Names}} } from '@/api/hooks/{{kebabs}}'
|
|
9
9
|
import { {{Name}}List } from '../components/{{kebab}}-list'
|
|
10
|
-
import { Alert, AlertDescription } from '@
|
|
10
|
+
import { Alert, AlertIcon, AlertDescription } from '@chakra-ui/react'
|
|
11
11
|
|
|
12
12
|
export default function {{Names}}Page() {
|
|
13
13
|
const { data, isLoading, errorMessage } = use{{Names}}()
|
|
@@ -19,7 +19,8 @@ export default function {{Names}}Page() {
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
{errorMessage && (
|
|
22
|
-
<Alert
|
|
22
|
+
<Alert status="error" borderRadius="md" className="mb-4">
|
|
23
|
+
<AlertIcon />
|
|
23
24
|
<AlertDescription>{errorMessage}</AlertDescription>
|
|
24
25
|
</Alert>
|
|
25
26
|
)}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { useParams, useNavigate } from 'react-router-dom'
|
|
9
9
|
import { useGet{{Name}}, useDelete{{Name}} } from '@/api/hooks/{{kebabs}}'
|
|
10
|
-
import { Alert, AlertDescription } from '@
|
|
10
|
+
import { Alert, AlertIcon, AlertDescription } from '@chakra-ui/react'
|
|
11
11
|
import { Path } from '@/router/paths'
|
|
12
12
|
|
|
13
13
|
export default function {{Name}}DetailPage() {
|
|
@@ -29,7 +29,8 @@ export default function {{Name}}DetailPage() {
|
|
|
29
29
|
|
|
30
30
|
if (errorMessage) {
|
|
31
31
|
return (
|
|
32
|
-
<Alert
|
|
32
|
+
<Alert status="error" borderRadius="md">
|
|
33
|
+
<AlertIcon />
|
|
33
34
|
<AlertDescription>{errorMessage}</AlertDescription>
|
|
34
35
|
</Alert>
|
|
35
36
|
)
|
|
@@ -49,7 +50,8 @@ export default function {{Name}}DetailPage() {
|
|
|
49
50
|
return (
|
|
50
51
|
<div>
|
|
51
52
|
{delete{{Name}}.errorMessage && (
|
|
52
|
-
<Alert
|
|
53
|
+
<Alert status="error" borderRadius="md" className="mb-4">
|
|
54
|
+
<AlertIcon />
|
|
53
55
|
<AlertDescription>{delete{{Name}}.errorMessage}</AlertDescription>
|
|
54
56
|
</Alert>
|
|
55
57
|
)}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { useForm } from 'react-hook-form'
|
|
10
10
|
import { z } from 'zod'
|
|
11
11
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
12
|
-
import { Alert, AlertDescription } from '@
|
|
12
|
+
import { Alert, AlertIcon, AlertDescription } from '@chakra-ui/react'
|
|
13
13
|
|
|
14
14
|
const {{name}}Schema = z.object({
|
|
15
15
|
title: z.string().min(1, 'Title is required').max(255),
|
|
@@ -55,7 +55,8 @@ export function {{Name}}Form({
|
|
|
55
55
|
return (
|
|
56
56
|
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
|
57
57
|
{errorMessage && (
|
|
58
|
-
<Alert
|
|
58
|
+
<Alert status="error" borderRadius="md">
|
|
59
|
+
<AlertIcon />
|
|
59
60
|
<AlertDescription>{errorMessage}</AlertDescription>
|
|
60
61
|
</Alert>
|
|
61
62
|
)}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { use{{Names}} } from '@/api/hooks/{{kebabs}}'
|
|
9
9
|
import { {{Name}}List } from './components/{{kebab}}-list'
|
|
10
|
-
import { Alert, AlertDescription } from '@
|
|
10
|
+
import { Alert, AlertIcon, AlertDescription } from '@chakra-ui/react'
|
|
11
11
|
|
|
12
12
|
export default function {{Names}}Page() {
|
|
13
13
|
const { data, isLoading, errorMessage } = use{{Names}}()
|
|
@@ -19,7 +19,8 @@ export default function {{Names}}Page() {
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
{errorMessage && (
|
|
22
|
-
<Alert
|
|
22
|
+
<Alert status="error" borderRadius="md" className="mb-4">
|
|
23
|
+
<AlertIcon />
|
|
23
24
|
<AlertDescription>{errorMessage}</AlertDescription>
|
|
24
25
|
</Alert>
|
|
25
26
|
)}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { useParams, useNavigate } from 'react-router-dom'
|
|
9
9
|
import { useGet{{Name}}, useDelete{{Name}} } from '@/api/hooks/{{kebabs}}'
|
|
10
|
-
import { Alert, AlertDescription } from '@
|
|
10
|
+
import { Alert, AlertIcon, AlertDescription } from '@chakra-ui/react'
|
|
11
11
|
import { Path } from '@/router/paths'
|
|
12
12
|
|
|
13
13
|
export default function {{Name}}DetailPage() {
|
|
@@ -29,7 +29,8 @@ export default function {{Name}}DetailPage() {
|
|
|
29
29
|
|
|
30
30
|
if (errorMessage) {
|
|
31
31
|
return (
|
|
32
|
-
<Alert
|
|
32
|
+
<Alert status="error" borderRadius="md">
|
|
33
|
+
<AlertIcon />
|
|
33
34
|
<AlertDescription>{errorMessage}</AlertDescription>
|
|
34
35
|
</Alert>
|
|
35
36
|
)
|
|
@@ -49,7 +50,8 @@ export default function {{Name}}DetailPage() {
|
|
|
49
50
|
return (
|
|
50
51
|
<div>
|
|
51
52
|
{delete{{Name}}.errorMessage && (
|
|
52
|
-
<Alert
|
|
53
|
+
<Alert status="error" borderRadius="md" className="mb-4">
|
|
54
|
+
<AlertIcon />
|
|
53
55
|
<AlertDescription>{delete{{Name}}.errorMessage}</AlertDescription>
|
|
54
56
|
</Alert>
|
|
55
57
|
)}
|