create-nextjs-cms 0.6.4 → 0.6.6

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.4",
3
+ "version": "0.6.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,6 +24,7 @@ import {
24
24
  RichTextFieldClientConfig,
25
25
  SelectFieldClientConfig,
26
26
  SelectMultipleFieldClientConfig,
27
+ SlugFieldClientConfig,
27
28
  TextAreaFieldClientConfig,
28
29
  TextFieldClientConfig,
29
30
  VideoFieldClientConfig,
@@ -44,6 +45,7 @@ import {
44
45
  colorFieldSchema,
45
46
  mapFieldSchema,
46
47
  passwordFieldSchema,
48
+ slugFieldSchema,
47
49
  } from 'nextjs-cms/validators'
48
50
 
49
51
  import { ConditionalField, FieldType } from 'nextjs-cms/core/types'
@@ -191,6 +193,12 @@ export default function Form({
191
193
  [input.name]: passwordFieldSchema(input as PasswordFieldClientConfig),
192
194
  })
193
195
  break
196
+
197
+ case 'slug':
198
+ schema = schema.extend({
199
+ [input.name]: slugFieldSchema(input as SlugFieldClientConfig),
200
+ })
201
+ break
194
202
  }
195
203
  })
196
204
  })
@@ -14,6 +14,7 @@ import MapFormInput from '@/components/form/inputs/MapFormInput'
14
14
  import PasswordFormInput from '@/components/form/inputs/PasswordFormInput'
15
15
  import TextareaFormInput from '@/components/form/inputs/TextareaFormInput'
16
16
  import VideoFormInput from '@/components/form/inputs/VideoFormInput'
17
+ import SlugFormInput from '@/components/form/inputs/SlugFormInput'
17
18
  import type { FieldClientConfig } from 'nextjs-cms/core/fields'
18
19
  import {
19
20
  CheckboxFieldClientConfig,
@@ -31,6 +32,7 @@ import {
31
32
  TextAreaFieldClientConfig,
32
33
  TextFieldClientConfig,
33
34
  VideoFieldClientConfig,
35
+ SlugFieldClientConfig,
34
36
  } from 'nextjs-cms/core/fields'
35
37
 
36
38
  export default function FormInputs({ inputs, sectionName }: { inputs: FieldClientConfig[]; sectionName: string }) {
@@ -99,6 +101,8 @@ export default function FormInputs({ inputs, sectionName }: { inputs: FieldClien
99
101
  case 'checkbox':
100
102
  // case 'permission':
101
103
  return <CheckboxFormInput input={input as CheckboxFieldClientConfig} key={input.name} />
104
+ case 'slug':
105
+ return <SlugFormInput input={input as SlugFieldClientConfig} key={input.name} />
102
106
  default:
103
107
  return null
104
108
  }
@@ -8,4 +8,4 @@ export const revalidate = 0
8
8
 
9
9
  // @refresh reset
10
10
 
11
- export const configLastUpdated = 1769902638411
11
+ export const configLastUpdated = 1770135505357
@@ -0,0 +1,129 @@
1
+ 'use client'
2
+
3
+ import React, { useCallback, useEffect, useRef } from 'react'
4
+ import FormInputElement from '@/components/form/FormInputElement'
5
+ import type { SlugFieldClientConfig } from 'nextjs-cms/core/fields'
6
+ import { useFormContext, useController, useWatch } from 'react-hook-form'
7
+ import { InputGroup, InputGroupInput, InputGroupAddon } from '@/components/ui/input-group'
8
+ import { Link2 } from 'lucide-react'
9
+
10
+ /**
11
+ * Convert a string to a URL-friendly slug (for real-time input).
12
+ * - Converts to lowercase
13
+ * - Replaces spaces with hyphens
14
+ * - Removes special characters (keeps letters from any language, numbers, and hyphens)
15
+ * - Collapses multiple consecutive hyphens into one
16
+ * - Keeps trailing hyphen (user might still be typing)
17
+ */
18
+ function toSlugLive(value: string): string {
19
+ return value
20
+ .toLowerCase()
21
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
22
+ .replace(/[^\p{L}\p{N}-]/gu, '') // Remove special characters (keep Unicode letters/numbers)
23
+ .replace(/-+/g, '-') // Collapse multiple hyphens
24
+ .replace(/^-/, '') // Remove leading hyphen only
25
+ }
26
+
27
+ /**
28
+ * Normalize a slug (for blur/final value).
29
+ * Same as toSlugLive but also trims and removes trailing hyphens.
30
+ */
31
+ function toSlugFinal(value: string): string {
32
+ return toSlugLive(value.trim()).replace(/-$/, '') // Remove trailing hyphen
33
+ }
34
+
35
+ export default function SlugFormInput({
36
+ input,
37
+ direction,
38
+ disabled = false,
39
+ }: {
40
+ input: SlugFieldClientConfig
41
+ direction?: 'row' | 'col'
42
+ disabled?: boolean
43
+ }) {
44
+ const { control } = useFormContext()
45
+ const {
46
+ field,
47
+ fieldState: { error },
48
+ } = useController({
49
+ name: input.name,
50
+ control,
51
+ defaultValue: input.value ?? '',
52
+ disabled: disabled,
53
+ })
54
+
55
+ // Watch the source field value
56
+ const sourceFieldValue = useWatch({
57
+ control,
58
+ name: input.forFieldName,
59
+ defaultValue: '',
60
+ })
61
+
62
+ // Track previous source value to only update when it actually changes
63
+ const previousSourceValueRef = useRef<string>(sourceFieldValue ?? '')
64
+
65
+ // Auto-generate slug from source field when it changes
66
+ useEffect(() => {
67
+ const currentSourceValue = sourceFieldValue ?? ''
68
+
69
+ // Only update if the source field value actually changed
70
+ if (currentSourceValue !== previousSourceValueRef.current) {
71
+ previousSourceValueRef.current = currentSourceValue
72
+
73
+ if (currentSourceValue) {
74
+ const newSlug = toSlugFinal(currentSourceValue)
75
+ field.onChange(newSlug)
76
+ } else {
77
+ field.onChange('')
78
+ }
79
+ }
80
+ }, [sourceFieldValue, field])
81
+
82
+ // Handle manual changes to the slug field
83
+ const handleChange = useCallback(
84
+ (e: React.ChangeEvent<HTMLInputElement>) => {
85
+ const newValue = e.target.value
86
+ // Apply slug normalization in real-time
87
+ field.onChange(toSlugLive(newValue))
88
+ },
89
+ [field],
90
+ )
91
+
92
+ // Handle blur - finalize the slug value (remove trailing hyphens)
93
+ const handleBlur = useCallback(() => {
94
+ field.onBlur()
95
+ if (field.value) {
96
+ const finalSlug = toSlugFinal(field.value)
97
+ if (finalSlug !== field.value) {
98
+ field.onChange(finalSlug)
99
+ }
100
+ }
101
+ }, [field])
102
+
103
+ return (
104
+ <FormInputElement
105
+ validationError={error}
106
+ value={input.value}
107
+ readonly={input.readonly}
108
+ label={input.label}
109
+ required={input.required}
110
+ >
111
+ <InputGroup className='bg-input'>
112
+ <InputGroupAddon align='inline-start' title='Auto-generated from linked field'>
113
+ <Link2 className='h-4 w-4' />
114
+ </InputGroupAddon>
115
+ <InputGroupInput
116
+ placeholder={input.placeholder ? input.placeholder : input.label}
117
+ type='text'
118
+ readOnly={disabled}
119
+ disabled={field.disabled}
120
+ name={field.name}
121
+ onChange={handleChange}
122
+ onBlur={handleBlur}
123
+ value={field.value ?? ''}
124
+ ref={field.ref}
125
+ />
126
+ </InputGroup>
127
+ </FormInputElement>
128
+ )
129
+ }
@@ -0,0 +1,54 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { cn } from '@/lib/utils'
5
+
6
+ const InputGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
7
+ ({ className, ...props }, ref) => (
8
+ <div
9
+ ref={ref}
10
+ className={cn(
11
+ 'flex items-stretch overflow-hidden rounded shadow-xs ring-2 ring-gray-300 outline-0 hover:ring-gray-400 focus-within:ring-blue-500 hover:focus-within:ring-blue-500',
12
+ className,
13
+ )}
14
+ {...props}
15
+ />
16
+ ),
17
+ )
18
+ InputGroup.displayName = 'InputGroup'
19
+
20
+ const InputGroupInput = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(
21
+ ({ className, ...props }, ref) => (
22
+ <input
23
+ ref={ref}
24
+ className={cn(
25
+ 'placeholder:text-muted-foreground flex h-9 w-full bg-transparent px-3 py-1 text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
26
+ className,
27
+ )}
28
+ {...props}
29
+ />
30
+ ),
31
+ )
32
+ InputGroupInput.displayName = 'InputGroupInput'
33
+
34
+ interface InputGroupAddonProps extends React.HTMLAttributes<HTMLDivElement> {
35
+ align?: 'inline-start' | 'inline-end'
36
+ }
37
+
38
+ const InputGroupAddon = React.forwardRef<HTMLDivElement, InputGroupAddonProps>(
39
+ ({ className, align = 'inline-start', ...props }, ref) => (
40
+ <div
41
+ ref={ref}
42
+ className={cn(
43
+ 'text-muted-foreground bg-muted flex items-center justify-center px-3 text-sm',
44
+ align === 'inline-start' && 'order-first border-e border-gray-300',
45
+ align === 'inline-end' && 'order-last border-s border-gray-300',
46
+ className,
47
+ )}
48
+ {...props}
49
+ />
50
+ ),
51
+ )
52
+ InputGroupAddon.displayName = 'InputGroupAddon'
53
+
54
+ export { InputGroup, InputGroupInput, InputGroupAddon }
@@ -0,0 +1,383 @@
1
+ import {mysqlTable,int,longtext,mysqlEnum,varchar,boolean,double,timestamp} from 'drizzle-orm/mysql-core'
2
+
3
+ export const AppInfoTable = mysqlTable('app_info', {
4
+ id: int('id').autoincrement().notNull().primaryKey(),
5
+ aboutEn: longtext('about_en').notNull(),
6
+ aboutAr: longtext('about_ar').notNull(),
7
+ aboutTr: longtext('about_tr').notNull(),
8
+ privacyEn: longtext('privacy_en').notNull(),
9
+ privacyAr: longtext('privacy_ar').notNull(),
10
+ privacyTr: longtext('privacy_tr').notNull()
11
+ });
12
+
13
+
14
+ export const UserReportsTable = mysqlTable('user_reports', {
15
+ id: int('id').autoincrement().notNull().primaryKey(),
16
+ contentType: mysqlEnum('content_type', ['ad', 'user']).notNull(),
17
+ reportType: mysqlEnum('report_type', ['explicit_content', 'wrong_information', 'no_longer_available', 'user_not_responsive', 'other']).notNull(),
18
+ contentId: int('content_id').notNull(),
19
+ catId: int('cat_id').notNull(),
20
+ userId: int('user_id'),
21
+ appId: varchar('app_id', { length: 36 }).notNull(),
22
+ title: varchar('title', { length: 255 }).notNull(),
23
+ slug: varchar('slug', { length: 255 }).notNull()
24
+ });
25
+
26
+
27
+ export const FeaturedSliderTable = mysqlTable('featured_slider', {
28
+ id: int('id').autoincrement().notNull().primaryKey(),
29
+ image: varchar('image', { length: 255 }).notNull(),
30
+ titleEn: varchar('title_en', { length: 255 }).notNull(),
31
+ titleAr: varchar('title_ar', { length: 255 }).notNull(),
32
+ titleTr: varchar('title_tr', { length: 255 }).notNull(),
33
+ descEn: longtext('desc_en').notNull(),
34
+ descAr: longtext('desc_ar').notNull(),
35
+ descTr: longtext('desc_tr').notNull()
36
+ });
37
+
38
+
39
+ export const MenuSettingsTable = mysqlTable('menu_settings', {
40
+ id: int('id').autoincrement().notNull().primaryKey(),
41
+ taxRate: varchar('tax_rate', { length: 255 }),
42
+ hideSlider: boolean('hide_slider')
43
+ });
44
+
45
+
46
+ export const ServicesTable = mysqlTable('services', {
47
+ id: int('id').autoincrement().notNull().primaryKey(),
48
+ title: varchar('title', { length: 255 }).notNull(),
49
+ catId: int('cat_id').notNull(),
50
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
51
+ price: int('price'),
52
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']),
53
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
54
+ desc: longtext('desc'),
55
+ latitude: double('latitude'),
56
+ longitude: double('longitude'),
57
+ viewCount: int('view_count'),
58
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
59
+ govId: int('gov_id').notNull(),
60
+ districtId: int('district_id').notNull(),
61
+ subDistrictId: int('sub_district_id'),
62
+ townId: int('town_id')
63
+ });
64
+
65
+
66
+ export const RealestateTable = mysqlTable('realestate', {
67
+ id: int('id').autoincrement().notNull().primaryKey(),
68
+ catId: int('cat_id').notNull(),
69
+ title: varchar('title', { length: 255 }).notNull(),
70
+ price: int('price').notNull(),
71
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
72
+ spaceGross: int('space_gross').notNull(),
73
+ spaceNet: int('space_net').notNull(),
74
+ latitude: double('latitude').notNull(),
75
+ longitude: double('longitude').notNull(),
76
+ roomCount: varchar('room_count', { length: 255 }),
77
+ buildingAge: varchar('building_age', { length: 255 }),
78
+ floorCount: varchar('floor_count', { length: 255 }),
79
+ bathroomCount: varchar('bathroom_count', { length: 255 }),
80
+ floorLocation: varchar('floor_location', { length: 255 }),
81
+ heatingType: varchar('heating_type', { length: 255 }),
82
+ kitchenType: varchar('kitchen_type', { length: 255 }),
83
+ balcony: boolean('balcony'),
84
+ lift: boolean('lift'),
85
+ parkingType: varchar('parking_type', { length: 255 }),
86
+ furnished: boolean('furnished'),
87
+ belongsToSite: boolean('belongs_to_site'),
88
+ siteName: varchar('site_name', { length: 255 }),
89
+ installments: boolean('installments'),
90
+ exchangeable: boolean('exchangeable'),
91
+ fromWhom: varchar('from_whom', { length: 255 }),
92
+ buildingMembershipFees: int('building_membership_fees'),
93
+ deposit: int('deposit'),
94
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
95
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
96
+ desc: longtext('desc'),
97
+ viewCount: int('view_count'),
98
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
99
+ govId: int('gov_id').notNull(),
100
+ districtId: int('district_id').notNull(),
101
+ subDistrictId: int('sub_district_id'),
102
+ townId: int('town_id')
103
+ });
104
+
105
+
106
+ export const HomepageSliderTable = mysqlTable('homepage_slider', {
107
+ id: int('id').autoincrement().notNull().primaryKey(),
108
+ titleEn: varchar('title_en', { length: 255 }).notNull(),
109
+ titleAr: varchar('title_ar', { length: 255 }).notNull(),
110
+ titleTr: varchar('title_tr', { length: 255 }).notNull(),
111
+ subtitleEn: varchar('subtitle_en', { length: 255 }).notNull(),
112
+ subtitleAr: varchar('subtitle_ar', { length: 255 }).notNull(),
113
+ subtitleTr: varchar('subtitle_tr', { length: 255 }).notNull(),
114
+ photo: varchar('photo', { length: 255 }).notNull(),
115
+ buttonUrl: varchar('button_url', { length: 255 }),
116
+ buttonTextEn: varchar('button_text_en', { length: 255 }),
117
+ buttonTextAr: varchar('button_text_ar', { length: 255 }),
118
+ buttonTextTr: varchar('button_text_tr', { length: 255 }),
119
+ buttonUrlTarget: mysqlEnum('button_url_target', ['_blank', '_self'])
120
+ });
121
+
122
+
123
+ export const ContestSubscribersTable = mysqlTable('contest_subscribers', {
124
+ id: int('id').autoincrement().notNull().primaryKey(),
125
+ userId: int('user_id').notNull(),
126
+ contestId: varchar('contest_id', { length: 255 }).notNull()
127
+ });
128
+
129
+
130
+ export const ContestsTable = mysqlTable('contests', {
131
+ id: int('id').autoincrement().notNull().primaryKey(),
132
+ date: timestamp('date').notNull(),
133
+ prize: varchar('prize', { length: 255 }).notNull(),
134
+ winnerId: int('winner_id'),
135
+ tags: varchar('tags', { length: 255 })
136
+ });
137
+
138
+
139
+ export const NotificationsTable = mysqlTable('notifications', {
140
+ id: int('id').autoincrement().notNull().primaryKey(),
141
+ type: mysqlEnum('type', ['ad_price_updated', 'ad_updated', 'ad_activated', 'ad_pending_review', 'ad_expired', 'ad_rejected', 'ad_viewed', 'ad_favorited', 'ad_shared', 'ad_reported', 'ad_deleted', 'ad_created', 'contest_winner', 'contest_reminder', 'contest_created', 'custom']).notNull(),
142
+ contentId: int('content_id'),
143
+ contentCatId: int('content_cat_id'),
144
+ userId: int('user_id'),
145
+ message: varchar('message', { length: 255 })
146
+ });
147
+
148
+
149
+ export const ModerationTable = mysqlTable('moderation', {
150
+ id: int('id').autoincrement().notNull().primaryKey(),
151
+ contentType: mysqlEnum('content_type', ['ad', 'user']).notNull(),
152
+ contentId: int('content_id').notNull(),
153
+ catId: int('cat_id'),
154
+ userId: int('user_id').notNull(),
155
+ flagged: int('flagged').notNull(),
156
+ result: varchar('result', { length: 255 }).notNull()
157
+ });
158
+
159
+
160
+ export const JobsTable = mysqlTable('jobs', {
161
+ id: int('id').autoincrement().notNull().primaryKey(),
162
+ title: varchar('title', { length: 255 }).notNull(),
163
+ catId: int('cat_id').notNull(),
164
+ salary: int('salary'),
165
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
166
+ workMethod: varchar('work_method', { length: 255 }).notNull(),
167
+ minimumEducation: varchar('minimum_education', { length: 255 }).notNull(),
168
+ experienceLevel: varchar('experience_level', { length: 255 }).notNull(),
169
+ remote: boolean('remote'),
170
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
171
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
172
+ desc: longtext('desc'),
173
+ latitude: double('latitude'),
174
+ longitude: double('longitude'),
175
+ viewCount: int('view_count'),
176
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
177
+ govId: int('gov_id').notNull(),
178
+ districtId: int('district_id').notNull(),
179
+ subDistrictId: int('sub_district_id'),
180
+ townId: int('town_id')
181
+ });
182
+
183
+
184
+ export const FurnitureTable = mysqlTable('furniture', {
185
+ id: int('id').autoincrement().notNull().primaryKey(),
186
+ title: varchar('title', { length: 255 }).notNull(),
187
+ catId: int('cat_id').notNull(),
188
+ condition: varchar('condition', { length: 255 }).notNull(),
189
+ price: int('price').notNull(),
190
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
191
+ exchangeable: boolean('exchangeable'),
192
+ fromWhom: varchar('from_whom', { length: 255 }).notNull(),
193
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
194
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
195
+ desc: longtext('desc'),
196
+ latitude: double('latitude'),
197
+ longitude: double('longitude'),
198
+ viewCount: int('view_count'),
199
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
200
+ govId: int('gov_id').notNull(),
201
+ districtId: int('district_id').notNull(),
202
+ subDistrictId: int('sub_district_id'),
203
+ townId: int('town_id')
204
+ });
205
+
206
+
207
+ export const FiltersTable = mysqlTable('filters', {
208
+ id: int('id').autoincrement().notNull().primaryKey(),
209
+ title: varchar('title', { length: 255 }).notNull(),
210
+ Key: varchar('_key', { length: 255 }).notNull(),
211
+ fieldName: varchar('field_name', { length: 255 }).notNull(),
212
+ type: mysqlEnum('type', ['checkbox', 'select', 'text', 'finance', 'number', 'point']).notNull(),
213
+ tableName: varchar('table_name', { length: 255 }),
214
+ isMandatory: boolean('is_mandatory')
215
+ });
216
+
217
+
218
+ export const FaqTable = mysqlTable('faq', {
219
+ id: int('id').autoincrement().notNull().primaryKey(),
220
+ qEn: varchar('q_en', { length: 255 }).notNull(),
221
+ qAr: varchar('q_ar', { length: 255 }).notNull(),
222
+ qTr: varchar('q_tr', { length: 255 }),
223
+ aEn: longtext('a_en').notNull(),
224
+ aAr: longtext('a_ar'),
225
+ aTr: longtext('a_tr')
226
+ });
227
+
228
+
229
+ export const ErrorsTable = mysqlTable('errors', {
230
+ id: int('id').autoincrement().notNull().primaryKey(),
231
+ title: varchar('title', { length: 255 }).notNull(),
232
+ caseId: varchar('case_id', { length: 255 }).notNull(),
233
+ userId: int('user_id'),
234
+ itemSlug: varchar('item_slug', { length: 255 }),
235
+ desc: longtext('desc'),
236
+ isResolved: boolean('is_resolved')
237
+ });
238
+
239
+
240
+ export const ElectronicsTable = mysqlTable('electronics', {
241
+ id: int('id').autoincrement().notNull().primaryKey(),
242
+ title: varchar('title', { length: 255 }).notNull(),
243
+ catId: int('cat_id').notNull(),
244
+ condition: varchar('condition', { length: 255 }).notNull(),
245
+ price: int('price').notNull(),
246
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
247
+ exchangeable: boolean('exchangeable'),
248
+ installments: boolean('installments'),
249
+ fromWhom: varchar('from_whom', { length: 255 }).notNull(),
250
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
251
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
252
+ desc: longtext('desc'),
253
+ latitude: double('latitude'),
254
+ longitude: double('longitude'),
255
+ viewCount: int('view_count'),
256
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
257
+ govId: int('gov_id').notNull(),
258
+ districtId: int('district_id').notNull(),
259
+ subDistrictId: int('sub_district_id'),
260
+ townId: int('town_id')
261
+ });
262
+
263
+
264
+ export const ClothesTable = mysqlTable('clothes', {
265
+ id: int('id').autoincrement().notNull().primaryKey(),
266
+ title: varchar('title', { length: 255 }).notNull(),
267
+ catId: int('cat_id').notNull(),
268
+ condition: varchar('condition', { length: 255 }).notNull(),
269
+ price: int('price').notNull(),
270
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
271
+ exchangeable: boolean('exchangeable'),
272
+ fromWhom: varchar('from_whom', { length: 255 }).notNull(),
273
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
274
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
275
+ desc: longtext('desc'),
276
+ latitude: double('latitude'),
277
+ longitude: double('longitude'),
278
+ viewCount: int('view_count'),
279
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
280
+ govId: int('gov_id').notNull(),
281
+ districtId: int('district_id').notNull(),
282
+ subDistrictId: int('sub_district_id'),
283
+ townId: int('town_id')
284
+ });
285
+
286
+
287
+ export const CatsTable = mysqlTable('cats', {
288
+ id: int('id').autoincrement().notNull().primaryKey(),
289
+ catOrder: int('cat_order').notNull(),
290
+ slug: varchar('slug', { length: 255 }).notNull(),
291
+ titleEn: varchar('title_en', { length: 255 }).notNull(),
292
+ titleAr: varchar('title_ar', { length: 255 }).notNull(),
293
+ titleTr: varchar('title_tr', { length: 255 }).notNull(),
294
+ fullTitleEn: varchar('full_title_en', { length: 255 }),
295
+ fullTitleAr: varchar('full_title_ar', { length: 255 }),
296
+ fullTitleTr: varchar('full_title_tr', { length: 255 }),
297
+ image: varchar('image', { length: 255 }),
298
+ metaDescEn: varchar('meta_desc_en', { length: 255 }),
299
+ metaDescAr: varchar('meta_desc_ar', { length: 255 }),
300
+ metaDescTr: varchar('meta_desc_tr', { length: 255 }),
301
+ filters: varchar('filters', { length: 255 }),
302
+ tableName: varchar('table_name', { length: 255 }).notNull(),
303
+ adCount: int('ad_count'),
304
+ parentId: int('parent_id'),
305
+ level: int('level')
306
+ });
307
+
308
+
309
+ export const CarsTable = mysqlTable('cars', {
310
+ id: int('id').autoincrement().notNull().primaryKey(),
311
+ modelYear: int('model_year').notNull(),
312
+ model: varchar('model', { length: 255 }).notNull(),
313
+ title: varchar('title', { length: 255 }).notNull(),
314
+ catId: int('cat_id').notNull(),
315
+ govId: int('gov_id').notNull(),
316
+ districtId: int('district_id').notNull(),
317
+ subDistrictId: int('sub_district_id'),
318
+ townId: int('town_id'),
319
+ price: int('price').notNull(),
320
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
321
+ condition: varchar('condition', { length: 255 }).notNull(),
322
+ fromWhom: varchar('from_whom', { length: 255 }).notNull(),
323
+ engineCapacity: varchar('engine_capacity', { length: 255 }).notNull(),
324
+ enginePower: varchar('engine_power', { length: 255 }).notNull(),
325
+ tractionType: varchar('traction_type', { length: 255 }).notNull(),
326
+ bodyType: varchar('body_type', { length: 255 }).notNull(),
327
+ gearType: varchar('gear_type', { length: 255 }).notNull(),
328
+ fuelType: varchar('fuel_type', { length: 255 }).notNull(),
329
+ exchangeable: boolean('exchangeable'),
330
+ installments: boolean('installments'),
331
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
332
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
333
+ desc: longtext('desc'),
334
+ latitude: double('latitude'),
335
+ longitude: double('longitude'),
336
+ viewCount: int('view_count'),
337
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired'])
338
+ });
339
+
340
+
341
+ export const CarsDbTable = mysqlTable('cars_db', {
342
+ id: int('id').autoincrement().notNull().primaryKey(),
343
+ name: varchar('name', { length: 255 }).notNull(),
344
+ parentId: int('parent_id'),
345
+ level: int('level')
346
+ });
347
+
348
+
349
+ export const BooksTable = mysqlTable('books', {
350
+ id: int('id').autoincrement().notNull().primaryKey(),
351
+ title: varchar('title', { length: 255 }).notNull(),
352
+ catId: int('cat_id').notNull(),
353
+ condition: varchar('condition', { length: 255 }).notNull(),
354
+ price: int('price').notNull(),
355
+ currency: mysqlEnum('currency', ['USD', 'TRY', 'SYP']).notNull(),
356
+ exchangeable: boolean('exchangeable'),
357
+ fromWhom: varchar('from_whom', { length: 255 }).notNull(),
358
+ coverphoto: varchar('coverphoto', { length: 255 }).notNull(),
359
+ coverphotoPlaceholder: varchar('coverphoto_placeholder', { length: 255 }),
360
+ desc: longtext('desc'),
361
+ latitude: double('latitude'),
362
+ longitude: double('longitude'),
363
+ viewCount: int('view_count'),
364
+ status: mysqlEnum('status', ['pending_creation', 'active', 'pending_review', 'rejected', 'expired']),
365
+ govId: int('gov_id').notNull(),
366
+ districtId: int('district_id').notNull(),
367
+ subDistrictId: int('sub_district_id'),
368
+ townId: int('town_id')
369
+ });
370
+
371
+
372
+ export const AddressTable = mysqlTable('address', {
373
+ id: int('id').autoincrement().notNull().primaryKey(),
374
+ catOrder: int('cat_order').notNull(),
375
+ titleEn: varchar('title_en', { length: 255 }).notNull(),
376
+ titleAr: varchar('title_ar', { length: 255 }).notNull(),
377
+ titleTr: varchar('title_tr', { length: 255 }).notNull(),
378
+ image: varchar('image', { length: 255 }),
379
+ path: varchar('path', { length: 255 }),
380
+ parentId: int('parent_id'),
381
+ level: int('level')
382
+ });
383
+
@@ -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.4",
68
+ "nextjs-cms": "0.6.6",
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.4",
101
+ "nextjs-cms-kit": "0.6.6",
102
102
  "postcss": "^8.5.1",
103
103
  "prettier": "3.5.0",
104
104
  "raw-loader": "^4.0.2",