create-nextjs-cms 0.7.8 → 0.7.9

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.7.8",
3
+ "version": "0.7.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,14 +16,14 @@ export default function DashboardPage() {
16
16
  src='/examples/dashboard-light.png'
17
17
  width={1280}
18
18
  height={866}
19
- alt='Dashboard'
19
+ alt={t('dashboard') as string}
20
20
  className='block dark:hidden'
21
21
  />
22
22
  <Image
23
23
  src='/examples/dashboard-dark.png'
24
24
  width={1280}
25
25
  height={866}
26
- alt='Dashboard'
26
+ alt={t('dashboard') as string}
27
27
  className='hidden dark:block'
28
28
  />
29
29
  </div>
@@ -39,7 +39,7 @@ export default function LogPage() {
39
39
  if (isLoading) {
40
40
  return (
41
41
  <div className='flex w-full items-center justify-center p-8'>
42
- <Spinner className='size-8' />
42
+ <Spinner className='size-8' aria-label={t('loading') as string} />
43
43
  </div>
44
44
  )
45
45
  }
@@ -96,7 +96,7 @@ export default function Navbar(props: Props) {
96
96
  className='border-foreground text-foreground hover:text-foreground/90 relative inline-flex items-center justify-center rounded-md border p-2 focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800 focus:outline-hidden'
97
97
  >
98
98
  <span className='absolute -inset-0.5' />
99
- <span className='sr-only'>Open main menu</span>
99
+ <span className='sr-only'>{t('openMainMenu')}</span>
100
100
  <HamburgerMenuIcon className='block h-6 w-6' aria-hidden='true' />
101
101
  </button>
102
102
  </div>
@@ -123,7 +123,7 @@ export default function Navbar(props: Props) {
123
123
  <button
124
124
  type='button'
125
125
  className='relative flex h-10 items-center justify-center rounded-full focus:outline-hidden'
126
- aria-label='Notifications'
126
+ aria-label={t('notifications') as string}
127
127
  >
128
128
  <span className='absolute -inset-1.5' />
129
129
  <BellIcon className='h-6 w-6' />
@@ -198,7 +198,7 @@ export default function Navbar(props: Props) {
198
198
  className='relative flex h-10 items-center justify-center rounded-full'
199
199
  >
200
200
  <span className='absolute -inset-1.5' />
201
- <span className='sr-only'>Open user menu</span>
201
+ <span className='sr-only'>{t('openUserMenu')}</span>
202
202
  {session?.data?.user.image ? (
203
203
  <ProtectedImage
204
204
  section={'admins'}
@@ -215,7 +215,7 @@ export default function Navbar(props: Props) {
215
215
  src='/blank_avatar.png'
216
216
  height={40}
217
217
  width={40}
218
- alt='profile image'
218
+ alt={t('profileImage') as string}
219
219
  className='rounded-full ring-2 ring-amber-300 ring-inset'
220
220
  />
221
221
  )}
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/button'
7
7
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'
8
8
  import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
9
9
  import { SelectOption } from 'nextjs-cms/core/fields'
10
+ import { useI18n } from 'nextjs-cms/translations/client'
10
11
 
11
12
  export default function SelectBox({
12
13
  items,
@@ -19,8 +20,7 @@ export default function SelectBox({
19
20
  onChange: any
20
21
  classname: string
21
22
  }) {
22
- // Set the selected item,
23
- // check for defaultValue and set it if it exists,
23
+ const t = useI18n()
24
24
  const [selected, setSelected] = useState<SelectOption | undefined>(
25
25
  defaultValue !== undefined && defaultValue !== null
26
26
  ? items.find((item) => item.value?.toString() === defaultValue.toString())
@@ -61,9 +61,9 @@ export default function SelectBox({
61
61
  align='start'
62
62
  >
63
63
  <Command>
64
- <CommandInput placeholder='Search...' className='h-9' />
64
+ <CommandInput placeholder={t('searchDots') as string} className='h-9' />
65
65
  <CommandList>
66
- <CommandEmpty>No item found.</CommandEmpty>
66
+ <CommandEmpty>{t('noItemFound')}</CommandEmpty>
67
67
  <CommandGroup>
68
68
  {items.map((item: SelectOption, index: number) => {
69
69
  // Use label for searchable value, but include value in a way that we can identify it
@@ -60,7 +60,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string;
60
60
  'justify-start gap-2 p-4': true,
61
61
  })}
62
62
  >
63
- <Image src={props.logoUrlPath} alt='logo' width={32} height={32} />
63
+ <Image src={props.logoUrlPath} alt={t('logo') as string} width={32} height={32} />
64
64
  <span className='bg-transparent px-2 font-normal tracking-[0.1em] text-white/90 transition-all duration-150'>
65
65
  {props.logoText}
66
66
  </span>
@@ -181,7 +181,7 @@ const Sidebar = (props: SidebarProps & { logoUrlPath: string; logoText: string;
181
181
  src='/blank_avatar.png'
182
182
  height={36}
183
183
  width={36}
184
- alt='profile image'
184
+ alt={t('profileImage') as string}
185
185
  className='rounded-full ring-2 ring-amber-300 ring-inset'
186
186
  />
187
187
  )}
@@ -3,8 +3,10 @@ import { useEffect, useState } from 'react'
3
3
  import { SelectMultipleFieldClientConfig, SelectOption } from 'nextjs-cms/core/fields'
4
4
  import { useController, useFormContext } from 'react-hook-form'
5
5
  import { MultiSelect, MultiSelectOption } from '@/components/multi-select'
6
+ import { useI18n } from 'nextjs-cms/translations/client'
6
7
 
7
8
  export default function MultipleSelectFormInput({ input }: { input: SelectMultipleFieldClientConfig }) {
9
+ const t = useI18n()
8
10
  const { control } = useFormContext()
9
11
  const {
10
12
  field,
@@ -74,7 +76,7 @@ export default function MultipleSelectFormInput({ input }: { input: SelectMultip
74
76
  options={multiSelectOptions}
75
77
  onValueChange={handleValueChange}
76
78
  defaultValue={currentValue}
77
- // placeholder={input.label || 'Select options'}
79
+ placeholder={t('selectOptions') as string}
78
80
  disabled={field.disabled}
79
81
  className='w-full py-3 ring-2 ring-gray-300'
80
82
  />
@@ -126,7 +126,7 @@ export default function PhotoFormInput({ input, sectionName }: { input: PhotoFie
126
126
  <Image
127
127
  className='mb-4 rounded p-1 ring-3 ring-green-600'
128
128
  src={image}
129
- alt='new'
129
+ alt={t('newImage') as string}
130
130
  fill={true}
131
131
  style={{
132
132
  objectFit: 'contain',
@@ -6,6 +6,7 @@ import type { SlugFieldClientConfig } from 'nextjs-cms/core/fields'
6
6
  import { useFormContext, useController, useWatch } from 'react-hook-form'
7
7
  import { InputGroup, InputGroupInput, InputGroupAddon } from '@/components/ui/input-group'
8
8
  import { Link2 } from 'lucide-react'
9
+ import { useI18n } from 'nextjs-cms/translations/client'
9
10
 
10
11
  /**
11
12
  * Convert a string to a URL-friendly slug (for real-time input).
@@ -41,6 +42,7 @@ export default function SlugFormInput({
41
42
  direction?: 'row' | 'col'
42
43
  disabled?: boolean
43
44
  }) {
45
+ const t = useI18n()
44
46
  const { control } = useFormContext()
45
47
  const {
46
48
  field,
@@ -109,7 +111,7 @@ export default function SlugFormInput({
109
111
  required={input.required}
110
112
  >
111
113
  <InputGroup className='bg-input'>
112
- <InputGroupAddon align='inline-start' title='Auto-generated from linked field'>
114
+ <InputGroupAddon align='inline-start' title={t('autoGeneratedFromLinkedField') as string}>
113
115
  <Link2 className='h-4 w-4' />
114
116
  </InputGroupAddon>
115
117
  <InputGroupInput
@@ -3,6 +3,7 @@ import { cva, type VariantProps } from 'class-variance-authority'
3
3
  import { CheckIcon, XCircle, ChevronDown, XIcon, WandSparkles } from 'lucide-react'
4
4
 
5
5
  import { cn } from '@/lib/utils'
6
+ import { useI18n } from 'nextjs-cms/translations/client'
6
7
  import { Separator } from '@/components/ui/separator'
7
8
  import { Button } from '@/components/ui/button'
8
9
  import { Badge } from '@/components/ui/badge'
@@ -329,6 +330,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
329
330
  },
330
331
  ref,
331
332
  ) => {
333
+ const t = useI18n()
332
334
  const [selectedValues, setSelectedValues] = React.useState<string[]>(defaultValue)
333
335
  const [isPopoverOpen, setIsPopoverOpen] = React.useState(false)
334
336
  const [isAnimating, setIsAnimating] = React.useState(false)
@@ -911,7 +913,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
911
913
  handleClear()
912
914
  }
913
915
  }}
914
- aria-label={`Clear all ${selectedValues.length} selected options`}
916
+ aria-label={t('clearAllSelectedOptions', { count: String(selectedValues.length) }) as string}
915
917
  className='text-muted-foreground hover:text-foreground focus:ring-ring mx-2 flex h-4 w-4 cursor-pointer items-center justify-center rounded-sm focus:ring-2 focus:ring-offset-1 focus:outline-none'
916
918
  >
917
919
  <XIcon className='h-4 w-4' />
@@ -935,7 +937,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
935
937
  id={listboxId}
936
938
  role='listbox'
937
939
  aria-multiselectable='true'
938
- aria-label='Available options'
940
+ aria-label={t('availableOptions') as string}
939
941
  className={cn(
940
942
  'w-auto p-0',
941
943
  getPopoverAnimationClass(),
@@ -957,17 +959,17 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
957
959
  <Command>
958
960
  {searchable && (
959
961
  <CommandInput
960
- placeholder='Search options...'
962
+ placeholder={t('searchOptionsDots') as string}
961
963
  onKeyDown={handleInputKeyDown}
962
964
  value={searchValue}
963
965
  onValueChange={setSearchValue}
964
- aria-label='Search through available options'
966
+ aria-label={t('searchThroughOptions') as string}
965
967
  aria-describedby={`${multiSelectId}-search-help`}
966
968
  />
967
969
  )}
968
970
  {searchable && (
969
971
  <div id={`${multiSelectId}-search-help`} className='sr-only'>
970
- Type to filter options. Use arrow keys to navigate results.
972
+ {t('filterOptionsHint')}
971
973
  </div>
972
974
  )}
973
975
  <CommandList
@@ -1109,7 +1111,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
1109
1111
  onSelect={handleClear}
1110
1112
  className='flex-1 cursor-pointer justify-center'
1111
1113
  >
1112
- Clear
1114
+ {t('clear')}
1113
1115
  </CommandItem>
1114
1116
  <Separator orientation='vertical' className='flex h-full min-h-6' />
1115
1117
  </>
@@ -1118,7 +1120,7 @@ export const MultiSelect = React.forwardRef<MultiSelectRef, MultiSelectProps>(
1118
1120
  onSelect={() => setIsPopoverOpen(false)}
1119
1121
  className='max-w-full flex-1 cursor-pointer justify-center'
1120
1122
  >
1121
- Close
1123
+ {t('close')}
1122
1124
  </CommandItem>
1123
1125
  </div>
1124
1126
  </CommandGroup>
@@ -2,8 +2,10 @@ import { useState, useEffect } from 'react'
2
2
  import { useTheme } from 'next-themes'
3
3
  import { MoonIcon, SunIcon } from '@radix-ui/react-icons'
4
4
  import { Spinner } from '@/components/ui/spinner'
5
+ import { useI18n } from 'nextjs-cms/translations/client'
5
6
 
6
7
  const ThemeToggle = () => {
8
+ const t = useI18n()
7
9
  const [mounted, setMounted] = useState(false)
8
10
  const { theme, setTheme } = useTheme()
9
11
 
@@ -12,7 +14,7 @@ const ThemeToggle = () => {
12
14
  }, [])
13
15
 
14
16
  if (!mounted) {
15
- return <Spinner className='size-6' />
17
+ return <Spinner className='size-6' aria-label={t('loading') as string} />
16
18
  }
17
19
 
18
20
  return (
@@ -24,7 +26,7 @@ const ThemeToggle = () => {
24
26
  className='text-foreground hover:text-foreground/90 relative flex h-10 items-center justify-center rounded-full focus:outline-hidden cursor-pointer'
25
27
  >
26
28
  <span className='absolute -inset-1.5' />
27
- <span className='sr-only'>Theme</span>
29
+ <span className='sr-only'>{t('theme')}</span>
28
30
  {theme === 'dark' ? (
29
31
  <SunIcon className='h-6 w-6' aria-hidden='true' />
30
32
  ) : (
@@ -66,7 +66,7 @@
66
66
  "nanoid": "^5.1.2",
67
67
  "next": "16.1.1",
68
68
  "next-themes": "^0.4.6",
69
- "nextjs-cms": "0.7.8",
69
+ "nextjs-cms": "0.7.9",
70
70
  "plaiceholder": "^3.0.0",
71
71
  "prettier-plugin-tailwindcss": "^0.7.2",
72
72
  "qrcode": "^1.5.4",