create-nextjs-cms 0.5.92 → 0.5.93

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
@@ -6,13 +6,14 @@ import { SidebarProps } from 'nextjs-cms/core/types'
6
6
  import SidebarItem from '@/components/SidebarItem'
7
7
  import SidebarDropdownItem from '@/components/SidebarDropdownItem'
8
8
  import { ScrollArea } from '@/components/ui/scroll-area'
9
- import getString from 'nextjs-cms/translations'
9
+ import { useI18n } from 'nextjs-cms/translations/client'
10
10
  import ProtectedImage from '@/components/ProtectedImage'
11
11
  import { trpc } from '@/app/_trpc/client'
12
12
  import { useToast } from '@/components/ui/use-toast'
13
13
  import { logout, useSession } from 'nextjs-cms/auth/react'
14
14
 
15
15
  const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }) => {
16
+ const t = useI18n()
16
17
  const session = useSession()
17
18
  const [navItems] = trpc.navigation.getSidebar.useSuspenseQuery()
18
19
  const { toast } = useToast()
@@ -24,19 +25,26 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
24
25
  } catch (error: any) {
25
26
  toast({
26
27
  variant: 'destructive',
27
- title: getString('logoutError'),
28
+ title: t('logoutError'),
28
29
  description: error.message,
29
30
  })
30
31
  }
31
32
  }
33
+ const isRTL = session?.data?.user?.locale === 'ar'
32
34
  return (
33
35
  <div
34
36
  className={classNames({
35
- 'fixed z-20 h-full bg-linear-to-br from-indigo-600 to-sky-500 text-zinc-50 md:translate-x-0 dark:from-slate-950 dark:to-pink-950':
37
+ 'fixed z-20 h-full bg-linear-to-br from-indigo-600 to-sky-500 text-zinc-50 dark:from-slate-950 dark:to-pink-950':
36
38
  true,
37
39
  'transition-all duration-100 ease-in-out': true,
38
40
  'w-[300px] md:w-[275px]': true,
41
+ // LTR: sidebar on left, slides in from left
42
+ 'left-0 md:translate-x-0': true,
39
43
  '-translate-x-full': !props.mobileSidebar,
44
+ // RTL: sidebar on right, slides in from right
45
+ 'rtl:left-auto rtl:right-0': true,
46
+ 'rtl:translate-x-full rtl:md:translate-x-0': !props.mobileSidebar,
47
+ 'rtl:translate-x-0': props.mobileSidebar,
40
48
  })}
41
49
  >
42
50
  <div
@@ -56,7 +64,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
56
64
  {props.logoText}
57
65
  </span>
58
66
  </div>
59
- <ScrollArea type='always' className='grow'>
67
+ <ScrollArea dir={isRTL ? 'rtl' : 'ltr'} type='always' className='grow'>
60
68
  <ul
61
69
  className={classNames({
62
70
  'my-2 flex flex-col items-stretch gap-2': true,
@@ -66,7 +74,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
66
74
  <>
67
75
  {navItems.fixed_sections && navItems.fixed_sections.length > 0 && (
68
76
  <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
69
- <h2 className='my-2 text-xs text-gray-300'>Main</h2>
77
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('main')}</h2>
70
78
  {navItems.fixed_sections.map((item, index) => {
71
79
  return (
72
80
  <SidebarItem
@@ -81,7 +89,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
81
89
 
82
90
  {navItems.cat_sections && navItems.cat_sections.length > 0 && (
83
91
  <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
84
- <h2 className='my-2 text-xs text-gray-300'>Category Sections</h2>
92
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('categorySections')}</h2>
85
93
  {navItems.cat_sections.map((item, index) => {
86
94
  return (
87
95
  <SidebarItem
@@ -96,7 +104,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
96
104
 
97
105
  {navItems.has_items_sections && navItems.has_items_sections.length > 0 && (
98
106
  <div className='border-primary/40 mx-3 flex flex-col border-b py-2'>
99
- <h2 className='my-2 text-xs text-gray-300'>Sections with Items</h2>
107
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('sectionsWithItems')}</h2>
100
108
  <div className='flex flex-col gap-y-2'>
101
109
  {navItems.has_items_sections.map((item, index) => {
102
110
  return (
@@ -112,7 +120,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
112
120
  )}
113
121
  {navItems.simple_sections && navItems.simple_sections.length > 0 && (
114
122
  <div className='mx-3 flex flex-col border-b border-blue-900 py-2'>
115
- <h2 className='my-2 text-xs text-gray-300'>Simple Sections</h2>
123
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('simpleSections')}</h2>
116
124
  {navItems.simple_sections.map((item, index) => {
117
125
  return (
118
126
  <SidebarItem
@@ -125,13 +133,13 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
125
133
  </div>
126
134
  )}
127
135
  <div className='mx-3 flex flex-col py-2'>
128
- <h2 className='my-2 text-xs text-gray-300'>Settings</h2>
136
+ <h2 className='my-2 text-start text-xs text-gray-300'>{t('settings')}</h2>
129
137
  <SidebarItem
130
138
  closeSideBar={props.closeSideBar}
131
139
  key={101}
132
140
  item={{
133
141
  path: '/settings',
134
- title: getString('accountSettings'),
142
+ title: t('accountSettings'),
135
143
  }}
136
144
  />
137
145
  <Link
@@ -140,10 +148,10 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
140
148
  className={classNames({
141
149
  'rounded-lg text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
142
150
  'transition-colors duration-100': false, //animation
143
- 'gap-4 p-2': true,
151
+ 'gap-4 p-2 text-start': true,
144
152
  })}
145
153
  >
146
- <span>{getString('logout')}</span>
154
+ <span>{t('logout')}</span>
147
155
  </Link>
148
156
  </div>
149
157
  </>
@@ -155,7 +163,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
155
163
  'grid place-content-stretch bg-indigo-700 p-2 dark:bg-slate-800': true,
156
164
  })}
157
165
  >
158
- <div className='flex h-12 items-center gap-4'>
166
+ <div className='flex h-12 items-center gap-4'>
159
167
  {session?.data?.user.image ? (
160
168
  <ProtectedImage
161
169
  section={'admins'}
@@ -177,10 +185,10 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
177
185
  />
178
186
  )}
179
187
 
180
- <div className='flex flex-col'>
188
+ <div className='flex flex-col text-start'>
181
189
  <span className='my-0 text-indigo-50'>{session?.data?.user.name}</span>
182
190
  <Link href='/settings' className='text-sm text-indigo-200'>
183
- {getString('settings')}
191
+ {t('settings')}
184
192
  </Link>
185
193
  </div>
186
194
  </div>
@@ -4,15 +4,17 @@ import { useState } from 'react'
4
4
  import { SidebarItemProps } from 'nextjs-cms/core/types'
5
5
  import { useAutoAnimate } from '@formkit/auto-animate/react'
6
6
  import { ChevronDownIcon, ChevronUpIcon, FolderIcon, PlusCircleIcon, PlusIcon } from 'lucide-react'
7
+ import { useI18n } from 'nextjs-cms/translations/client'
7
8
 
8
9
  export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemProps) {
10
+ const t = useI18n()
9
11
  const [parent] = useAutoAnimate()
10
12
  const [open, setOpen] = useState(false)
11
13
  return (
12
14
  <div ref={parent}>
13
15
  <div
14
16
  className={classNames({
15
- 'flex text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
17
+ 'flex cursor-pointer text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
16
18
  'transition-colors duration-100': false, //animation
17
19
  'gap-4 rounded-md p-2': true,
18
20
  'rounded-b-none bg-indigo-700 dark:bg-emerald-600': open,
@@ -21,9 +23,13 @@ export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemP
21
23
  >
22
24
  <li className='relative flex w-full items-center justify-between gap-2'>
23
25
  {/*<span>{item.icon}</span>*/}
24
- <span>{item.title}</span>
26
+ <span className='text-start'>{item.title}</span>
25
27
  <span>
26
- {open ? <ChevronUpIcon className='h-5 w-5' /> : <ChevronDownIcon className='h-5 w-5' />}
28
+ {open ? (
29
+ <ChevronUpIcon className='h-5 w-5' />
30
+ ) : (
31
+ <ChevronDownIcon className='h-5 w-5 rtl:rotate-0' />
32
+ )}
27
33
  </span>
28
34
  </li>
29
35
  </div>
@@ -48,7 +54,7 @@ export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemP
48
54
  <span>
49
55
  <PlusIcon className='size-4' />
50
56
  </span>
51
- <span>New</span>
57
+ <span>{t('new')}</span>
52
58
  </li>
53
59
  </Link>
54
60
  <Link
@@ -64,7 +70,7 @@ export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemP
64
70
  <span>
65
71
  <FolderIcon className='size-4' />
66
72
  </span>
67
- <span>Browse</span>
73
+ <span>{t('browse')}</span>
68
74
  </li>
69
75
  </Link>
70
76
  </div>
@@ -11,6 +11,7 @@ export default function SidebarItem({ item, closeSideBar }: SidebarItemProps) {
11
11
  'rounded-lg text-white hover:bg-indigo-900 dark:hover:bg-emerald-600': true, //colors
12
12
  'transition-colors duration-100': false, //animation
13
13
  'gap-4 p-2': true,
14
+ 'text-start': true, // RTL support
14
15
  })}
15
16
  >
16
17
  <span>{item.title}</span>
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import ContainerBox from '@/components/ContainerBox'
3
3
  import React from 'react'
4
4
  import { Variant } from 'nextjs-cms/core/types'
@@ -30,7 +30,7 @@ const VariantCard = ({
30
30
  if (response.error) {
31
31
  toast({
32
32
  variant: 'destructive',
33
- title: getString('delete_admin'),
33
+ title: t('deleteAdmin'),
34
34
  description: response.error.message,
35
35
  })
36
36
  } else if (response.code === 200) {
@@ -39,7 +39,7 @@ const VariantCard = ({
39
39
  setModalResponse(null)
40
40
  toast({
41
41
  variant: 'success',
42
- title: getString('itemDeletedSuccessfully'),
42
+ title: t('itemDeletedSuccessfully'),
43
43
  description: response.message,
44
44
  })
45
45
  }
@@ -55,7 +55,7 @@ const VariantCard = ({
55
55
  onClick={() => {
56
56
  setModal({
57
57
  size: 'lg',
58
- title: getString('edit'),
58
+ title: t('edit'),
59
59
  body: (
60
60
  <div className='p-4'>
61
61
  <VariantEditPage
@@ -73,7 +73,7 @@ const VariantCard = ({
73
73
  })
74
74
  }}
75
75
  >
76
- {getString('edit')}
76
+ {t('edit')}
77
77
  </Button>
78
78
  {/* Delete Button */}
79
79
  <Button
@@ -82,11 +82,11 @@ const VariantCard = ({
82
82
  variant='destructive'
83
83
  onClick={() => {
84
84
  setModal({
85
- title: getString('delete'),
85
+ title: t('delete'),
86
86
  body: (
87
87
  <div className='p-4'>
88
88
  <div className='flex flex-col gap-4'>
89
- <div>{getString('deleteItemText')}</div>
89
+ <div>{t('deleteItemText')}</div>
90
90
  <div className='flex gap-2'>
91
91
  <button
92
92
  className='rounded bg-green-600 px-2 py-1 text-white'
@@ -112,7 +112,7 @@ const VariantCard = ({
112
112
  })
113
113
  }}
114
114
  >
115
- {getString('delete')}
115
+ {t('delete')}
116
116
  </Button>
117
117
  </div>
118
118
  </div>
@@ -5,7 +5,7 @@ import { getVariantPage } from '@/lib/apiHelpers'
5
5
  import React, { RefObject, useEffect, useRef, useState } from 'react'
6
6
  import { useQuery } from '@tanstack/react-query'
7
7
  import { InputGroup } from 'nextjs-cms/core/types'
8
- import getString from 'nextjs-cms/translations'
8
+ import { useI18n } from 'nextjs-cms/translations/client'
9
9
  import useModal from '@/hooks/useModal'
10
10
  import { AxiosError } from 'axios'
11
11
  import InfoCard from '@/components/InfoCard'
@@ -37,6 +37,7 @@ export default function VariantEditPage({
37
37
  }[]
38
38
  action?: any
39
39
  }) {
40
+ const t = useI18n()
40
41
  const [response, setResponse] = useState<any>(null)
41
42
  const [progress, setProgress] = useState(0)
42
43
  const [progressVariant, setProgressVariant] = useState<'determinate' | 'query'>('determinate')
@@ -117,7 +118,7 @@ export default function VariantEditPage({
117
118
  setResponse(null)
118
119
  toast({
119
120
  variant: 'success',
120
- description: getString('itemUpdatedSuccessfully'),
121
+ description: t('itemUpdatedSuccessfully'),
121
122
  })
122
123
 
123
124
  // Redirect to the edit page
@@ -159,7 +160,7 @@ export default function VariantEditPage({
159
160
  <>
160
161
  <h1 className='pb-4 text-4xl'>{data?.variant?.variant_html_name_en}</h1>
161
162
  <span>
162
- /{getString('edit')} {data?.variant?.variant_single_item_name_en}
163
+ /{t('edit')} {data?.variant?.variant_single_item_name_en}
163
164
  </span>
164
165
  </>
165
166
  )}
@@ -208,7 +209,7 @@ export default function VariantEditPage({
208
209
  type='submit'
209
210
  disabled={isSubmitting}
210
211
  >
211
- {isSubmitting ? getString('loading') : getString('save')}
212
+ {isSubmitting ? t('loading') : t('save')}
212
213
  </button>
213
214
  {isSubmitting && (
214
215
  <div className='mt-0.5'>
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { formatNumber } from 'nextjs-cms/utils'
3
3
  import PieChartBox from '@/components/PieChartBox'
4
4
  import React, { useEffect } from 'react'
@@ -9,6 +9,7 @@ import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
9
9
  import { useTheme } from 'next-themes'
10
10
 
11
11
  export const BounceRate = ({ fromDate, toDate }: { fromDate: Date | string | null; toDate: Date | string | null }) => {
12
+ const t = useI18n()
12
13
  const axiosPrivate = useAxiosPrivate()
13
14
  let controller = new AbortController()
14
15
  const { theme } = useTheme()
@@ -34,12 +35,12 @@ export const BounceRate = ({ fromDate, toDate }: { fromDate: Date | string | nul
34
35
 
35
36
  const bounceRateData: PieChartDataItem[] = [
36
37
  {
37
- name: getString('total_disk_space'),
38
+ name: t('totalDiskSpace'),
38
39
  value: 100 - parseInt(data?.bounceRate),
39
40
  fill: 'transparent',
40
41
  },
41
42
  {
42
- name: getString('used_disk_space'),
43
+ name: t('usedDiskSpace'),
43
44
  value: parseInt(data?.bounceRate),
44
45
  fill: theme === 'dark' ? '#adfa1d' : '#E1315B',
45
46
  },
@@ -58,9 +59,9 @@ export const BounceRate = ({ fromDate, toDate }: { fromDate: Date | string | nul
58
59
  chartData={bounceRateData}
59
60
  isLoading={isLoading}
60
61
  chartBoxTitles={{
61
- mainTitle: getString('bounceRate'),
62
+ mainTitle: t('bounceRate'),
62
63
  totalUnitSubtitle: {
63
- key: getString('sessionsPerUser'),
64
+ key: t('sessionsPerUser'),
64
65
  value: formatNumber(data?.sessionsPerUser),
65
66
  },
66
67
  }}
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
3
3
  import ContainerBox from '@/components/ContainerBox'
4
4
  import React, { useEffect } from 'react'
@@ -7,6 +7,7 @@ import { useQuery } from '@tanstack/react-query'
7
7
  import { getAnalytics } from '@/lib/apiHelpers'
8
8
 
9
9
  export const LivePageViews = () => {
10
+ const t = useI18n()
10
11
  const axiosPrivate = useAxiosPrivate()
11
12
  const controller = new AbortController()
12
13
 
@@ -21,14 +22,14 @@ export const LivePageViews = () => {
21
22
  })
22
23
 
23
24
  return (
24
- <ContainerBox title={getString('liveUsersAreViewing')}>
25
+ <ContainerBox title={t('liveUsersAreViewing')}>
25
26
  <Table>
26
- <TableCaption>{getString('liveUsersSubtitle')}</TableCaption>
27
+ <TableCaption>{t('liveUsersSubtitle')}</TableCaption>
27
28
  <TableHeader>
28
29
  <TableRow>
29
- <TableHead>{getString('country')}</TableHead>
30
- <TableHead>{getString('device')}</TableHead>
31
- <TableHead>{getString('page')}</TableHead>
30
+ <TableHead>{t('country')}</TableHead>
31
+ <TableHead>{t('device')}</TableHead>
32
+ <TableHead>{t('page')}</TableHead>
32
33
  </TableRow>
33
34
  </TableHeader>
34
35
  <TableBody>
@@ -43,7 +44,7 @@ export const LivePageViews = () => {
43
44
  ) : (
44
45
  <TableRow>
45
46
  <TableCell colSpan={3} className='text-center'>
46
- {getString('noLiveUsers')}
47
+ {t('noLiveUsers')}
47
48
  </TableCell>
48
49
  </TableRow>
49
50
  )}
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { formatNumber } from 'nextjs-cms/utils'
3
3
  import ContainerBox from '@/components/ContainerBox'
4
4
  import React from 'react'
@@ -8,6 +8,7 @@ import { getAnalytics } from '@/lib/apiHelpers'
8
8
  import LoadingSpinners from '@/components/LoadingSpinners'
9
9
 
10
10
  export const LiveUsersCount = () => {
11
+ const t = useI18n()
11
12
  const axiosPrivate = useAxiosPrivate()
12
13
  const controller = new AbortController()
13
14
 
@@ -21,7 +22,7 @@ export const LiveUsersCount = () => {
21
22
  }),
22
23
  })
23
24
  return (
24
- <ContainerBox title={getString('liveUsers')}>
25
+ <ContainerBox title={t('liveUsers')}>
25
26
  {isLoading ? (
26
27
  <LoadingSpinners single={true} />
27
28
  ) : (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import BarChartBox from '@/components/BarChartBox'
3
3
  import React from 'react'
4
4
  import { useTheme } from 'next-themes'
@@ -13,6 +13,7 @@ export const MonthlyPageViews = ({
13
13
  fromDate: Date | string | null
14
14
  toDate: Date | string | null
15
15
  }) => {
16
+ const t = useI18n()
16
17
  const axiosPrivate = useAxiosPrivate()
17
18
  const controller = new AbortController()
18
19
  const { theme } = useTheme()
@@ -33,7 +34,7 @@ export const MonthlyPageViews = ({
33
34
  <BarChartBox
34
35
  isLoading={isLoading}
35
36
  chartData={data?.monthlyPageViews}
36
- title={getString('monthlyPageViews')}
37
+ title={t('monthlyPageViews')}
37
38
  fill={theme === 'dark' ? '#adfa1d' : '#ff6688'}
38
39
  />
39
40
  </>
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { BarChartDataItem } from 'nextjs-cms/core/types'
3
3
  import { Badge } from '@/components/ui/badge'
4
4
  import { formatNumber } from 'nextjs-cms/utils'
@@ -16,6 +16,7 @@ export const TopCountries = ({
16
16
  fromDate: Date | string | null
17
17
  toDate: Date | string | null
18
18
  }) => {
19
+ const t = useI18n()
19
20
  const axiosPrivate = useAxiosPrivate()
20
21
  const controller = new AbortController()
21
22
 
@@ -32,9 +33,9 @@ export const TopCountries = ({
32
33
  })
33
34
 
34
35
  return (
35
- <ContainerBox title={getString('countries')}>
36
+ <ContainerBox title={t('countries')}>
36
37
  <div className='w-full mb-6'>
37
- <h1 className='font-bold border-b pb-1 my-1'>{getString('topCountries')}</h1>
38
+ <h1 className='font-bold border-b pb-1 my-1'>{t('topCountries')}</h1>
38
39
  {isLoading && <LoadingSpinners single={true} />}
39
40
  {data?.topCountries?.length > 0 &&
40
41
  data.topCountries.map((country: BarChartDataItem, index: number) => (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { BarChartDataItem } from 'nextjs-cms/core/types'
3
3
  import { Badge } from '@/components/ui/badge'
4
4
  import { formatNumber } from 'nextjs-cms/utils'
@@ -10,6 +10,7 @@ import { getAnalytics } from '@/lib/apiHelpers'
10
10
  import LoadingSpinners from '@/components/LoadingSpinners'
11
11
 
12
12
  export const TopDevices = ({ fromDate, toDate }: { fromDate: Date | string | null; toDate: Date | string | null }) => {
13
+ const t = useI18n()
13
14
  const axiosPrivate = useAxiosPrivate()
14
15
  const controller = new AbortController()
15
16
 
@@ -26,9 +27,9 @@ export const TopDevices = ({ fromDate, toDate }: { fromDate: Date | string | nul
26
27
  })
27
28
 
28
29
  return (
29
- <ContainerBox title={getString('devices')}>
30
+ <ContainerBox title={t('devices')}>
30
31
  <div className='w-full'>
31
- <h1 className='font-bold border-b pb-1 my-1'>{getString('topDevices')}</h1>
32
+ <h1 className='font-bold border-b pb-1 my-1'>{t('topDevices')}</h1>
32
33
  {isLoading && <LoadingSpinners single={true} />}
33
34
  {data?.topDevices?.length > 0 &&
34
35
  data.topDevices.map((device: BarChartDataItem, index: number) => (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { BarChartDataItem } from 'nextjs-cms/core/types'
3
3
  import { Badge } from '@/components/ui/badge'
4
4
  import { formatNumber } from 'nextjs-cms/utils'
@@ -10,6 +10,7 @@ import { getAnalytics } from '@/lib/apiHelpers'
10
10
  import LoadingSpinners from '@/components/LoadingSpinners'
11
11
 
12
12
  export const TopMediums = ({ fromDate, toDate }: { fromDate: Date | string | null; toDate: Date | string | null }) => {
13
+ const t = useI18n()
13
14
  const axiosPrivate = useAxiosPrivate()
14
15
  let controller = new AbortController()
15
16
 
@@ -38,9 +39,9 @@ export const TopMediums = ({ fromDate, toDate }: { fromDate: Date | string | nul
38
39
  }, [])
39
40
 
40
41
  return (
41
- <ContainerBox title={getString('mediums')}>
42
+ <ContainerBox title={t('mediums')}>
42
43
  <div className='w-full mb-6'>
43
- <h1 className='font-bold border-b pb-1 my-1'>{getString('topMediums')}</h1>
44
+ <h1 className='font-bold border-b pb-1 my-1'>{t('topMediums')}</h1>
44
45
  {isLoading && <LoadingSpinners single={true} />}
45
46
  {data?.topMediums?.length > 0 &&
46
47
  data.topMediums.map((medium: BarChartDataItem, index: number) => (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { BarChartDataItem } from 'nextjs-cms/core/types'
3
3
  import { Badge } from '@/components/ui/badge'
4
4
  import { formatNumber } from 'nextjs-cms/utils'
@@ -10,6 +10,7 @@ import { getAnalytics } from '@/lib/apiHelpers'
10
10
  import LoadingSpinners from '@/components/LoadingSpinners'
11
11
 
12
12
  export const TopSources = ({ fromDate, toDate }: { fromDate: Date | string | null; toDate: Date | string | null }) => {
13
+ const t = useI18n()
13
14
  const axiosPrivate = useAxiosPrivate()
14
15
  const controller = new AbortController()
15
16
 
@@ -25,9 +26,9 @@ export const TopSources = ({ fromDate, toDate }: { fromDate: Date | string | nul
25
26
  }),
26
27
  })
27
28
  return (
28
- <ContainerBox title={getString('sources')}>
29
+ <ContainerBox title={t('sources')}>
29
30
  <div className='w-full mb-6'>
30
- <h1 className='font-bold border-b pb-1 my-1'>{getString('topSources')}</h1>
31
+ <h1 className='font-bold border-b pb-1 my-1'>{t('topSources')}</h1>
31
32
  {isLoading && <LoadingSpinners single={true} />}
32
33
  {data?.topSources?.length > 0 &&
33
34
  data.topSources.map((source: BarChartDataItem, index: number) => (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { formatNumber } from 'nextjs-cms/utils'
3
3
  import ContainerBox from '@/components/ContainerBox'
4
4
  import React from 'react'
@@ -14,6 +14,7 @@ export const TotalPageViews = ({
14
14
  fromDate: Date | string | null
15
15
  toDate: Date | string | null
16
16
  }) => {
17
+ const t = useI18n()
17
18
  const axiosPrivate = useAxiosPrivate()
18
19
  const controller = new AbortController()
19
20
 
@@ -29,7 +30,7 @@ export const TotalPageViews = ({
29
30
  }),
30
31
  })
31
32
  return (
32
- <ContainerBox title={getString('totalPageViews')}>
33
+ <ContainerBox title={t('totalPageViews')}>
33
34
  {isLoading ? (
34
35
  <LoadingSpinners single={true} />
35
36
  ) : (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { formatNumber } from 'nextjs-cms/utils'
3
3
  import ContainerBox from '@/components/ContainerBox'
4
4
  import React from 'react'
@@ -14,6 +14,7 @@ export const TotalSessions = ({
14
14
  fromDate: Date | string | null
15
15
  toDate: Date | string | null
16
16
  }) => {
17
+ const t = useI18n()
17
18
  const axiosPrivate = useAxiosPrivate()
18
19
  const controller = new AbortController()
19
20
 
@@ -29,7 +30,7 @@ export const TotalSessions = ({
29
30
  }),
30
31
  })
31
32
  return (
32
- <ContainerBox title={getString('totalSessions')}>
33
+ <ContainerBox title={t('totalSessions')}>
33
34
  {isLoading ? (
34
35
  <LoadingSpinners single={true} />
35
36
  ) : (
@@ -1,4 +1,4 @@
1
- import getString from 'nextjs-cms/translations'
1
+ import { useI18n } from 'nextjs-cms/translations/client'
2
2
  import { formatNumber } from 'nextjs-cms/utils'
3
3
  import ContainerBox from '@/components/ContainerBox'
4
4
  import React from 'react'
@@ -14,6 +14,7 @@ export const TotalUniqueUsers = ({
14
14
  fromDate: Date | string | null
15
15
  toDate: Date | string | null
16
16
  }) => {
17
+ const t = useI18n()
17
18
  const axiosPrivate = useAxiosPrivate()
18
19
  const controller = new AbortController()
19
20
 
@@ -29,7 +30,7 @@ export const TotalUniqueUsers = ({
29
30
  }),
30
31
  })
31
32
  return (
32
- <ContainerBox title={getString('totalUniqueUsers')}>
33
+ <ContainerBox title={t('totalUniqueUsers')}>
33
34
  {isLoading ? (
34
35
  <LoadingSpinners single={true} />
35
36
  ) : (