create-nextjs-cms 0.5.92 → 0.5.94

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 (67) hide show
  1. package/package.json +3 -3
  2. package/templates/default/app/(auth)/auth/login/LoginPage.tsx +13 -12
  3. package/templates/default/app/(auth)/layout.tsx +56 -0
  4. package/templates/default/app/(rootLayout)/layout.tsx +58 -8
  5. package/templates/default/app/globals.css +1 -1
  6. package/templates/default/components/AdminCard.tsx +16 -15
  7. package/templates/default/components/AdminEditPage.tsx +8 -7
  8. package/templates/default/components/AdminPrivilegeCard.tsx +12 -11
  9. package/templates/default/components/AdminsPage.tsx +5 -4
  10. package/templates/default/components/AnalyticsPage.tsx +8 -7
  11. package/templates/default/components/BrowsePage.tsx +7 -6
  12. package/templates/default/components/CategoryDeleteConfirmPage.tsx +12 -11
  13. package/templates/default/components/CategorySectionSelectInput.tsx +3 -2
  14. package/templates/default/components/DashboardNewPage.tsx +40 -39
  15. package/templates/default/components/DashboardPage.tsx +34 -33
  16. package/templates/default/components/DashboardPageAlt.tsx +3 -1
  17. package/templates/default/components/Dropzone.tsx +8 -7
  18. package/templates/default/components/EmailCard.tsx +12 -11
  19. package/templates/default/components/EmailPasswordForm.tsx +7 -6
  20. package/templates/default/components/EmailQuotaForm.tsx +7 -6
  21. package/templates/default/components/EmailsPage.tsx +6 -5
  22. package/templates/default/components/GalleryPhoto.tsx +6 -5
  23. package/templates/default/components/ItemEditPage.tsx +5 -4
  24. package/templates/default/components/Layout.tsx +1 -1
  25. package/templates/default/components/LoadingSpinners.tsx +1 -1
  26. package/templates/default/components/LogPage.tsx +24 -9
  27. package/templates/default/components/Navbar.tsx +13 -12
  28. package/templates/default/components/NewAdminForm.tsx +12 -11
  29. package/templates/default/components/NewEmailForm.tsx +11 -10
  30. package/templates/default/components/NewPage.tsx +6 -5
  31. package/templates/default/components/NewVariantComponent.tsx +6 -5
  32. package/templates/default/components/PhotoGallery.tsx +4 -3
  33. package/templates/default/components/SectionItemCard.tsx +8 -8
  34. package/templates/default/components/SectionItemStatusBadge.tsx +3 -2
  35. package/templates/default/components/SectionPage.tsx +6 -5
  36. package/templates/default/components/SelectInputButtons.tsx +8 -7
  37. package/templates/default/components/SettingsPage.tsx +18 -17
  38. package/templates/default/components/Sidebar.tsx +23 -15
  39. package/templates/default/components/SidebarDropdownItem.tsx +11 -5
  40. package/templates/default/components/SidebarItem.tsx +1 -0
  41. package/templates/default/components/VariantCard.tsx +8 -8
  42. package/templates/default/components/VariantEditPage.tsx +5 -4
  43. package/templates/default/components/analytics/BounceRate.tsx +6 -5
  44. package/templates/default/components/analytics/LivePageViews.tsx +8 -7
  45. package/templates/default/components/analytics/LiveUsersCount.tsx +3 -2
  46. package/templates/default/components/analytics/MonthlyPageViews.tsx +3 -2
  47. package/templates/default/components/analytics/TopCountries.tsx +4 -3
  48. package/templates/default/components/analytics/TopDevices.tsx +4 -3
  49. package/templates/default/components/analytics/TopMediums.tsx +4 -3
  50. package/templates/default/components/analytics/TopSources.tsx +4 -3
  51. package/templates/default/components/analytics/TotalPageViews.tsx +3 -2
  52. package/templates/default/components/analytics/TotalSessions.tsx +3 -2
  53. package/templates/default/components/analytics/TotalUniqueUsers.tsx +3 -2
  54. package/templates/default/components/custom/RightHomeRoomVariantCard.tsx +9 -8
  55. package/templates/default/components/form/Form.tsx +5 -4
  56. package/templates/default/components/form/FormInputElement.tsx +3 -1
  57. package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
  58. package/templates/default/components/form/inputs/DateFormInput.tsx +3 -2
  59. package/templates/default/components/form/inputs/DocumentFormInput.tsx +16 -15
  60. package/templates/default/components/form/inputs/MapFormInput.tsx +5 -4
  61. package/templates/default/components/form/inputs/PhotoFormInput.tsx +16 -15
  62. package/templates/default/components/form/inputs/SelectFormInput.tsx +3 -2
  63. package/templates/default/components/form/inputs/TagsFormInput.tsx +3 -2
  64. package/templates/default/components/form/inputs/VideoFormInput.tsx +7 -6
  65. package/templates/default/components/pagination/PaginationButtons.tsx +8 -6
  66. package/templates/default/package.json +2 -2
  67. package/templates/default/app/layout.tsx +0 -40
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
 
3
3
  import { useRef } from 'react'
4
- import getString from 'nextjs-cms/translations'
4
+ import { useI18n } from 'nextjs-cms/translations/client'
5
5
  import SectionItemCard from '@/components/SectionItemCard'
6
6
  import ContainerBox from '@/components/ContainerBox'
7
7
  import Pagination from '@/components/pagination/Pagination'
@@ -15,6 +15,7 @@ import { capitalizeWords } from 'nextjs-cms/utils'
15
15
  import ErrorComponent from '@/components/ErrorComponent'
16
16
 
17
17
  export default function BrowsePage({ section, page }: { section: string; page: string }) {
18
+ const t = useI18n()
18
19
  const pageInt = parseInt(page) ?? 1
19
20
  const params = useSearchParams()
20
21
  const router = useRouter()
@@ -50,24 +51,24 @@ export default function BrowsePage({ section, page }: { section: string; page: s
50
51
  }}
51
52
  >
52
53
  <CardHeader>
53
- <CardTitle>Search {data?.section?.title}</CardTitle>
54
+ <CardTitle>{t('search')} {data?.section?.title}</CardTitle>
54
55
  {/*<CardDescription>Search by title</CardDescription>*/}
55
56
  </CardHeader>
56
57
  <CardContent>
57
58
  <Input
58
59
  className='border-accent-foreground bg-input'
59
60
  ref={searchInputRef}
60
- placeholder={`${capitalizeWords(getString('search'))}...`}
61
+ placeholder={`${capitalizeWords(t('search'))}...`}
61
62
  defaultValue={q || ''}
62
63
  />
63
64
  </CardContent>
64
65
  <CardFooter className='border-t px-6 py-4'>
65
- <Button>{capitalizeWords(getString('search'))}</Button>
66
+ <Button>{capitalizeWords(t('search'))}</Button>
66
67
  </CardFooter>
67
68
  </form>
68
69
  </Card>
69
70
  ) : null}
70
- <ContainerBox title={getString('browse')}>
71
+ <ContainerBox title={t('browse')}>
71
72
 
72
73
 
73
74
  { data.items && data.items.length > 0 ? (
@@ -83,7 +84,7 @@ export default function BrowsePage({ section, page }: { section: string; page: s
83
84
  </div>
84
85
  ) : (
85
86
  <Alert variant='default' className='bg-primary text-primary-foreground my-8'>
86
- <AlertDescription className='font-bold'>{getString('noItems')}</AlertDescription>
87
+ <AlertDescription className='font-bold'>{t('noItems')}</AlertDescription>
87
88
  </Alert>
88
89
  )}
89
90
 
@@ -1,7 +1,7 @@
1
1
  import LoadingSpinners from '@/components/LoadingSpinners'
2
2
  import InfoCard from '@/components/InfoCard'
3
3
  import React from 'react'
4
- import getString from 'nextjs-cms/translations'
4
+ import { useI18n } from 'nextjs-cms/translations/client'
5
5
  import { Button } from '@/components/ui/button'
6
6
  import useModal from '@/hooks/useModal'
7
7
  import { useToast } from '@/components/ui/use-toast'
@@ -22,6 +22,7 @@ export default function CategoryDeleteConfirmPage({
22
22
  action: any
23
23
  allowRecursiveDelete: boolean
24
24
  }) {
25
+ const t = useI18n()
25
26
  const { setModal } = useModal()
26
27
  const { toast } = useToast()
27
28
 
@@ -39,7 +40,7 @@ export default function CategoryDeleteConfirmPage({
39
40
  const deleteMutation = trpc.hasItemsSections.deleteItem.useMutation({
40
41
  onError: (error) => {
41
42
  setModal({
42
- title: getString('delete'),
43
+ title: t('delete'),
43
44
  body: (
44
45
  <div className='rounded border-2 border-dashed border-red-500 bg-red-100 p-2 text-red-800'>
45
46
  {error.message}
@@ -55,8 +56,8 @@ export default function CategoryDeleteConfirmPage({
55
56
  await action()
56
57
  setModal(null)
57
58
  toast({
58
- title: getString('delete'),
59
- description: getString('itemDeletedSuccessfully'),
59
+ title: t('delete'),
60
+ description: t('itemDeletedSuccessfully'),
60
61
  variant: 'success',
61
62
  })
62
63
  },
@@ -74,10 +75,10 @@ export default function CategoryDeleteConfirmPage({
74
75
  <div className='relative z-1 border-b-2 p-8 pt-12 font-extrabold text-foreground'>
75
76
  <div className='absolute left-0 top-0 z-2 h-4 w-full bg-linear-to-r from-red-300 via-rose-500 to-pink-400'></div>
76
77
  <h1 className='pb-4 text-3xl'>{sectionTitle}</h1>
77
- <span>/{getString('delete')}</span>
78
+ <span>/{t('delete')}</span>
78
79
  </div>
79
80
  <div className='flex flex-col gap-2 px-8 py-4'>
80
- <div className='mb-4 text-2xl'>{getString('catDeleteTextLight')}</div>
81
+ <div className='mb-4 text-2xl'>{t('catDeleteTextLight')}</div>
81
82
  {deleteMutation.isPending ? (
82
83
  <div className='flex w-full items-center justify-center text-center'>
83
84
  <LoadingSpinners />
@@ -87,7 +88,7 @@ export default function CategoryDeleteConfirmPage({
87
88
  <InfoCard
88
89
  result={{
89
90
  key: 'info',
90
- title: `${getString('catDeleteWarningLight')}`,
91
+ title: `${t('catDeleteWarningLight')}`,
91
92
  status: false,
92
93
  }}
93
94
  />
@@ -97,20 +98,20 @@ export default function CategoryDeleteConfirmPage({
97
98
  <InfoCard
98
99
  result={{
99
100
  key: 'info',
100
- title: `${getString('recursiveCategoryDeleteWarning')}`,
101
+ title: `${t('recursiveCategoryDeleteWarning')}`,
101
102
  status: false,
102
103
  }}
103
104
  />
104
105
  <div className='flex items-center space-x-2'>
105
106
  <Switch id='recursive-category-delete' />
106
- <Label htmlFor='airplane-mode'>{getString('recursiveCategoryDelete')}</Label>
107
+ <Label htmlFor='airplane-mode'>{t('recursiveCategoryDelete')}</Label>
107
108
  </div>
108
109
  </div>
109
110
  ) : null}
110
111
 
111
112
  <div className='mt-2 flex flex-wrap gap-2'>
112
113
  <Button variant='destructive' onClick={handleDelete}>
113
- {getString('delete')}
114
+ {t('delete')}
114
115
  </Button>
115
116
 
116
117
  <Button
@@ -119,7 +120,7 @@ export default function CategoryDeleteConfirmPage({
119
120
  setModal(null)
120
121
  }}
121
122
  >
122
- {getString('cancel')}
123
+ {t('cancel')}
123
124
  </Button>
124
125
  </div>
125
126
  </div>
@@ -4,7 +4,7 @@ import SelectBox from '@/components/SelectBox'
4
4
  import LoadingSpinners from '@/components/LoadingSpinners'
5
5
  import { useAutoAnimate } from '@formkit/auto-animate/react'
6
6
  import SelectInputButtons from '@/components/SelectInputButtons'
7
- import getString from 'nextjs-cms/translations'
7
+ import { useI18n } from 'nextjs-cms/translations/client'
8
8
  import { trpc } from '@/app/_trpc/client'
9
9
  import { SelectOption } from 'nextjs-cms/core/fields'
10
10
  import type { RouterOutputs } from 'nextjs-cms/api'
@@ -21,6 +21,7 @@ export default function CategorySectionSelectInput({
21
21
  refetch?: any
22
22
  isChild?: boolean
23
23
  }) {
24
+ const t = useI18n()
24
25
  /**
25
26
  * Check and add the select option if it does not exist, the select option has a value of undefined
26
27
  */
@@ -28,7 +29,7 @@ export default function CategorySectionSelectInput({
28
29
  if (!exists || exists.length === 0) {
29
30
  if (input.options) {
30
31
  // @ts-ignore - This is a type-hack to add the placeholder `select` option to the options array
31
- input.options.unshift({ value: undefined, label: getString('select') })
32
+ input.options.unshift({ value: undefined, label: t('select') })
32
33
  }
33
34
  }
34
35
 
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
 
3
3
  import React from 'react'
4
- import getString from 'nextjs-cms/translations'
4
+ import { useI18n } from 'nextjs-cms/translations/client'
5
5
  import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'
6
6
  import { LiveUsersCount } from '@/components/analytics/LiveUsersCount'
7
7
  import { TotalPageViews } from '@/components/analytics/TotalPageViews'
@@ -18,6 +18,7 @@ import { PlusCircle, FileText, BarChart3, Users, Settings, Eye } from 'lucide-re
18
18
  ChartJS.register(ArcElement, Tooltip, Legend)
19
19
 
20
20
  const DashboardNewPage = () => {
21
+ const t = useI18n()
21
22
  // Analytics date range - last 30 days
22
23
  const [fromDate, setFromDate] = React.useState<Date | string>('30daysAgo')
23
24
  const [toDate, setToDate] = React.useState<Date | string>('today')
@@ -32,8 +33,8 @@ const DashboardNewPage = () => {
32
33
  return (
33
34
  <div className='w-full'>
34
35
  <div className='text-foreground bg-linear-to-r from-sky-200 via-emerald-300 to-blue-600 p-8 font-extrabold dark:from-blue-800 dark:via-amber-700 dark:to-rose-900'>
35
- <h1 className='text-3xl'>{getString('dashboard')}</h1>
36
- <p className='mt-2 text-lg opacity-90'>Content Management System Overview</p>
36
+ <h1 className='text-3xl'>{t('dashboard')}</h1>
37
+ <p className='mt-2 text-lg opacity-90'>{t('cmsOverview')}</p>
37
38
  </div>
38
39
 
39
40
  <div className='flex flex-col gap-6 p-6'>
@@ -41,7 +42,7 @@ const DashboardNewPage = () => {
41
42
  <div>
42
43
  <h2 className='mb-4 flex items-center gap-2 text-2xl font-semibold'>
43
44
  <BarChart3 className='h-6 w-6' />
44
- Analytics Overview
45
+ {t('analyticsOverview')}
45
46
  </h2>
46
47
  <div className='sm-sidebar:grid-cols-2 md-sidebar:grid-cols-2 lg-sidebar:grid-cols-4 grid grid-cols-1 gap-4'>
47
48
  <LiveUsersCount />
@@ -55,50 +56,50 @@ const DashboardNewPage = () => {
55
56
  <div>
56
57
  <h2 className='mb-4 flex items-center gap-2 text-2xl font-semibold'>
57
58
  <FileText className='h-6 w-6' />
58
- Content Statistics
59
+ {t('contentStatistics')}
59
60
  </h2>
60
61
  <div className='sm-sidebar:grid-cols-2 md-sidebar:grid-cols-3 lg-sidebar:grid-cols-4 grid grid-cols-1 gap-4'>
61
62
  <Card>
62
63
  <CardHeader className='flex flex-row items-center justify-between space-y-0 pb-2'>
63
- <CardTitle className='text-sm font-medium'>Total Cars</CardTitle>
64
+ <CardTitle className='text-sm font-medium'>{t('totalCars')}</CardTitle>
64
65
  <FileText className='text-muted-foreground h-4 w-4' />
65
66
  </CardHeader>
66
67
  <CardContent>
67
68
  <div className='text-2xl font-bold'>1,234</div>
68
- <p className='text-muted-foreground text-xs'>+20.1% from last month</p>
69
+ <p className='text-muted-foreground text-xs'>+20.1% {t('fromLastMonth')}</p>
69
70
  </CardContent>
70
71
  </Card>
71
72
 
72
73
  <Card>
73
74
  <CardHeader className='flex flex-row items-center justify-between space-y-0 pb-2'>
74
- <CardTitle className='text-sm font-medium'>Real Estate</CardTitle>
75
+ <CardTitle className='text-sm font-medium'>{t('realEstate')}</CardTitle>
75
76
  <FileText className='text-muted-foreground h-4 w-4' />
76
77
  </CardHeader>
77
78
  <CardContent>
78
79
  <div className='text-2xl font-bold'>856</div>
79
- <p className='text-muted-foreground text-xs'>+15.3% from last month</p>
80
+ <p className='text-muted-foreground text-xs'>+15.3% {t('fromLastMonth')}</p>
80
81
  </CardContent>
81
82
  </Card>
82
83
 
83
84
  <Card>
84
85
  <CardHeader className='flex flex-row items-center justify-between space-y-0 pb-2'>
85
- <CardTitle className='text-sm font-medium'>Jobs</CardTitle>
86
+ <CardTitle className='text-sm font-medium'>{t('jobs')}</CardTitle>
86
87
  <FileText className='text-muted-foreground h-4 w-4' />
87
88
  </CardHeader>
88
89
  <CardContent>
89
90
  <div className='text-2xl font-bold'>432</div>
90
- <p className='text-muted-foreground text-xs'>+7.2% from last month</p>
91
+ <p className='text-muted-foreground text-xs'>+7.2% {t('fromLastMonth')}</p>
91
92
  </CardContent>
92
93
  </Card>
93
94
 
94
95
  <Card>
95
96
  <CardHeader className='flex flex-row items-center justify-between space-y-0 pb-2'>
96
- <CardTitle className='text-sm font-medium'>Services</CardTitle>
97
+ <CardTitle className='text-sm font-medium'>{t('services')}</CardTitle>
97
98
  <FileText className='text-muted-foreground h-4 w-4' />
98
99
  </CardHeader>
99
100
  <CardContent>
100
101
  <div className='text-2xl font-bold'>298</div>
101
- <p className='text-muted-foreground text-xs'>+12.5% from last month</p>
102
+ <p className='text-muted-foreground text-xs'>+12.5% {t('fromLastMonth')}</p>
102
103
  </CardContent>
103
104
  </Card>
104
105
  </div>
@@ -106,11 +107,11 @@ const DashboardNewPage = () => {
106
107
 
107
108
  {/* Recent Activity */}
108
109
  <div>
109
- <h2 className='mb-4 text-2xl font-semibold'>Recent Activity</h2>
110
+ <h2 className='mb-4 text-2xl font-semibold'>{t('recentActivity')}</h2>
110
111
  <Card>
111
112
  <CardHeader>
112
- <CardTitle>Latest Content Updates</CardTitle>
113
- <CardDescription>Recently added or modified items across all sections</CardDescription>
113
+ <CardTitle>{t('latestContentUpdates')}</CardTitle>
114
+ <CardDescription>{t('recentlyAddedOrModified')}</CardDescription>
114
115
  </CardHeader>
115
116
  <CardContent>
116
117
  <div className='space-y-4'>
@@ -122,7 +123,7 @@ const DashboardNewPage = () => {
122
123
  <Button variant='outline' size='sm' asChild>
123
124
  <Link href='/browse/cars/1'>
124
125
  <Eye className='mr-1 h-4 w-4' />
125
- View
126
+ {t('view')}
126
127
  </Link>
127
128
  </Button>
128
129
  </div>
@@ -135,7 +136,7 @@ const DashboardNewPage = () => {
135
136
  <Button variant='outline' size='sm' asChild>
136
137
  <Link href='/browse/real-estate/1'>
137
138
  <Eye className='mr-1 h-4 w-4' />
138
- View
139
+ {t('view')}
139
140
  </Link>
140
141
  </Button>
141
142
  </div>
@@ -148,7 +149,7 @@ const DashboardNewPage = () => {
148
149
  <Button variant='outline' size='sm' asChild>
149
150
  <Link href='/browse/jobs/1'>
150
151
  <Eye className='mr-1 h-4 w-4' />
151
- View
152
+ {t('view')}
152
153
  </Link>
153
154
  </Button>
154
155
  </div>
@@ -159,19 +160,19 @@ const DashboardNewPage = () => {
159
160
 
160
161
  {/* Quick Actions */}
161
162
  <div>
162
- <h2 className='mb-4 text-2xl font-semibold'>Quick Actions</h2>
163
+ <h2 className='mb-4 text-2xl font-semibold'>{t('quickActions')}</h2>
163
164
  <div className='sm-sidebar:grid-cols-2 md-sidebar:grid-cols-3 lg-sidebar:grid-cols-4 grid grid-cols-1 gap-4'>
164
165
  <Card className='cursor-pointer transition-shadow hover:shadow-md'>
165
166
  <CardHeader>
166
167
  <CardTitle className='flex items-center gap-2'>
167
168
  <PlusCircle className='h-5 w-5' />
168
- Add New Car
169
+ {t('addNewCar')}
169
170
  </CardTitle>
170
- <CardDescription>Create a new car listing</CardDescription>
171
+ <CardDescription>{t('createCarListing')}</CardDescription>
171
172
  </CardHeader>
172
173
  <CardContent>
173
174
  <Button asChild className='w-full'>
174
- <Link href='/new/cars'>Create Car Listing</Link>
175
+ <Link href='/new/cars'>{t('create')}</Link>
175
176
  </Button>
176
177
  </CardContent>
177
178
  </Card>
@@ -180,13 +181,13 @@ const DashboardNewPage = () => {
180
181
  <CardHeader>
181
182
  <CardTitle className='flex items-center gap-2'>
182
183
  <PlusCircle className='h-5 w-5' />
183
- Add Real Estate
184
+ {t('addRealEstate')}
184
185
  </CardTitle>
185
- <CardDescription>Create a new property listing</CardDescription>
186
+ <CardDescription>{t('createPropertyListing')}</CardDescription>
186
187
  </CardHeader>
187
188
  <CardContent>
188
189
  <Button asChild className='w-full'>
189
- <Link href='/new/real-estate'>Create Property</Link>
190
+ <Link href='/new/real-estate'>{t('create')}</Link>
190
191
  </Button>
191
192
  </CardContent>
192
193
  </Card>
@@ -195,13 +196,13 @@ const DashboardNewPage = () => {
195
196
  <CardHeader>
196
197
  <CardTitle className='flex items-center gap-2'>
197
198
  <Users className='h-5 w-5' />
198
- Manage Admins
199
+ {t('manageAdmins')}
199
200
  </CardTitle>
200
- <CardDescription>View and manage administrators</CardDescription>
201
+ <CardDescription>{t('viewAndManageAdmins')}</CardDescription>
201
202
  </CardHeader>
202
203
  <CardContent>
203
204
  <Button asChild variant='outline' className='w-full'>
204
- <Link href='/admins'>Manage Admins</Link>
205
+ <Link href='/admins'>{t('manageAdmins')}</Link>
205
206
  </Button>
206
207
  </CardContent>
207
208
  </Card>
@@ -210,13 +211,13 @@ const DashboardNewPage = () => {
210
211
  <CardHeader>
211
212
  <CardTitle className='flex items-center gap-2'>
212
213
  <BarChart3 className='h-5 w-5' />
213
- View Analytics
214
+ {t('viewAnalytics')}
214
215
  </CardTitle>
215
- <CardDescription>Detailed analytics and insights</CardDescription>
216
+ <CardDescription>{t('detailedAnalytics')}</CardDescription>
216
217
  </CardHeader>
217
218
  <CardContent>
218
219
  <Button asChild variant='outline' className='w-full'>
219
- <Link href='/analytics'>View Analytics</Link>
220
+ <Link href='/analytics'>{t('viewAnalytics')}</Link>
220
221
  </Button>
221
222
  </CardContent>
222
223
  </Card>
@@ -225,22 +226,22 @@ const DashboardNewPage = () => {
225
226
 
226
227
  {/* System Status */}
227
228
  <div>
228
- <h2 className='mb-4 text-2xl font-semibold'>System Status</h2>
229
+ <h2 className='mb-4 text-2xl font-semibold'>{t('systemStatus')}</h2>
229
230
  <div className='grid grid-cols-1 gap-4 md:grid-cols-2'>
230
- <ContainerBox title='Database Status'>
231
+ <ContainerBox title={t('databaseStatus')}>
231
232
  <div className='flex items-center gap-2'>
232
233
  <div className='h-3 w-3 rounded-full bg-green-500'></div>
233
- <span>Connected</span>
234
+ <span>{t('connected')}</span>
234
235
  </div>
235
- <p className='text-muted-foreground mt-2 text-sm'>All database connections are healthy</p>
236
+ <p className='text-muted-foreground mt-2 text-sm'>{t('allConnectionsHealthy')}</p>
236
237
  </ContainerBox>
237
238
 
238
- <ContainerBox title='Cache Status'>
239
+ <ContainerBox title={t('cacheStatus')}>
239
240
  <div className='flex items-center gap-2'>
240
241
  <div className='h-3 w-3 rounded-full bg-green-500'></div>
241
- <span>Operational</span>
242
+ <span>{t('operational')}</span>
242
243
  </div>
243
- <p className='text-muted-foreground mt-2 text-sm'>Caching system is functioning properly</p>
244
+ <p className='text-muted-foreground mt-2 text-sm'>{t('cacheFunctioning')}</p>
244
245
  </ContainerBox>
245
246
  </div>
246
247
  </div>
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
 
3
3
  import React, { useEffect } from 'react'
4
- import getString from 'nextjs-cms/translations'
4
+ import { useI18n } from 'nextjs-cms/translations/client'
5
5
  import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'
6
6
  import { humanReadableFileSize } from 'nextjs-cms/utils'
7
7
  import PieChartBox from '@/components/PieChartBox'
@@ -11,6 +11,7 @@ import { trpc } from '@/app/_trpc/client'
11
11
  ChartJS.register(ArcElement, Tooltip, Legend)
12
12
 
13
13
  const DashboardPage = () => {
14
+ const t = useI18n()
14
15
  const { isLoading, isError, data, error } = trpc.cpanelDashboard.getData.useQuery()
15
16
 
16
17
  useEffect(() => {}, [])
@@ -18,7 +19,7 @@ const DashboardPage = () => {
18
19
  return (
19
20
  <div className='w-full'>
20
21
  <div className='bg-linear-to-r from-sky-200 via-emerald-300 to-blue-600 p-8 font-extrabold text-foreground dark:from-blue-800 dark:via-amber-700 dark:to-rose-900'>
21
- <h1 className='text-3xl'>{getString('dashboard')}</h1>
22
+ <h1 className='text-3xl'>{t('dashboard')}</h1>
22
23
  </div>
23
24
  <div className='flex flex-col gap-4 p-4'>
24
25
  {isLoading && (
@@ -32,24 +33,24 @@ const DashboardPage = () => {
32
33
  <PieChartBox
33
34
  chartData={[
34
35
  {
35
- name: getString('total_disk_space'),
36
+ name: t('totalDiskSpace'),
36
37
  value: data.diskSpaceLimit - data.diskSpaceUsage,
37
38
  fill: '#00C49F',
38
39
  },
39
40
  {
40
- name: getString('used_disk_space'),
41
+ name: t('usedDiskSpace'),
41
42
  value: data.diskSpaceUsage,
42
43
  fill: '#E1315B',
43
44
  },
44
45
  ]}
45
46
  chartBoxTitles={{
46
- mainTitle: getString('disk_space'),
47
+ mainTitle: t('diskSpace'),
47
48
  totalUnitSubtitle: {
48
- key: getString('total_disk_space'),
49
+ key: t('totalDiskSpace'),
49
50
  value: humanReadableFileSize(data.diskSpaceLimit),
50
51
  },
51
52
  usedUnitSubtitle: {
52
- key: getString('used_disk_space'),
53
+ key: t('usedDiskSpace'),
53
54
  value: humanReadableFileSize(data.diskSpaceUsage),
54
55
  },
55
56
  }}
@@ -57,24 +58,24 @@ const DashboardPage = () => {
57
58
  <PieChartBox
58
59
  chartData={[
59
60
  {
60
- name: getString('total_bandwidth'),
61
+ name: t('totalBandwidth'),
61
62
  value: data.bandwidthLimit - data.bandwidthUsage,
62
63
  fill: '#1c89f1',
63
64
  },
64
65
  {
65
- name: getString('used_bandwidth'),
66
+ name: t('usedBandwidth'),
66
67
  value: data.bandwidthUsage,
67
68
  fill: '#ff6688',
68
69
  },
69
70
  ]}
70
71
  chartBoxTitles={{
71
- mainTitle: getString('this_moth_bandwidth'),
72
+ mainTitle: t('thisMothBandwidth'),
72
73
  totalUnitSubtitle: {
73
- key: getString('total_bandwidth'),
74
+ key: t('totalBandwidth'),
74
75
  value: humanReadableFileSize(data.bandwidthLimit),
75
76
  },
76
77
  usedUnitSubtitle: {
77
- key: getString('used_bandwidth'),
78
+ key: t('usedBandwidth'),
78
79
  value: humanReadableFileSize(data.bandwidthUsage),
79
80
  },
80
81
  }}
@@ -82,24 +83,24 @@ const DashboardPage = () => {
82
83
  <PieChartBox
83
84
  chartData={[
84
85
  {
85
- name: getString('total_emails'),
86
+ name: t('totalEmails'),
86
87
  value: data.emailsLimit - data.emailsUsage,
87
88
  fill: '#c4ba56',
88
89
  },
89
90
  {
90
- name: getString('used_emails'),
91
+ name: t('usedEmails'),
91
92
  value: data.emailsUsage,
92
93
  fill: '#1404c4',
93
94
  },
94
95
  ]}
95
96
  chartBoxTitles={{
96
- mainTitle: getString('email_accounts'),
97
+ mainTitle: t('emailAccounts'),
97
98
  totalUnitSubtitle: {
98
- key: getString('total_emails'),
99
+ key: t('totalEmails'),
99
100
  value: data.emailsLimit.toString(),
100
101
  },
101
102
  usedUnitSubtitle: {
102
- key: getString('used_emails'),
103
+ key: t('usedEmails'),
103
104
  value: data.emailsUsage.toString(),
104
105
  },
105
106
  }}
@@ -107,24 +108,24 @@ const DashboardPage = () => {
107
108
  <PieChartBox
108
109
  chartData={[
109
110
  {
110
- name: getString('totalDatabases'),
111
+ name: t('totalDatabases'),
111
112
  value: data.dbsLimit - data.dbsCount,
112
113
  fill: '#56c4b4',
113
114
  },
114
115
  {
115
- name: getString('usedDatabases'),
116
+ name: t('usedDatabases'),
116
117
  value: data.dbsCount,
117
118
  fill: '#625bb2',
118
119
  },
119
120
  ]}
120
121
  chartBoxTitles={{
121
- mainTitle: 'MySQL®/MariaDB Databases',
122
+ mainTitle: t('mysqlDatabases'),
122
123
  totalUnitSubtitle: {
123
- key: getString('totalDatabases'),
124
+ key: t('totalDatabases'),
124
125
  value: data.dbsLimit.toString(),
125
126
  },
126
127
  usedUnitSubtitle: {
127
- key: getString('usedDatabases'),
128
+ key: t('usedDatabases'),
128
129
  value: data.dbsCount.toString(),
129
130
  },
130
131
  }}
@@ -133,35 +134,35 @@ const DashboardPage = () => {
133
134
  ) : null}
134
135
  </div>
135
136
  <div className='grid grid-cols-1 gap-4 md:grid-cols-2'>
136
- <ContainerBox title={getString('accountInformation')}>
137
- <div>PHP Version: {data?.phpVersion}</div>
138
- <div>root: {data?.documentRoot}</div>
137
+ <ContainerBox title={t('accountInformation')}>
138
+ <div>{t('phpVersion')}: {data?.phpVersion}</div>
139
+ <div>{t('documentRoot')}: {data?.documentRoot}</div>
139
140
  </ContainerBox>
140
141
 
141
- <ContainerBox title='MySQL/MariaDB'>
142
+ <ContainerBox title={t('mysqlDatabases')}>
142
143
  <div>
143
144
  {data?.dbInfo ? (
144
145
  <>
145
- <div>Version: {data.dbInfo.version}</div>
146
- <div>Remote: {data.dbInfo.is_remote}</div>
146
+ <div>{t('version')}: {data.dbInfo.version}</div>
147
+ <div>{t('remote')}: {data.dbInfo.is_remote}</div>
147
148
  </>
148
149
  ) : (
149
- <div>MySQL/MariaDB is not installed</div>
150
+ <div>{t('mysqlNotInstalled')}</div>
150
151
  )}
151
152
  </div>
152
153
  <div>
153
154
  {data?.dbsList?.map((db: any, index: number) => (
154
155
  <div key={`${db.name}_${db.database}_${index}`}>
155
- <div>database: {db.database}</div>
156
- <div>Disk Usage: {humanReadableFileSize(db.disk_usage)}</div>
157
- <div>Users: {db.users?.length}</div>
156
+ <div>{t('database')}: {db.database}</div>
157
+ <div>{t('diskUsage')}: {humanReadableFileSize(db.disk_usage)}</div>
158
+ <div>{t('users')}: {db.users?.length}</div>
158
159
  </div>
159
160
  ))}
160
161
  </div>
161
162
  </ContainerBox>
162
163
  </div>
163
164
  {/*<div>
164
- <ContainerBox title={getString('passengerApplications')}>
165
+ <ContainerBox title={t('passengerApplications')}>
165
166
  <div className='flex gap-4'>
166
167
  {data?.passengerAppList?.map((app: any) => (
167
168
  <ContainerBox title={app.name} key={app.name}>
@@ -1,5 +1,6 @@
1
1
  import { Metadata } from 'next'
2
2
  import Image from 'next/image'
3
+ import { useI18n } from 'nextjs-cms/translations/client'
3
4
 
4
5
  export const metadata: Metadata = {
5
6
  title: 'Dashboard',
@@ -7,6 +8,7 @@ export const metadata: Metadata = {
7
8
  }
8
9
 
9
10
  export default function DashboardPage() {
11
+ const t = useI18n()
10
12
  return (
11
13
  <>
12
14
  <div className='md:hidden'>
@@ -33,7 +35,7 @@ export default function DashboardPage() {
33
35
  </div>
34
36
  <div className='flex-1 space-y-4 p-8 pt-6'>
35
37
  <div className='flex items-center justify-between space-y-2'>
36
- <h2 className='text-3xl font-bold tracking-tight'>Dashboard</h2>
38
+ <h2 className='text-3xl font-bold tracking-tight'>{t('dashboard')}</h2>
37
39
  <div className='flex items-center space-x-2'></div>
38
40
  </div>
39
41
  </div>