create-nextjs-cms 0.6.2 → 0.6.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-nextjs-cms",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,8 +29,8 @@
29
29
  "tsx": "^4.20.6",
30
30
  "typescript": "^5.9.2",
31
31
  "@lzcms/eslint-config": "0.3.0",
32
- "@lzcms/prettier-config": "0.1.0",
33
- "@lzcms/tsconfig": "0.1.0"
32
+ "@lzcms/tsconfig": "0.1.0",
33
+ "@lzcms/prettier-config": "0.1.0"
34
34
  },
35
35
  "prettier": "@lzcms/prettier-config",
36
36
  "scripts": {
@@ -11,6 +11,7 @@ import { Button } from '@/components/ui/button'
11
11
  import { MoonIcon, SunIcon } from '@radix-ui/react-icons'
12
12
  import { useTheme } from 'next-themes'
13
13
  import { login, useSession } from 'nextjs-cms/auth/react'
14
+ import { wasLocaleChangedOnLogin } from 'nextjs-cms/translations'
14
15
  import LoginLocaleDropdown from '@/components/login-locale-dropdown'
15
16
  import { useAuthLocale } from '../../auth-locale-provider'
16
17
 
@@ -38,10 +39,13 @@ export default function LoginPage() {
38
39
  loginButtonRef.current.innerHTML = t('loading')
39
40
  }
40
41
  try {
42
+ // Only send locale if user explicitly changed it on login page
43
+ // Otherwise, server will use admin's stored DB preference
44
+ const localeChanged = wasLocaleChangedOnLogin()
41
45
  await login({
42
46
  username: formRef.current?.username.value,
43
47
  password: formRef.current?.password.value,
44
- locale: initialLocale,
48
+ locale: localeChanged ? initialLocale : undefined,
45
49
  })
46
50
  } catch (error: any) {
47
51
  if (loginButtonRef.current) {
@@ -54,7 +54,7 @@ export default async function CMSLayout({ children }: { children: React.ReactNod
54
54
  >
55
55
  <Providers session={session ?? undefined}>
56
56
  <HydrateClient>
57
- <Layout logoUrlPath={cmsConfig.ui.logo} logoText={cmsConfig.ui.logoText}>
57
+ <Layout logoUrlPath={cmsConfig.ui.logo} logoText={cmsConfig.ui.logoText} isRTL={isRTL}>
58
58
  {children}
59
59
  </Layout>
60
60
  </HydrateClient>
@@ -4,10 +4,7 @@ import ar from 'nextjs-cms/translations/dictionaries/ar'
4
4
  import process from 'process'
5
5
  import { resolve } from 'path'
6
6
 
7
- export const config: CMSConfig = {
8
- dashboard: {
9
- override: '/cpanel-dashboard',
10
- },
7
+ export const config: CMSConfig = {
11
8
  title: 'NEXTJS CMS',
12
9
  defaultTheme: 'dark',
13
10
  },
@@ -11,13 +11,12 @@ import { Button } from '@/components/ui/button'
11
11
  import { trpc } from '@/app/_trpc/client'
12
12
  import Image from 'next/image'
13
13
  import type { RouterOutputs } from 'nextjs-cms/api'
14
-
15
14
  export default function AdminCard({
16
15
  admin,
17
16
  action,
18
17
  }: {
19
- admin: RouterOutputs['admins']['list']['admins'][0]
20
- action: any
18
+ admin: NonNullable<RouterOutputs['admins']['list']['admins']>[number]
19
+ action: () => void
21
20
  }) {
22
21
  const t = useI18n()
23
22
  const { setModal, modal, modalResponse, setModalResponse } = useModal()
@@ -16,7 +16,7 @@ export default function AdminRoleCard({
16
16
  publisher: false,
17
17
  }
18
18
  }: {
19
- privilege: RouterOutputs['admins']['list']['privileges'][0]
19
+ privilege: NonNullable<RouterOutputs['admins']['list']['privileges']>[number]
20
20
  allChecked: boolean | 'edited' | null
21
21
  setAllChecked: React.Dispatch<React.SetStateAction<boolean | 'edited' | null>>
22
22
  defaultValue?: {
@@ -13,10 +13,12 @@ function Layout({
13
13
  children,
14
14
  logoUrlPath,
15
15
  logoText,
16
+ isRTL,
16
17
  }: {
17
18
  children: React.ReactNode
18
19
  logoUrlPath: string
19
20
  logoText: string
21
+ isRTL: boolean
20
22
  }) {
21
23
  const [showMobileSidebar, setShowMobileSidebar] = useState(false)
22
24
  const session = useSession({
@@ -44,6 +46,7 @@ function Layout({
44
46
  mobileSidebar={showMobileSidebar}
45
47
  logoUrlPath={logoUrlPath}
46
48
  logoText={logoText}
49
+ isRTL={isRTL}
47
50
  />
48
51
  {showMobileSidebar && (
49
52
  // Display a black transparent div to close the sidebar when clicked outside
@@ -55,7 +58,8 @@ function Layout({
55
58
  <div
56
59
  className={classNames({
57
60
  'transition-all duration-100 ease-in-out': true,
58
- 'float-right rtl:float-left': true,
61
+ 'float-right': !isRTL,
62
+ 'float-left': isRTL,
59
63
  'w-full md:w-[calc(100%-275px)]': true,
60
64
  })}
61
65
  >
@@ -12,7 +12,7 @@ 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
- const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }) => {
15
+ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string; isRTL: boolean }) => {
16
16
  const t = useI18n()
17
17
  const session = useSession()
18
18
  const [navItems] = trpc.navigation.getSidebar.useSuspenseQuery()
@@ -30,7 +30,6 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
30
30
  })
31
31
  }
32
32
  }
33
- const isRTL = session?.data?.user?.locale === 'ar'
34
33
  return (
35
34
  <div
36
35
  className={classNames({
@@ -39,12 +38,14 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
39
38
  'transition-all duration-100 ease-in-out': true,
40
39
  'w-[300px] md:w-[275px]': true,
41
40
  // LTR: sidebar on left, slides in from left
42
- 'left-0 md:translate-x-0': true,
43
- '-translate-x-full': !props.mobileSidebar,
41
+ 'left-0': !props.isRTL,
42
+ 'md:translate-x-0': !props.isRTL,
43
+ '-translate-x-full': !props.isRTL && !props.mobileSidebar,
44
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,
45
+ 'right-0': props.isRTL,
46
+ 'translate-x-full md:translate-x-0': props.isRTL && !props.mobileSidebar,
47
+ // Mobile sidebar shown (both LTR and RTL)
48
+ 'translate-x-0': props.mobileSidebar,
48
49
  })}
49
50
  >
50
51
  <div
@@ -64,7 +65,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string }
64
65
  {props.logoText}
65
66
  </span>
66
67
  </div>
67
- <ScrollArea dir={isRTL ? 'rtl' : 'ltr'} type='always' className='grow'>
68
+ <ScrollArea dir={props.isRTL ? 'rtl' : 'ltr'} type='always' className='grow'>
68
69
  <ul
69
70
  className={classNames({
70
71
  'my-2 flex flex-col items-stretch gap-2': true,
@@ -28,7 +28,7 @@ export default function SidebarDropdownItem({ item, closeSideBar }: SidebarItemP
28
28
  {open ? (
29
29
  <ChevronUpIcon className='h-5 w-5' />
30
30
  ) : (
31
- <ChevronDownIcon className='h-5 w-5 rtl:rotate-0' />
31
+ <ChevronDownIcon className='h-5 w-5' />
32
32
  )}
33
33
  </span>
34
34
  </li>
@@ -8,4 +8,4 @@ export const revalidate = 0
8
8
 
9
9
  // @refresh reset
10
10
 
11
- export const configLastUpdated = 1769812496863
11
+ export const configLastUpdated = 1769902638411
@@ -3,7 +3,7 @@
3
3
  import { useCallback } from 'react'
4
4
  import { useRouter } from 'next/navigation'
5
5
  import { useI18n } from 'nextjs-cms/translations/client'
6
- import { setLoginPageLocaleCookie } from 'nextjs-cms/translations'
6
+ import { setLoginPageLocaleCookie, markLocaleChangedOnLogin } from 'nextjs-cms/translations'
7
7
  import LocalePicker from './locale-picker'
8
8
 
9
9
  export interface LoginLocaleDropdownProps {
@@ -29,6 +29,7 @@ export default function LoginLocaleDropdown({
29
29
  (locale: string) => {
30
30
  if (locale === currentLocale) return
31
31
  setLoginPageLocaleCookie(locale)
32
+ markLocaleChangedOnLogin()
32
33
  router.refresh()
33
34
  },
34
35
  [currentLocale, router],
@@ -12,6 +12,7 @@ const badgeVariants = cva(
12
12
  default: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
13
13
  primary: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
14
14
  secondary: 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
15
+ success: 'border-transparent bg-green-500 text-white [a&]:hover:bg-green-600',
15
16
  destructive:
16
17
  'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
17
18
  outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
@@ -65,7 +65,7 @@
65
65
  "nanoid": "^5.1.2",
66
66
  "next": "16.1.1",
67
67
  "next-themes": "^0.4.6",
68
- "nextjs-cms": "0.6.2",
68
+ "nextjs-cms": "0.6.4",
69
69
  "plaiceholder": "^3.0.0",
70
70
  "prettier-plugin-tailwindcss": "^0.7.2",
71
71
  "qrcode": "^1.5.4",
@@ -98,7 +98,7 @@
98
98
  "eslint-config-prettier": "^10.0.1",
99
99
  "eslint-plugin-prettier": "^5.2.3",
100
100
  "fs-extra": "^11.3.3",
101
- "nextjs-cms-kit": "0.6.2",
101
+ "nextjs-cms-kit": "0.6.4",
102
102
  "postcss": "^8.5.1",
103
103
  "prettier": "3.5.0",
104
104
  "raw-loader": "^4.0.2",