create-nextjs-cms 0.7.0 → 0.7.2
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/LICENSE +21 -21
- package/README.md +71 -71
- package/dist/helpers/utils.js +16 -16
- package/dist/lib/section-creators.js +166 -166
- package/package.json +3 -3
- package/templates/default/.eslintrc.json +5 -5
- package/templates/default/.prettierignore +7 -7
- package/templates/default/.prettierrc.json +27 -27
- package/templates/default/CHANGELOG.md +140 -140
- package/templates/default/_gitignore +57 -57
- package/templates/default/app/(auth)/auth/login/LoginPage.tsx +192 -192
- package/templates/default/app/(auth)/auth/login/page.tsx +11 -11
- package/templates/default/app/(auth)/auth-locale-provider.tsx +34 -34
- package/templates/default/app/(auth)/layout.tsx +81 -81
- package/templates/default/app/(rootLayout)/(plugins)/[...slug]/page.tsx +40 -40
- package/templates/default/app/(rootLayout)/(plugins)/[...slug]/plugin-server-registry.ts +22 -22
- package/templates/default/app/(rootLayout)/admins/page.tsx +10 -10
- package/templates/default/app/(rootLayout)/browse/[section]/[page]/page.tsx +22 -22
- package/templates/default/app/(rootLayout)/categorized/[section]/page.tsx +15 -15
- package/templates/default/app/(rootLayout)/dashboard/page.tsx +63 -63
- package/templates/default/app/(rootLayout)/dashboard-new/page.tsx +7 -7
- package/templates/default/app/(rootLayout)/edit/[section]/[itemId]/page.tsx +17 -17
- package/templates/default/app/(rootLayout)/layout.tsx +81 -81
- package/templates/default/app/(rootLayout)/loading.tsx +10 -10
- package/templates/default/app/(rootLayout)/log/page.tsx +7 -7
- package/templates/default/app/(rootLayout)/new/[section]/page.tsx +15 -15
- package/templates/default/app/(rootLayout)/section/[section]/page.tsx +16 -16
- package/templates/default/app/(rootLayout)/settings/page.tsx +13 -13
- package/templates/default/app/_trpc/client.ts +3 -3
- package/templates/default/app/api/auth/csrf/route.ts +25 -25
- package/templates/default/app/api/auth/refresh/route.ts +10 -10
- package/templates/default/app/api/auth/session/route.ts +20 -20
- package/templates/default/app/api/editor/photo/route.ts +49 -49
- package/templates/default/app/api/photo/route.ts +27 -27
- package/templates/default/app/api/submit/section/item/[slug]/route.ts +66 -66
- package/templates/default/app/api/submit/section/item/route.ts +56 -56
- package/templates/default/app/api/submit/section/simple/route.ts +57 -57
- package/templates/default/app/api/trpc/[trpc]/route.ts +33 -33
- package/templates/default/app/api/video/route.ts +174 -174
- package/templates/default/app/globals.css +219 -219
- package/templates/default/app/providers.tsx +152 -152
- package/templates/default/cms.config.ts +49 -52
- package/templates/default/components/AdminCard.tsx +166 -166
- package/templates/default/components/AdminEditPage.tsx +124 -124
- package/templates/default/components/AdminPrivilegeCard.tsx +185 -185
- package/templates/default/components/AdminsPage.tsx +43 -43
- package/templates/default/components/AnalyticsPage.tsx +128 -128
- package/templates/default/components/BarChartBox.tsx +42 -42
- package/templates/default/components/BrowsePage.tsx +106 -106
- package/templates/default/components/CategorizedSectionPage.tsx +31 -31
- package/templates/default/components/CategoryDeleteConfirmPage.tsx +130 -130
- package/templates/default/components/CategorySectionSelectInput.tsx +140 -140
- package/templates/default/components/ConditionalFields.tsx +49 -49
- package/templates/default/components/ContainerBox.tsx +24 -24
- package/templates/default/components/DashboardNewPage.tsx +253 -253
- package/templates/default/components/DashboardPage.tsx +188 -188
- package/templates/default/components/DashboardPageAlt.tsx +45 -45
- package/templates/default/components/DefaultNavItems.tsx +3 -3
- package/templates/default/components/Dropzone.tsx +154 -154
- package/templates/default/components/EmailCard.tsx +138 -138
- package/templates/default/components/EmailPasswordForm.tsx +85 -85
- package/templates/default/components/EmailQuotaForm.tsx +73 -73
- package/templates/default/components/EmailsPage.tsx +49 -49
- package/templates/default/components/ErrorComponent.tsx +16 -16
- package/templates/default/components/GalleryPhoto.tsx +93 -93
- package/templates/default/components/InfoCard.tsx +93 -93
- package/templates/default/components/ItemEditPage.tsx +214 -214
- package/templates/default/components/Layout.tsx +84 -84
- package/templates/default/components/LoadingSpinners.tsx +67 -67
- package/templates/default/components/LogPage.tsx +107 -107
- package/templates/default/components/Modal.tsx +166 -166
- package/templates/default/components/Navbar.tsx +258 -258
- package/templates/default/components/NewAdminForm.tsx +173 -173
- package/templates/default/components/NewEmailForm.tsx +132 -132
- package/templates/default/components/NewPage.tsx +205 -205
- package/templates/default/components/NewVariantComponent.tsx +229 -229
- package/templates/default/components/PhotoGallery.tsx +35 -35
- package/templates/default/components/PieChartBox.tsx +101 -101
- package/templates/default/components/ProgressBar.tsx +48 -48
- package/templates/default/components/ProtectedDocument.tsx +78 -78
- package/templates/default/components/ProtectedImage.tsx +143 -143
- package/templates/default/components/ProtectedVideo.tsx +76 -76
- package/templates/default/components/SectionItemCard.tsx +144 -144
- package/templates/default/components/SectionItemStatusBadge.tsx +17 -17
- package/templates/default/components/SectionPage.tsx +125 -125
- package/templates/default/components/SelectBox.tsx +98 -98
- package/templates/default/components/SelectInputButtons.tsx +125 -125
- package/templates/default/components/SettingsPage.tsx +232 -232
- package/templates/default/components/Sidebar.tsx +201 -201
- package/templates/default/components/SidebarDropdownItem.tsx +80 -80
- package/templates/default/components/SidebarItem.tsx +20 -20
- package/templates/default/components/ThemeProvider.tsx +8 -8
- package/templates/default/components/TooltipComponent.tsx +27 -27
- package/templates/default/components/VariantCard.tsx +124 -124
- package/templates/default/components/VariantEditPage.tsx +230 -230
- package/templates/default/components/analytics/BounceRate.tsx +70 -70
- package/templates/default/components/analytics/LivePageViews.tsx +55 -55
- package/templates/default/components/analytics/LiveUsersCount.tsx +33 -33
- package/templates/default/components/analytics/MonthlyPageViews.tsx +42 -42
- package/templates/default/components/analytics/TopCountries.tsx +52 -52
- package/templates/default/components/analytics/TopDevices.tsx +46 -46
- package/templates/default/components/analytics/TopMediums.tsx +58 -58
- package/templates/default/components/analytics/TopSources.tsx +45 -45
- package/templates/default/components/analytics/TotalPageViews.tsx +41 -41
- package/templates/default/components/analytics/TotalSessions.tsx +41 -41
- package/templates/default/components/analytics/TotalUniqueUsers.tsx +41 -41
- package/templates/default/components/custom/RightHomeRoomVariantCard.tsx +138 -138
- package/templates/default/components/dndKit/Draggable.tsx +21 -21
- package/templates/default/components/dndKit/Droppable.tsx +20 -20
- package/templates/default/components/dndKit/SortableItem.tsx +18 -18
- package/templates/default/components/form/DateRangeFormInput.tsx +57 -57
- package/templates/default/components/form/Form.tsx +317 -317
- package/templates/default/components/form/FormInputElement.tsx +70 -70
- package/templates/default/components/form/FormInputs.tsx +112 -112
- package/templates/default/components/form/helpers/_section-hot-reload.js +1 -1
- package/templates/default/components/form/helpers/util.ts +17 -17
- package/templates/default/components/form/inputs/CheckboxFormInput.tsx +33 -33
- package/templates/default/components/form/inputs/ColorFormInput.tsx +44 -44
- package/templates/default/components/form/inputs/DateFormInput.tsx +156 -156
- package/templates/default/components/form/inputs/DocumentFormInput.tsx +222 -222
- package/templates/default/components/form/inputs/MapFormInput.tsx +140 -140
- package/templates/default/components/form/inputs/MultipleSelectFormInput.tsx +83 -83
- package/templates/default/components/form/inputs/NumberFormInput.tsx +42 -42
- package/templates/default/components/form/inputs/PasswordFormInput.tsx +47 -47
- package/templates/default/components/form/inputs/PhotoFormInput.tsx +219 -219
- package/templates/default/components/form/inputs/RichTextFormInput.tsx +135 -135
- package/templates/default/components/form/inputs/SelectFormInput.tsx +175 -175
- package/templates/default/components/form/inputs/SlugFormInput.tsx +129 -129
- package/templates/default/components/form/inputs/TagsFormInput.tsx +154 -154
- package/templates/default/components/form/inputs/TextFormInput.tsx +48 -48
- package/templates/default/components/form/inputs/TextareaFormInput.tsx +47 -47
- package/templates/default/components/form/inputs/VideoFormInput.tsx +118 -118
- package/templates/default/components/locale-dropdown.tsx +74 -74
- package/templates/default/components/locale-picker.tsx +85 -85
- package/templates/default/components/login-locale-dropdown.tsx +46 -46
- package/templates/default/components/multi-select.tsx +1144 -1144
- package/templates/default/components/pagination/Pagination.tsx +36 -36
- package/templates/default/components/pagination/PaginationButtons.tsx +147 -147
- package/templates/default/components/theme-toggle.tsx +37 -37
- package/templates/default/components/ui/accordion.tsx +53 -53
- package/templates/default/components/ui/alert-dialog.tsx +157 -157
- package/templates/default/components/ui/alert.tsx +46 -46
- package/templates/default/components/ui/badge.tsx +38 -38
- package/templates/default/components/ui/button.tsx +62 -62
- package/templates/default/components/ui/calendar.tsx +166 -166
- package/templates/default/components/ui/card.tsx +43 -43
- package/templates/default/components/ui/checkbox.tsx +29 -29
- package/templates/default/components/ui/command.tsx +137 -137
- package/templates/default/components/ui/custom-alert-dialog.tsx +113 -113
- package/templates/default/components/ui/custom-dialog.tsx +123 -123
- package/templates/default/components/ui/dialog.tsx +123 -123
- package/templates/default/components/ui/dropdown-menu.tsx +182 -182
- package/templates/default/components/ui/input-group.tsx +54 -54
- package/templates/default/components/ui/input.tsx +22 -22
- package/templates/default/components/ui/label.tsx +19 -19
- package/templates/default/components/ui/popover.tsx +42 -42
- package/templates/default/components/ui/progress.tsx +31 -31
- package/templates/default/components/ui/scroll-area.tsx +42 -42
- package/templates/default/components/ui/select.tsx +165 -165
- package/templates/default/components/ui/separator.tsx +28 -28
- package/templates/default/components/ui/sheet.tsx +103 -103
- package/templates/default/components/ui/switch.tsx +29 -29
- package/templates/default/components/ui/table.tsx +83 -83
- package/templates/default/components/ui/tabs.tsx +55 -55
- package/templates/default/components/ui/toast.tsx +113 -113
- package/templates/default/components/ui/toaster.tsx +35 -35
- package/templates/default/components/ui/tooltip.tsx +30 -30
- package/templates/default/components/ui/use-toast.ts +188 -188
- package/templates/default/components.json +21 -21
- package/templates/default/context/ModalProvider.tsx +53 -53
- package/templates/default/drizzle.config.ts +4 -4
- package/templates/default/dynamic-schemas/schema.ts +10 -0
- package/templates/default/env/env.js +130 -130
- package/templates/default/envConfig.ts +4 -4
- package/templates/default/hooks/useModal.ts +8 -8
- package/templates/default/lib/apiHelpers.ts +92 -92
- package/templates/default/lib/postinstall.js +14 -14
- package/templates/default/lib/utils.ts +6 -6
- package/templates/default/next-env.d.ts +6 -6
- package/templates/default/next.config.ts +23 -23
- package/templates/default/package.json +2 -4
- package/templates/default/postcss.config.mjs +6 -6
- package/templates/default/proxy.ts +32 -32
- package/templates/default/tsconfig.json +48 -48
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
-
import { BarChartDataItem } from 'nextjs-cms/core/types'
|
|
3
|
-
import { Badge } from '@/components/ui/badge'
|
|
4
|
-
import { formatNumber } from 'nextjs-cms/utils'
|
|
5
|
-
import ContainerBox from '@/components/ContainerBox'
|
|
6
|
-
import React from 'react'
|
|
7
|
-
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
8
|
-
import { useQuery } from '@tanstack/react-query'
|
|
9
|
-
import { getAnalytics } from '@/lib/apiHelpers'
|
|
10
|
-
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
11
|
-
|
|
12
|
-
export const TopSources = ({ fromDate, toDate }: { fromDate: Date | string | null; toDate: Date | string | null }) => {
|
|
13
|
-
const t = useI18n()
|
|
14
|
-
const axiosPrivate = useAxiosPrivate()
|
|
15
|
-
const controller = new AbortController()
|
|
16
|
-
|
|
17
|
-
const { isLoading, isError, data, error } = useQuery({
|
|
18
|
-
queryKey: ['analyticsPage', 'topSources', fromDate, toDate],
|
|
19
|
-
queryFn: () =>
|
|
20
|
-
getAnalytics({
|
|
21
|
-
requestType: 'topSources',
|
|
22
|
-
axiosPrivate,
|
|
23
|
-
controller,
|
|
24
|
-
fromDate,
|
|
25
|
-
toDate,
|
|
26
|
-
}),
|
|
27
|
-
})
|
|
28
|
-
return (
|
|
29
|
-
<ContainerBox title={t('sources')}>
|
|
30
|
-
<div className='w-full mb-6'>
|
|
31
|
-
<h1 className='font-bold border-b pb-1 my-1'>{t('topSources')}</h1>
|
|
32
|
-
{isLoading && <LoadingSpinners single={true} />}
|
|
33
|
-
{data?.topSources?.length > 0 &&
|
|
34
|
-
data.topSources.map((source: BarChartDataItem, index: number) => (
|
|
35
|
-
<div key={`${index}-${source.name}`} className='w-full text-sm flex justify-between'>
|
|
36
|
-
<span className='font-bold text-foreground'>{source.name}:</span>
|
|
37
|
-
<Badge variant='outline' className='ms-2'>
|
|
38
|
-
{formatNumber(source.value)}
|
|
39
|
-
</Badge>
|
|
40
|
-
</div>
|
|
41
|
-
))}
|
|
42
|
-
</div>
|
|
43
|
-
</ContainerBox>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
1
|
+
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
+
import { BarChartDataItem } from 'nextjs-cms/core/types'
|
|
3
|
+
import { Badge } from '@/components/ui/badge'
|
|
4
|
+
import { formatNumber } from 'nextjs-cms/utils'
|
|
5
|
+
import ContainerBox from '@/components/ContainerBox'
|
|
6
|
+
import React from 'react'
|
|
7
|
+
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
8
|
+
import { useQuery } from '@tanstack/react-query'
|
|
9
|
+
import { getAnalytics } from '@/lib/apiHelpers'
|
|
10
|
+
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
11
|
+
|
|
12
|
+
export const TopSources = ({ fromDate, toDate }: { fromDate: Date | string | null; toDate: Date | string | null }) => {
|
|
13
|
+
const t = useI18n()
|
|
14
|
+
const axiosPrivate = useAxiosPrivate()
|
|
15
|
+
const controller = new AbortController()
|
|
16
|
+
|
|
17
|
+
const { isLoading, isError, data, error } = useQuery({
|
|
18
|
+
queryKey: ['analyticsPage', 'topSources', fromDate, toDate],
|
|
19
|
+
queryFn: () =>
|
|
20
|
+
getAnalytics({
|
|
21
|
+
requestType: 'topSources',
|
|
22
|
+
axiosPrivate,
|
|
23
|
+
controller,
|
|
24
|
+
fromDate,
|
|
25
|
+
toDate,
|
|
26
|
+
}),
|
|
27
|
+
})
|
|
28
|
+
return (
|
|
29
|
+
<ContainerBox title={t('sources')}>
|
|
30
|
+
<div className='w-full mb-6'>
|
|
31
|
+
<h1 className='font-bold border-b pb-1 my-1'>{t('topSources')}</h1>
|
|
32
|
+
{isLoading && <LoadingSpinners single={true} />}
|
|
33
|
+
{data?.topSources?.length > 0 &&
|
|
34
|
+
data.topSources.map((source: BarChartDataItem, index: number) => (
|
|
35
|
+
<div key={`${index}-${source.name}`} className='w-full text-sm flex justify-between'>
|
|
36
|
+
<span className='font-bold text-foreground'>{source.name}:</span>
|
|
37
|
+
<Badge variant='outline' className='ms-2'>
|
|
38
|
+
{formatNumber(source.value)}
|
|
39
|
+
</Badge>
|
|
40
|
+
</div>
|
|
41
|
+
))}
|
|
42
|
+
</div>
|
|
43
|
+
</ContainerBox>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
-
import { formatNumber } from 'nextjs-cms/utils'
|
|
3
|
-
import ContainerBox from '@/components/ContainerBox'
|
|
4
|
-
import React from 'react'
|
|
5
|
-
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
6
|
-
import { useQuery } from '@tanstack/react-query'
|
|
7
|
-
import { getAnalytics } from '@/lib/apiHelpers'
|
|
8
|
-
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
9
|
-
|
|
10
|
-
export const TotalPageViews = ({
|
|
11
|
-
fromDate,
|
|
12
|
-
toDate,
|
|
13
|
-
}: {
|
|
14
|
-
fromDate: Date | string | null
|
|
15
|
-
toDate: Date | string | null
|
|
16
|
-
}) => {
|
|
17
|
-
const t = useI18n()
|
|
18
|
-
const axiosPrivate = useAxiosPrivate()
|
|
19
|
-
const controller = new AbortController()
|
|
20
|
-
|
|
21
|
-
const { isLoading, isError, data, error } = useQuery({
|
|
22
|
-
queryKey: ['analyticsPage', 'statistics', fromDate, toDate],
|
|
23
|
-
queryFn: () =>
|
|
24
|
-
getAnalytics({
|
|
25
|
-
requestType: 'statistics',
|
|
26
|
-
axiosPrivate,
|
|
27
|
-
controller,
|
|
28
|
-
fromDate,
|
|
29
|
-
toDate,
|
|
30
|
-
}),
|
|
31
|
-
})
|
|
32
|
-
return (
|
|
33
|
-
<ContainerBox title={t('totalPageViews')}>
|
|
34
|
-
{isLoading ? (
|
|
35
|
-
<LoadingSpinners single={true} />
|
|
36
|
-
) : (
|
|
37
|
-
<div className='text-4xl'>{formatNumber(data?.totalPageViews)}</div>
|
|
38
|
-
)}
|
|
39
|
-
</ContainerBox>
|
|
40
|
-
)
|
|
41
|
-
}
|
|
1
|
+
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
+
import { formatNumber } from 'nextjs-cms/utils'
|
|
3
|
+
import ContainerBox from '@/components/ContainerBox'
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
6
|
+
import { useQuery } from '@tanstack/react-query'
|
|
7
|
+
import { getAnalytics } from '@/lib/apiHelpers'
|
|
8
|
+
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
9
|
+
|
|
10
|
+
export const TotalPageViews = ({
|
|
11
|
+
fromDate,
|
|
12
|
+
toDate,
|
|
13
|
+
}: {
|
|
14
|
+
fromDate: Date | string | null
|
|
15
|
+
toDate: Date | string | null
|
|
16
|
+
}) => {
|
|
17
|
+
const t = useI18n()
|
|
18
|
+
const axiosPrivate = useAxiosPrivate()
|
|
19
|
+
const controller = new AbortController()
|
|
20
|
+
|
|
21
|
+
const { isLoading, isError, data, error } = useQuery({
|
|
22
|
+
queryKey: ['analyticsPage', 'statistics', fromDate, toDate],
|
|
23
|
+
queryFn: () =>
|
|
24
|
+
getAnalytics({
|
|
25
|
+
requestType: 'statistics',
|
|
26
|
+
axiosPrivate,
|
|
27
|
+
controller,
|
|
28
|
+
fromDate,
|
|
29
|
+
toDate,
|
|
30
|
+
}),
|
|
31
|
+
})
|
|
32
|
+
return (
|
|
33
|
+
<ContainerBox title={t('totalPageViews')}>
|
|
34
|
+
{isLoading ? (
|
|
35
|
+
<LoadingSpinners single={true} />
|
|
36
|
+
) : (
|
|
37
|
+
<div className='text-4xl'>{formatNumber(data?.totalPageViews)}</div>
|
|
38
|
+
)}
|
|
39
|
+
</ContainerBox>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
-
import { formatNumber } from 'nextjs-cms/utils'
|
|
3
|
-
import ContainerBox from '@/components/ContainerBox'
|
|
4
|
-
import React from 'react'
|
|
5
|
-
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
6
|
-
import { useQuery } from '@tanstack/react-query'
|
|
7
|
-
import { getAnalytics } from '@/lib/apiHelpers'
|
|
8
|
-
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
9
|
-
|
|
10
|
-
export const TotalSessions = ({
|
|
11
|
-
fromDate,
|
|
12
|
-
toDate,
|
|
13
|
-
}: {
|
|
14
|
-
fromDate: Date | string | null
|
|
15
|
-
toDate: Date | string | null
|
|
16
|
-
}) => {
|
|
17
|
-
const t = useI18n()
|
|
18
|
-
const axiosPrivate = useAxiosPrivate()
|
|
19
|
-
const controller = new AbortController()
|
|
20
|
-
|
|
21
|
-
const { isLoading, isError, data, error } = useQuery({
|
|
22
|
-
queryKey: ['analyticsPage', 'statistics', fromDate, toDate],
|
|
23
|
-
queryFn: () =>
|
|
24
|
-
getAnalytics({
|
|
25
|
-
requestType: 'statistics',
|
|
26
|
-
axiosPrivate,
|
|
27
|
-
controller,
|
|
28
|
-
fromDate,
|
|
29
|
-
toDate,
|
|
30
|
-
}),
|
|
31
|
-
})
|
|
32
|
-
return (
|
|
33
|
-
<ContainerBox title={t('totalSessions')}>
|
|
34
|
-
{isLoading ? (
|
|
35
|
-
<LoadingSpinners single={true} />
|
|
36
|
-
) : (
|
|
37
|
-
<div className='text-4xl'>{formatNumber(data?.totalSessions)}</div>
|
|
38
|
-
)}
|
|
39
|
-
</ContainerBox>
|
|
40
|
-
)
|
|
41
|
-
}
|
|
1
|
+
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
+
import { formatNumber } from 'nextjs-cms/utils'
|
|
3
|
+
import ContainerBox from '@/components/ContainerBox'
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
6
|
+
import { useQuery } from '@tanstack/react-query'
|
|
7
|
+
import { getAnalytics } from '@/lib/apiHelpers'
|
|
8
|
+
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
9
|
+
|
|
10
|
+
export const TotalSessions = ({
|
|
11
|
+
fromDate,
|
|
12
|
+
toDate,
|
|
13
|
+
}: {
|
|
14
|
+
fromDate: Date | string | null
|
|
15
|
+
toDate: Date | string | null
|
|
16
|
+
}) => {
|
|
17
|
+
const t = useI18n()
|
|
18
|
+
const axiosPrivate = useAxiosPrivate()
|
|
19
|
+
const controller = new AbortController()
|
|
20
|
+
|
|
21
|
+
const { isLoading, isError, data, error } = useQuery({
|
|
22
|
+
queryKey: ['analyticsPage', 'statistics', fromDate, toDate],
|
|
23
|
+
queryFn: () =>
|
|
24
|
+
getAnalytics({
|
|
25
|
+
requestType: 'statistics',
|
|
26
|
+
axiosPrivate,
|
|
27
|
+
controller,
|
|
28
|
+
fromDate,
|
|
29
|
+
toDate,
|
|
30
|
+
}),
|
|
31
|
+
})
|
|
32
|
+
return (
|
|
33
|
+
<ContainerBox title={t('totalSessions')}>
|
|
34
|
+
{isLoading ? (
|
|
35
|
+
<LoadingSpinners single={true} />
|
|
36
|
+
) : (
|
|
37
|
+
<div className='text-4xl'>{formatNumber(data?.totalSessions)}</div>
|
|
38
|
+
)}
|
|
39
|
+
</ContainerBox>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
-
import { formatNumber } from 'nextjs-cms/utils'
|
|
3
|
-
import ContainerBox from '@/components/ContainerBox'
|
|
4
|
-
import React from 'react'
|
|
5
|
-
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
6
|
-
import { useQuery } from '@tanstack/react-query'
|
|
7
|
-
import { getAnalytics } from '@/lib/apiHelpers'
|
|
8
|
-
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
9
|
-
|
|
10
|
-
export const TotalUniqueUsers = ({
|
|
11
|
-
fromDate,
|
|
12
|
-
toDate,
|
|
13
|
-
}: {
|
|
14
|
-
fromDate: Date | string | null
|
|
15
|
-
toDate: Date | string | null
|
|
16
|
-
}) => {
|
|
17
|
-
const t = useI18n()
|
|
18
|
-
const axiosPrivate = useAxiosPrivate()
|
|
19
|
-
const controller = new AbortController()
|
|
20
|
-
|
|
21
|
-
const { isLoading, isError, data, error } = useQuery({
|
|
22
|
-
queryKey: ['analyticsPage', 'statistics', fromDate, toDate],
|
|
23
|
-
queryFn: () =>
|
|
24
|
-
getAnalytics({
|
|
25
|
-
requestType: 'statistics',
|
|
26
|
-
axiosPrivate,
|
|
27
|
-
controller,
|
|
28
|
-
fromDate,
|
|
29
|
-
toDate,
|
|
30
|
-
}),
|
|
31
|
-
})
|
|
32
|
-
return (
|
|
33
|
-
<ContainerBox title={t('totalUniqueUsers')}>
|
|
34
|
-
{isLoading ? (
|
|
35
|
-
<LoadingSpinners single={true} />
|
|
36
|
-
) : (
|
|
37
|
-
<div className='text-4xl'>{formatNumber(data?.totalUniqueUsers)}</div>
|
|
38
|
-
)}
|
|
39
|
-
</ContainerBox>
|
|
40
|
-
)
|
|
41
|
-
}
|
|
1
|
+
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
+
import { formatNumber } from 'nextjs-cms/utils'
|
|
3
|
+
import ContainerBox from '@/components/ContainerBox'
|
|
4
|
+
import React from 'react'
|
|
5
|
+
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
6
|
+
import { useQuery } from '@tanstack/react-query'
|
|
7
|
+
import { getAnalytics } from '@/lib/apiHelpers'
|
|
8
|
+
import LoadingSpinners from '@/components/LoadingSpinners'
|
|
9
|
+
|
|
10
|
+
export const TotalUniqueUsers = ({
|
|
11
|
+
fromDate,
|
|
12
|
+
toDate,
|
|
13
|
+
}: {
|
|
14
|
+
fromDate: Date | string | null
|
|
15
|
+
toDate: Date | string | null
|
|
16
|
+
}) => {
|
|
17
|
+
const t = useI18n()
|
|
18
|
+
const axiosPrivate = useAxiosPrivate()
|
|
19
|
+
const controller = new AbortController()
|
|
20
|
+
|
|
21
|
+
const { isLoading, isError, data, error } = useQuery({
|
|
22
|
+
queryKey: ['analyticsPage', 'statistics', fromDate, toDate],
|
|
23
|
+
queryFn: () =>
|
|
24
|
+
getAnalytics({
|
|
25
|
+
requestType: 'statistics',
|
|
26
|
+
axiosPrivate,
|
|
27
|
+
controller,
|
|
28
|
+
fromDate,
|
|
29
|
+
toDate,
|
|
30
|
+
}),
|
|
31
|
+
})
|
|
32
|
+
return (
|
|
33
|
+
<ContainerBox title={t('totalUniqueUsers')}>
|
|
34
|
+
{isLoading ? (
|
|
35
|
+
<LoadingSpinners single={true} />
|
|
36
|
+
) : (
|
|
37
|
+
<div className='text-4xl'>{formatNumber(data?.totalUniqueUsers)}</div>
|
|
38
|
+
)}
|
|
39
|
+
</ContainerBox>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
-
import ContainerBox from '@/components/ContainerBox'
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import { Variant } from 'nextjs-cms/core/types'
|
|
5
|
-
import useModal from '@/hooks/useModal'
|
|
6
|
-
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
7
|
-
import { handleVariantDeletion } from '@/lib/apiHelpers'
|
|
8
|
-
import { useToast } from '@/components/ui/use-toast'
|
|
9
|
-
import { Button } from '@/components/ui/button'
|
|
10
|
-
import VariantEditPage from '@/components/VariantEditPage'
|
|
11
|
-
|
|
12
|
-
const RightHomeRoomVariantCard = ({
|
|
13
|
-
variant,
|
|
14
|
-
variantItem,
|
|
15
|
-
sectionItemId,
|
|
16
|
-
action,
|
|
17
|
-
}: {
|
|
18
|
-
variant: Variant
|
|
19
|
-
variantItem: any
|
|
20
|
-
sectionItemId: string
|
|
21
|
-
action: any
|
|
22
|
-
}) => {
|
|
23
|
-
const t = useI18n()
|
|
24
|
-
const { setModal, modal, modalResponse, setModalResponse } = useModal()
|
|
25
|
-
const axiosPrivate = useAxiosPrivate()
|
|
26
|
-
const controller = new AbortController()
|
|
27
|
-
const { toast } = useToast()
|
|
28
|
-
|
|
29
|
-
const handleDelete = async () => {
|
|
30
|
-
const response = await handleVariantDeletion(variant.variant_name, variantItem.id, axiosPrivate, controller)
|
|
31
|
-
if (response.error) {
|
|
32
|
-
toast({
|
|
33
|
-
variant: 'destructive',
|
|
34
|
-
title: t('deleteAdmin'),
|
|
35
|
-
description: response.error.message,
|
|
36
|
-
})
|
|
37
|
-
} else if (response.code === 200) {
|
|
38
|
-
action ? action() : null
|
|
39
|
-
setModal(null)
|
|
40
|
-
setModalResponse(null)
|
|
41
|
-
toast({
|
|
42
|
-
variant: 'success',
|
|
43
|
-
title: t('itemDeletedSuccessfully'),
|
|
44
|
-
description: response.message,
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return (
|
|
49
|
-
<ContainerBox title={variantItem.display_name} key={variantItem.id}>
|
|
50
|
-
<div className='flex flex-col gap-4'>
|
|
51
|
-
<div className='flex flex-col gap-1'>
|
|
52
|
-
<div className='flex justify-between'>
|
|
53
|
-
<span className='font-bold'>Size From:</span>
|
|
54
|
-
<span>{variantItem.size_from}</span>
|
|
55
|
-
</div>
|
|
56
|
-
<div className='flex justify-between'>
|
|
57
|
-
<span className='font-bold'>Size To:</span>
|
|
58
|
-
<span>{variantItem.size_to}</span>
|
|
59
|
-
</div>
|
|
60
|
-
<div className='flex justify-between'>
|
|
61
|
-
<span className='font-bold'>Price:</span>
|
|
62
|
-
<span>{variantItem.price}</span>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
<div className='flex flex-row gap-2'>
|
|
66
|
-
<Button
|
|
67
|
-
size='sm'
|
|
68
|
-
type='button'
|
|
69
|
-
variant='default'
|
|
70
|
-
onClick={() => {
|
|
71
|
-
setModal({
|
|
72
|
-
size: 'lg',
|
|
73
|
-
title: t('edit'),
|
|
74
|
-
body: (
|
|
75
|
-
<div className='p-4'>
|
|
76
|
-
<VariantEditPage
|
|
77
|
-
section={variant.section_name}
|
|
78
|
-
variant={variant.variant_name}
|
|
79
|
-
sectionItemId={sectionItemId}
|
|
80
|
-
itemId={variantItem.id}
|
|
81
|
-
action={action}
|
|
82
|
-
/>
|
|
83
|
-
</div>
|
|
84
|
-
),
|
|
85
|
-
headerColor: 'bg-sky-700',
|
|
86
|
-
titleColor: 'text-white',
|
|
87
|
-
lang: 'en',
|
|
88
|
-
})
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
{t('edit')}
|
|
92
|
-
</Button>
|
|
93
|
-
{/* Delete Button */}
|
|
94
|
-
<Button
|
|
95
|
-
size='sm'
|
|
96
|
-
type='button'
|
|
97
|
-
variant='destructive'
|
|
98
|
-
onClick={() => {
|
|
99
|
-
setModal({
|
|
100
|
-
title: t('delete'),
|
|
101
|
-
body: (
|
|
102
|
-
<div className='p-4'>
|
|
103
|
-
<div className='flex flex-col gap-4'>
|
|
104
|
-
<div>{t('deleteItemText')}</div>
|
|
105
|
-
<div className='flex gap-2'>
|
|
106
|
-
<button
|
|
107
|
-
className='rounded bg-green-600 px-2 py-1 text-white'
|
|
108
|
-
onClick={handleDelete}
|
|
109
|
-
>
|
|
110
|
-
Yes
|
|
111
|
-
</button>
|
|
112
|
-
<button
|
|
113
|
-
className='rounded bg-red-800 px-2 py-1 text-white'
|
|
114
|
-
onClick={() => {
|
|
115
|
-
setModal(null)
|
|
116
|
-
}}
|
|
117
|
-
>
|
|
118
|
-
No
|
|
119
|
-
</button>
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
),
|
|
124
|
-
headerColor: 'bg-red-700',
|
|
125
|
-
titleColor: 'text-white',
|
|
126
|
-
lang: 'en',
|
|
127
|
-
})
|
|
128
|
-
}}
|
|
129
|
-
>
|
|
130
|
-
{t('delete')}
|
|
131
|
-
</Button>
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
</ContainerBox>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export default RightHomeRoomVariantCard
|
|
1
|
+
import { useI18n } from 'nextjs-cms/translations/client'
|
|
2
|
+
import ContainerBox from '@/components/ContainerBox'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Variant } from 'nextjs-cms/core/types'
|
|
5
|
+
import useModal from '@/hooks/useModal'
|
|
6
|
+
import { useAxiosPrivate } from 'nextjs-cms/auth/hooks'
|
|
7
|
+
import { handleVariantDeletion } from '@/lib/apiHelpers'
|
|
8
|
+
import { useToast } from '@/components/ui/use-toast'
|
|
9
|
+
import { Button } from '@/components/ui/button'
|
|
10
|
+
import VariantEditPage from '@/components/VariantEditPage'
|
|
11
|
+
|
|
12
|
+
const RightHomeRoomVariantCard = ({
|
|
13
|
+
variant,
|
|
14
|
+
variantItem,
|
|
15
|
+
sectionItemId,
|
|
16
|
+
action,
|
|
17
|
+
}: {
|
|
18
|
+
variant: Variant
|
|
19
|
+
variantItem: any
|
|
20
|
+
sectionItemId: string
|
|
21
|
+
action: any
|
|
22
|
+
}) => {
|
|
23
|
+
const t = useI18n()
|
|
24
|
+
const { setModal, modal, modalResponse, setModalResponse } = useModal()
|
|
25
|
+
const axiosPrivate = useAxiosPrivate()
|
|
26
|
+
const controller = new AbortController()
|
|
27
|
+
const { toast } = useToast()
|
|
28
|
+
|
|
29
|
+
const handleDelete = async () => {
|
|
30
|
+
const response = await handleVariantDeletion(variant.variant_name, variantItem.id, axiosPrivate, controller)
|
|
31
|
+
if (response.error) {
|
|
32
|
+
toast({
|
|
33
|
+
variant: 'destructive',
|
|
34
|
+
title: t('deleteAdmin'),
|
|
35
|
+
description: response.error.message,
|
|
36
|
+
})
|
|
37
|
+
} else if (response.code === 200) {
|
|
38
|
+
action ? action() : null
|
|
39
|
+
setModal(null)
|
|
40
|
+
setModalResponse(null)
|
|
41
|
+
toast({
|
|
42
|
+
variant: 'success',
|
|
43
|
+
title: t('itemDeletedSuccessfully'),
|
|
44
|
+
description: response.message,
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return (
|
|
49
|
+
<ContainerBox title={variantItem.display_name} key={variantItem.id}>
|
|
50
|
+
<div className='flex flex-col gap-4'>
|
|
51
|
+
<div className='flex flex-col gap-1'>
|
|
52
|
+
<div className='flex justify-between'>
|
|
53
|
+
<span className='font-bold'>Size From:</span>
|
|
54
|
+
<span>{variantItem.size_from}</span>
|
|
55
|
+
</div>
|
|
56
|
+
<div className='flex justify-between'>
|
|
57
|
+
<span className='font-bold'>Size To:</span>
|
|
58
|
+
<span>{variantItem.size_to}</span>
|
|
59
|
+
</div>
|
|
60
|
+
<div className='flex justify-between'>
|
|
61
|
+
<span className='font-bold'>Price:</span>
|
|
62
|
+
<span>{variantItem.price}</span>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
<div className='flex flex-row gap-2'>
|
|
66
|
+
<Button
|
|
67
|
+
size='sm'
|
|
68
|
+
type='button'
|
|
69
|
+
variant='default'
|
|
70
|
+
onClick={() => {
|
|
71
|
+
setModal({
|
|
72
|
+
size: 'lg',
|
|
73
|
+
title: t('edit'),
|
|
74
|
+
body: (
|
|
75
|
+
<div className='p-4'>
|
|
76
|
+
<VariantEditPage
|
|
77
|
+
section={variant.section_name}
|
|
78
|
+
variant={variant.variant_name}
|
|
79
|
+
sectionItemId={sectionItemId}
|
|
80
|
+
itemId={variantItem.id}
|
|
81
|
+
action={action}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
),
|
|
85
|
+
headerColor: 'bg-sky-700',
|
|
86
|
+
titleColor: 'text-white',
|
|
87
|
+
lang: 'en',
|
|
88
|
+
})
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
{t('edit')}
|
|
92
|
+
</Button>
|
|
93
|
+
{/* Delete Button */}
|
|
94
|
+
<Button
|
|
95
|
+
size='sm'
|
|
96
|
+
type='button'
|
|
97
|
+
variant='destructive'
|
|
98
|
+
onClick={() => {
|
|
99
|
+
setModal({
|
|
100
|
+
title: t('delete'),
|
|
101
|
+
body: (
|
|
102
|
+
<div className='p-4'>
|
|
103
|
+
<div className='flex flex-col gap-4'>
|
|
104
|
+
<div>{t('deleteItemText')}</div>
|
|
105
|
+
<div className='flex gap-2'>
|
|
106
|
+
<button
|
|
107
|
+
className='rounded bg-green-600 px-2 py-1 text-white'
|
|
108
|
+
onClick={handleDelete}
|
|
109
|
+
>
|
|
110
|
+
Yes
|
|
111
|
+
</button>
|
|
112
|
+
<button
|
|
113
|
+
className='rounded bg-red-800 px-2 py-1 text-white'
|
|
114
|
+
onClick={() => {
|
|
115
|
+
setModal(null)
|
|
116
|
+
}}
|
|
117
|
+
>
|
|
118
|
+
No
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
),
|
|
124
|
+
headerColor: 'bg-red-700',
|
|
125
|
+
titleColor: 'text-white',
|
|
126
|
+
lang: 'en',
|
|
127
|
+
})
|
|
128
|
+
}}
|
|
129
|
+
>
|
|
130
|
+
{t('delete')}
|
|
131
|
+
</Button>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</ContainerBox>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export default RightHomeRoomVariantCard
|