nexstruct 1.0.0

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 (229) hide show
  1. package/AGENTS.md +122 -0
  2. package/LICENSE +21 -0
  3. package/README.md +103 -0
  4. package/package.json +99 -0
  5. package/scaffold/generator.js +409 -0
  6. package/scaffold/index.js +20 -0
  7. package/scaffold/prompts.js +108 -0
  8. package/templates/api/axios/src/api/axios/client.api.ts +30 -0
  9. package/templates/api/axios/src/api/axios/users.api.ts +15 -0
  10. package/templates/api/fetch/src/api/fetch/client.api.ts +68 -0
  11. package/templates/api/fetch/src/api/fetch/users.api.ts +15 -0
  12. package/templates/api/trpc/src/api/trpc/client.api.ts +4 -0
  13. package/templates/api/trpc/src/api/trpc/router.api.ts +15 -0
  14. package/templates/api/trpc/src/api/trpc/server.client.api.ts +4 -0
  15. package/templates/api/trpc/src/providers/trpc.provider.tsx +24 -0
  16. package/templates/auth/clerk/src/auth/clerk/auth.service.ts +4 -0
  17. package/templates/auth/clerk/src/hooks/use-auth.hook.ts +13 -0
  18. package/templates/auth/clerk/src/middleware.ts +7 -0
  19. package/templates/auth/clerk/src/providers/auth.provider.tsx +6 -0
  20. package/templates/auth/next-auth/src/app/api/auth/[...nextauth]/route.ts +5 -0
  21. package/templates/auth/next-auth/src/auth/next-auth/auth.service.ts +45 -0
  22. package/templates/auth/next-auth/src/hooks/use-session.hook.ts +13 -0
  23. package/templates/auth/next-auth/src/providers/session.provider.tsx +6 -0
  24. package/templates/forms/formik/src/components/forms/login-form.component.tsx +30 -0
  25. package/templates/forms/formik/src/forms/formik/hooks/use-form-config.hook.ts +7 -0
  26. package/templates/forms/formik/src/forms/formik/schemas/example.schema.ts +8 -0
  27. package/templates/forms/react-hook-form/src/components/forms/login-form.component.tsx +27 -0
  28. package/templates/forms/react-hook-form/src/forms/react-hook-form/hooks/use-form.hook.ts +13 -0
  29. package/templates/forms/react-hook-form/src/forms/react-hook-form/schemas/example.schema.ts +15 -0
  30. package/templates/nextjs-base/next.config.ts +5 -0
  31. package/templates/nextjs-base/postcss.config.mjs +9 -0
  32. package/templates/nextjs-base/src/app/_components/navbar.tsx +88 -0
  33. package/templates/nextjs-base/src/app/_components/sidebar.tsx +223 -0
  34. package/templates/nextjs-base/src/app/error.tsx +39 -0
  35. package/templates/nextjs-base/src/app/globals.css +71 -0
  36. package/templates/nextjs-base/src/app/layout.tsx +21 -0
  37. package/templates/nextjs-base/src/app/loading.tsx +13 -0
  38. package/templates/nextjs-base/src/app/not-found.tsx +22 -0
  39. package/templates/nextjs-base/src/app/page.tsx +10 -0
  40. package/templates/nextjs-base/tailwind.config.ts +69 -0
  41. package/templates/shared/src/components/common/theme-toggle.component.tsx +31 -0
  42. package/templates/shared/src/components/common/toast/custom-message.component.tsx +18 -0
  43. package/templates/shared/src/components/common/toast/index.ts +8 -0
  44. package/templates/shared/src/components/common/toast/toast-message.component.tsx +112 -0
  45. package/templates/shared/src/hooks/use-debounce.hook.ts +12 -0
  46. package/templates/shared/src/hooks/use-fetch.hook.ts +42 -0
  47. package/templates/shared/src/hooks/use-intersection-observer.hook.ts +39 -0
  48. package/templates/shared/src/hooks/use-local-storage.hook.ts +30 -0
  49. package/templates/shared/src/hooks/use-media-query.hook.ts +26 -0
  50. package/templates/shared/src/hooks/use-toggle.hook.ts +12 -0
  51. package/templates/shared/src/lib/utils.util.ts +361 -0
  52. package/templates/shared/src/providers/theme.provider.tsx +17 -0
  53. package/templates/shared/src/providers/toast.provider.tsx +32 -0
  54. package/templates/shared/src/types/common.type.ts +34 -0
  55. package/templates/state/context/src/store/context/auth.context.tsx +47 -0
  56. package/templates/state/context/src/store/context/counter.context.tsx +41 -0
  57. package/templates/state/context/src/store/context/index.ts +2 -0
  58. package/templates/state/redux/src/providers/redux.provider.tsx +7 -0
  59. package/templates/state/redux/src/store/redux/hooks.store.ts +5 -0
  60. package/templates/state/redux/src/store/redux/index.ts +4 -0
  61. package/templates/state/redux/src/store/redux/slices/api.slice.ts +8 -0
  62. package/templates/state/redux/src/store/redux/slices/counter.slice.ts +24 -0
  63. package/templates/state/redux/src/store/redux/store.store.ts +13 -0
  64. package/templates/state/zustand/src/store/zustand/counter.store.ts +15 -0
  65. package/templates/state/zustand/src/store/zustand/index.ts +2 -0
  66. package/templates/state/zustand/src/store/zustand/user.store.ts +32 -0
  67. package/templates/ui/antd/COMPONENT_GUIDE.md +326 -0
  68. package/templates/ui/antd/src/app/examples/dialog/page.tsx +205 -0
  69. package/templates/ui/antd/src/app/examples/form/page.tsx +160 -0
  70. package/templates/ui/antd/src/app/examples/layout.tsx +125 -0
  71. package/templates/ui/antd/src/app/examples/page.tsx +64 -0
  72. package/templates/ui/antd/src/app/examples/table/page.tsx +118 -0
  73. package/templates/ui/antd/src/app/page.tsx +283 -0
  74. package/templates/ui/antd/src/components/common/DynamicTable/dynamic-table.component.tsx +79 -0
  75. package/templates/ui/antd/src/components/common/button/action-button.component.tsx +63 -0
  76. package/templates/ui/antd/src/components/common/dialog/dialog-wrapper.component.tsx +63 -0
  77. package/templates/ui/antd/src/components/common/fields/assets/components/check-field.component.tsx +55 -0
  78. package/templates/ui/antd/src/components/common/fields/assets/components/date-picker-field.component.tsx +80 -0
  79. package/templates/ui/antd/src/components/common/fields/assets/components/limit-field.component.tsx +26 -0
  80. package/templates/ui/antd/src/components/common/fields/assets/components/multi-check-field.component.tsx +56 -0
  81. package/templates/ui/antd/src/components/common/fields/assets/components/number-field.component.tsx +100 -0
  82. package/templates/ui/antd/src/components/common/fields/assets/components/otp-field.component.tsx +63 -0
  83. package/templates/ui/antd/src/components/common/fields/assets/components/password-field.component.tsx +106 -0
  84. package/templates/ui/antd/src/components/common/fields/assets/components/phone-number-field.component.tsx +78 -0
  85. package/templates/ui/antd/src/components/common/fields/assets/components/radio-field.component.tsx +55 -0
  86. package/templates/ui/antd/src/components/common/fields/assets/components/range-date-picker.component.tsx +66 -0
  87. package/templates/ui/antd/src/components/common/fields/assets/components/search-field.component.tsx +24 -0
  88. package/templates/ui/antd/src/components/common/fields/assets/components/select-field.component.tsx +82 -0
  89. package/templates/ui/antd/src/components/common/fields/assets/components/single-check-field.component.tsx +50 -0
  90. package/templates/ui/antd/src/components/common/fields/assets/components/single-select-field.component.tsx +86 -0
  91. package/templates/ui/antd/src/components/common/fields/assets/components/string-number-field.component.tsx +80 -0
  92. package/templates/ui/antd/src/components/common/fields/assets/components/switch-field.component.tsx +62 -0
  93. package/templates/ui/antd/src/components/common/fields/assets/components/text-area-field.component.tsx +85 -0
  94. package/templates/ui/antd/src/components/common/fields/assets/components/text-field.component.tsx +88 -0
  95. package/templates/ui/antd/src/components/common/fields/assets/interface/input-props.type.ts +233 -0
  96. package/templates/ui/antd/src/components/common/fields/cusInputField.component.tsx +40 -0
  97. package/templates/ui/antd/src/components/common/pagination/pagination.component.tsx +27 -0
  98. package/templates/ui/antd/src/components/ui/avatar.component.tsx +8 -0
  99. package/templates/ui/antd/src/components/ui/badge.component.tsx +8 -0
  100. package/templates/ui/antd/src/components/ui/button.component.tsx +8 -0
  101. package/templates/ui/antd/src/components/ui/card.component.tsx +8 -0
  102. package/templates/ui/antd/src/components/ui/checkbox.component.tsx +8 -0
  103. package/templates/ui/antd/src/components/ui/dialog.component.tsx +9 -0
  104. package/templates/ui/antd/src/components/ui/dropdown-menu.component.tsx +10 -0
  105. package/templates/ui/antd/src/components/ui/form.component.tsx +12 -0
  106. package/templates/ui/antd/src/components/ui/input.component.tsx +13 -0
  107. package/templates/ui/antd/src/components/ui/label.component.tsx +18 -0
  108. package/templates/ui/antd/src/components/ui/popover.component.tsx +8 -0
  109. package/templates/ui/antd/src/components/ui/progress.component.tsx +8 -0
  110. package/templates/ui/antd/src/components/ui/radio-group.component.tsx +10 -0
  111. package/templates/ui/antd/src/components/ui/scroll-area.component.tsx +25 -0
  112. package/templates/ui/antd/src/components/ui/select.component.tsx +8 -0
  113. package/templates/ui/antd/src/components/ui/separator.component.tsx +8 -0
  114. package/templates/ui/antd/src/components/ui/sheet.component.tsx +8 -0
  115. package/templates/ui/antd/src/components/ui/switch.component.tsx +8 -0
  116. package/templates/ui/antd/src/components/ui/table.component.tsx +8 -0
  117. package/templates/ui/antd/src/components/ui/tabs.component.tsx +8 -0
  118. package/templates/ui/antd/src/components/ui/textarea.component.tsx +9 -0
  119. package/templates/ui/antd/src/components/ui/tooltip.component.tsx +8 -0
  120. package/templates/ui/antd/src/lib/theme.util.ts +40 -0
  121. package/templates/ui/antd/src/providers/antd.provider.tsx +13 -0
  122. package/templates/ui/mui/src/app/examples/layout.tsx +113 -0
  123. package/templates/ui/mui/src/app/examples/page.tsx +716 -0
  124. package/templates/ui/mui/src/app/page.tsx +298 -0
  125. package/templates/ui/mui/src/components/common/DynamicTable/dynamic-table.component.tsx +131 -0
  126. package/templates/ui/mui/src/components/common/button/action-button.component.tsx +57 -0
  127. package/templates/ui/mui/src/components/common/dialog/dialog-wrapper.component.tsx +55 -0
  128. package/templates/ui/mui/src/components/common/fields/assets/components/check-field.component.tsx +51 -0
  129. package/templates/ui/mui/src/components/common/fields/assets/components/date-picker-field.component.tsx +50 -0
  130. package/templates/ui/mui/src/components/common/fields/assets/components/multi-check-field.component.tsx +14 -0
  131. package/templates/ui/mui/src/components/common/fields/assets/components/number-field.component.tsx +59 -0
  132. package/templates/ui/mui/src/components/common/fields/assets/components/password-field.component.tsx +87 -0
  133. package/templates/ui/mui/src/components/common/fields/assets/components/phone-number-field.component.tsx +48 -0
  134. package/templates/ui/mui/src/components/common/fields/assets/components/radio-field.component.tsx +37 -0
  135. package/templates/ui/mui/src/components/common/fields/assets/components/search-field.component.tsx +41 -0
  136. package/templates/ui/mui/src/components/common/fields/assets/components/select-field.component.tsx +77 -0
  137. package/templates/ui/mui/src/components/common/fields/assets/components/single-check-field.component.tsx +39 -0
  138. package/templates/ui/mui/src/components/common/fields/assets/components/single-select-field.component.tsx +56 -0
  139. package/templates/ui/mui/src/components/common/fields/assets/components/string-number-field.component.tsx +52 -0
  140. package/templates/ui/mui/src/components/common/fields/assets/components/switch-field.component.tsx +35 -0
  141. package/templates/ui/mui/src/components/common/fields/assets/components/text-area-field.component.tsx +46 -0
  142. package/templates/ui/mui/src/components/common/fields/assets/components/text-field.component.tsx +51 -0
  143. package/templates/ui/mui/src/components/common/fields/assets/interface/input-props.type.ts +193 -0
  144. package/templates/ui/mui/src/components/common/fields/cusInputField.component.tsx +34 -0
  145. package/templates/ui/mui/src/components/common/pagination/pagination.component.tsx +59 -0
  146. package/templates/ui/mui/src/components/ui/avatar.component.tsx +19 -0
  147. package/templates/ui/mui/src/components/ui/badge.component.tsx +18 -0
  148. package/templates/ui/mui/src/components/ui/button.component.tsx +22 -0
  149. package/templates/ui/mui/src/components/ui/card.component.tsx +39 -0
  150. package/templates/ui/mui/src/components/ui/checkbox.component.tsx +21 -0
  151. package/templates/ui/mui/src/components/ui/dialog.component.tsx +38 -0
  152. package/templates/ui/mui/src/components/ui/dropdown-menu.component.tsx +43 -0
  153. package/templates/ui/mui/src/components/ui/form.component.tsx +98 -0
  154. package/templates/ui/mui/src/components/ui/input.component.tsx +15 -0
  155. package/templates/ui/mui/src/components/ui/label.component.tsx +15 -0
  156. package/templates/ui/mui/src/components/ui/popover.component.tsx +20 -0
  157. package/templates/ui/mui/src/components/ui/progress.component.tsx +19 -0
  158. package/templates/ui/mui/src/components/ui/radio-group.component.tsx +25 -0
  159. package/templates/ui/mui/src/components/ui/scroll-area.component.tsx +27 -0
  160. package/templates/ui/mui/src/components/ui/select.component.tsx +26 -0
  161. package/templates/ui/mui/src/components/ui/separator.component.tsx +11 -0
  162. package/templates/ui/mui/src/components/ui/sheet.component.tsx +44 -0
  163. package/templates/ui/mui/src/components/ui/switch.component.tsx +23 -0
  164. package/templates/ui/mui/src/components/ui/table.component.tsx +34 -0
  165. package/templates/ui/mui/src/components/ui/tabs.component.tsx +38 -0
  166. package/templates/ui/mui/src/components/ui/textarea.component.tsx +18 -0
  167. package/templates/ui/mui/src/components/ui/tooltip.component.tsx +24 -0
  168. package/templates/ui/mui/src/lib/theme.util.ts +73 -0
  169. package/templates/ui/mui/src/providers/mui.provider.tsx +13 -0
  170. package/templates/ui/shadcn/COMPONENT_GUIDE.md +306 -0
  171. package/templates/ui/shadcn/src/app/examples/dialog/page.tsx +122 -0
  172. package/templates/ui/shadcn/src/app/examples/form/page.tsx +107 -0
  173. package/templates/ui/shadcn/src/app/examples/layout.tsx +24 -0
  174. package/templates/ui/shadcn/src/app/examples/page.tsx +30 -0
  175. package/templates/ui/shadcn/src/app/examples/table/page.tsx +77 -0
  176. package/templates/ui/shadcn/src/app/page.tsx +20 -0
  177. package/templates/ui/shadcn/src/components/common/DynamicTable/dynamic-table.component.tsx +136 -0
  178. package/templates/ui/shadcn/src/components/common/button/action-button.component.tsx +68 -0
  179. package/templates/ui/shadcn/src/components/common/dialog/dialog-wrapper.component.tsx +58 -0
  180. package/templates/ui/shadcn/src/components/common/fields/assets/components/check-field.component.tsx +52 -0
  181. package/templates/ui/shadcn/src/components/common/fields/assets/components/date-picker-field.component.tsx +62 -0
  182. package/templates/ui/shadcn/src/components/common/fields/assets/components/dynamic-file-upload-field.component.tsx +152 -0
  183. package/templates/ui/shadcn/src/components/common/fields/assets/components/limit-field.component.tsx +73 -0
  184. package/templates/ui/shadcn/src/components/common/fields/assets/components/multi-check-field.component.tsx +46 -0
  185. package/templates/ui/shadcn/src/components/common/fields/assets/components/number-field.component.tsx +124 -0
  186. package/templates/ui/shadcn/src/components/common/fields/assets/components/otp-field.component.tsx +61 -0
  187. package/templates/ui/shadcn/src/components/common/fields/assets/components/password-field.component.tsx +110 -0
  188. package/templates/ui/shadcn/src/components/common/fields/assets/components/phone-number-field.component.tsx +90 -0
  189. package/templates/ui/shadcn/src/components/common/fields/assets/components/radio-field.component.tsx +41 -0
  190. package/templates/ui/shadcn/src/components/common/fields/assets/components/range-date-picker.component.tsx +71 -0
  191. package/templates/ui/shadcn/src/components/common/fields/assets/components/rich-text-editor.component.tsx +91 -0
  192. package/templates/ui/shadcn/src/components/common/fields/assets/components/search-field.component.tsx +34 -0
  193. package/templates/ui/shadcn/src/components/common/fields/assets/components/select-field.component.tsx +231 -0
  194. package/templates/ui/shadcn/src/components/common/fields/assets/components/single-check-field.component.tsx +42 -0
  195. package/templates/ui/shadcn/src/components/common/fields/assets/components/single-select-field.component.tsx +82 -0
  196. package/templates/ui/shadcn/src/components/common/fields/assets/components/string-number-field.component.tsx +68 -0
  197. package/templates/ui/shadcn/src/components/common/fields/assets/components/switch-field.component.tsx +61 -0
  198. package/templates/ui/shadcn/src/components/common/fields/assets/components/text-area-field.component.tsx +62 -0
  199. package/templates/ui/shadcn/src/components/common/fields/assets/components/text-area-with-file.component.tsx +142 -0
  200. package/templates/ui/shadcn/src/components/common/fields/assets/components/text-field.component.tsx +80 -0
  201. package/templates/ui/shadcn/src/components/common/fields/assets/components/tiny-editor.component.tsx +51 -0
  202. package/templates/ui/shadcn/src/components/common/fields/assets/components/upload-profile-picture.component.tsx +103 -0
  203. package/templates/ui/shadcn/src/components/common/fields/assets/components/upload-video-file.component.tsx +86 -0
  204. package/templates/ui/shadcn/src/components/common/fields/assets/interface/input-props.type.ts +198 -0
  205. package/templates/ui/shadcn/src/components/common/fields/cusInputField.component.tsx +52 -0
  206. package/templates/ui/shadcn/src/components/common/pagination/pagination.component.tsx +68 -0
  207. package/templates/ui/shadcn/src/components/ui/avatar.component.tsx +37 -0
  208. package/templates/ui/shadcn/src/components/ui/badge.component.tsx +28 -0
  209. package/templates/ui/shadcn/src/components/ui/button.component.tsx +52 -0
  210. package/templates/ui/shadcn/src/components/ui/card.component.tsx +46 -0
  211. package/templates/ui/shadcn/src/components/ui/checkbox.component.tsx +25 -0
  212. package/templates/ui/shadcn/src/components/ui/dialog.component.tsx +98 -0
  213. package/templates/ui/shadcn/src/components/ui/dropdown-menu.component.tsx +163 -0
  214. package/templates/ui/shadcn/src/components/ui/form.component.tsx +110 -0
  215. package/templates/ui/shadcn/src/components/ui/input-otp.component.tsx +64 -0
  216. package/templates/ui/shadcn/src/components/ui/input.component.tsx +23 -0
  217. package/templates/ui/shadcn/src/components/ui/label.component.tsx +23 -0
  218. package/templates/ui/shadcn/src/components/ui/popover.component.tsx +27 -0
  219. package/templates/ui/shadcn/src/components/ui/progress.component.tsx +22 -0
  220. package/templates/ui/shadcn/src/components/ui/radio-group.component.tsx +33 -0
  221. package/templates/ui/shadcn/src/components/ui/scroll-area.component.tsx +37 -0
  222. package/templates/ui/shadcn/src/components/ui/select.component.tsx +139 -0
  223. package/templates/ui/shadcn/src/components/ui/separator.component.tsx +23 -0
  224. package/templates/ui/shadcn/src/components/ui/sheet.component.tsx +89 -0
  225. package/templates/ui/shadcn/src/components/ui/switch.component.tsx +26 -0
  226. package/templates/ui/shadcn/src/components/ui/table.component.tsx +71 -0
  227. package/templates/ui/shadcn/src/components/ui/tabs.component.tsx +52 -0
  228. package/templates/ui/shadcn/src/components/ui/textarea.component.tsx +20 -0
  229. package/templates/ui/shadcn/src/components/ui/tooltip.component.tsx +25 -0
@@ -0,0 +1,298 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import Link from 'next/link';
5
+ import Box from '@mui/material/Box';
6
+ import Typography from '@mui/material/Typography';
7
+ import Container from '@mui/material/Container';
8
+ import Button from '@mui/material/Button';
9
+ import Chip from '@mui/material/Chip';
10
+ import Stack from '@mui/material/Stack';
11
+ import Grid from '@mui/material/Grid';
12
+ import Card from '@mui/material/Card';
13
+ import CardContent from '@mui/material/CardContent';
14
+ import IconButton from '@mui/material/IconButton';
15
+ import Tooltip from '@mui/material/Tooltip';
16
+ import Divider from '@mui/material/Divider';
17
+ import Drawer from '@mui/material/Drawer';
18
+ import List from '@mui/material/List';
19
+ import ListItem from '@mui/material/ListItem';
20
+ import ListItemButton from '@mui/material/ListItemButton';
21
+ import ListItemText from '@mui/material/ListItemText';
22
+
23
+ import MenuIcon from '@mui/icons-material/Menu';
24
+ import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
25
+ import CodeIcon from '@mui/icons-material/Code';
26
+ import DashboardIcon from '@mui/icons-material/Dashboard';
27
+ import ViewKanbanIcon from '@mui/icons-material/ViewKanban';
28
+ import TableChartIcon from '@mui/icons-material/TableChart';
29
+ import VerifiedIcon from '@mui/icons-material/Verified';
30
+ import GitHubIcon from '@mui/icons-material/GitHub';
31
+ import CloseIcon from '@mui/icons-material/Close';
32
+
33
+ const navLinks = [
34
+ { label: 'Home', href: '/' },
35
+ { label: 'Components', href: '/examples' },
36
+ ];
37
+
38
+ const features = [
39
+ {
40
+ icon: <DashboardIcon sx={{ fontSize: 40 }} />,
41
+ title: '21 UI Primitives',
42
+ desc: 'Button, Card, Dialog, Table, Tabs, Avatar, Select, Switch, Tooltip, and more — all pre-styled with MUI.',
43
+ color: '#2563eb',
44
+ },
45
+ {
46
+ icon: <ViewKanbanIcon sx={{ fontSize: 40 }} />,
47
+ title: 'CustomField System',
48
+ desc: '15 field types with dual-mode: react-hook-form integration or standalone value/setValue.',
49
+ color: '#7c3aed',
50
+ },
51
+ {
52
+ icon: <TableChartIcon sx={{ fontSize: 40 }} />,
53
+ title: 'DynamicTable',
54
+ desc: 'Config-driven table with loading states, empty states, checkbox selection, and pagination.',
55
+ color: '#059669',
56
+ },
57
+ {
58
+ icon: <VerifiedIcon sx={{ fontSize: 40 }} />,
59
+ title: 'Form Validation',
60
+ desc: 'React Hook Form + Zod schema validation with live error messages and form state tracking.',
61
+ color: '#dc2626',
62
+ },
63
+ ];
64
+
65
+ const techStack = [
66
+ 'Material UI', 'React Hook Form', 'Zod', 'Next.js 15', 'TypeScript',
67
+ '@emotion/react', '@emotion/styled', '@mui/icons-material',
68
+ ];
69
+
70
+ export default function Home() {
71
+ const [mobileOpen, setMobileOpen] = useState(false);
72
+
73
+ return (
74
+ <Box sx={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', bgcolor: 'background.default' }}>
75
+
76
+ {/* Navbar */}
77
+ <Box sx={{
78
+ position: 'sticky', top: 0, zIndex: 100,
79
+ bgcolor: 'rgba(255,255,255,0.85)', backdropFilter: 'blur(16px)',
80
+ borderBottom: 1, borderColor: 'divider',
81
+ }}>
82
+ <Container maxWidth="xl" sx={{ display: 'flex', alignItems: 'center', height: 64, justifyContent: 'space-between' }}>
83
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
84
+ <Box sx={{ width: 32, height: 32, borderRadius: 1, bgcolor: 'primary.main', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
85
+ <Typography variant="body2" fontWeight={800} color="white">F</Typography>
86
+ </Box>
87
+ <Typography variant="subtitle1" fontWeight={700} sx={{ letterSpacing: '-0.02em' }}>Nexstruct</Typography>
88
+ </Box>
89
+
90
+ <Box sx={{ display: { xs: 'none', md: 'flex' }, alignItems: 'center', gap: 1 }}>
91
+ {navLinks.map((link) => (
92
+ <Link key={link.href} href={link.href} passHref legacyBehavior>
93
+ <Button
94
+ component="a"
95
+ variant={link.href === '/' ? 'contained' : 'text'}
96
+ size="small"
97
+ sx={{ fontWeight: 500 }}
98
+ >
99
+ {link.label}
100
+ </Button>
101
+ </Link>
102
+ ))}
103
+ <Box sx={{ width: 1, height: 24, mx: 1 }} />
104
+ <Tooltip title="View on GitHub">
105
+ <IconButton size="small" href="https://github.com" target="_blank">
106
+ <GitHubIcon fontSize="small" />
107
+ </IconButton>
108
+ </Tooltip>
109
+ </Box>
110
+
111
+ <IconButton sx={{ display: { xs: 'flex', md: 'none' } }} onClick={() => setMobileOpen(true)}>
112
+ <MenuIcon />
113
+ </IconButton>
114
+ </Container>
115
+ </Box>
116
+
117
+ {/* Mobile Drawer */}
118
+ <Drawer anchor="right" open={mobileOpen} onClose={() => setMobileOpen(false)}>
119
+ <Box sx={{ width: 280, p: 2 }}>
120
+ <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
121
+ <Typography variant="subtitle1" fontWeight={700}>Menu</Typography>
122
+ <IconButton onClick={() => setMobileOpen(false)}><CloseIcon /></IconButton>
123
+ </Box>
124
+ <List>
125
+ {navLinks.map((link) => (
126
+ <ListItem key={link.href} disablePadding>
127
+ <Link href={link.href} passHref legacyBehavior>
128
+ <ListItemButton component="a" onClick={() => setMobileOpen(false)}>
129
+ <ListItemText primary={link.label} />
130
+ </ListItemButton>
131
+ </Link>
132
+ </ListItem>
133
+ ))}
134
+ </List>
135
+ </Box>
136
+ </Drawer>
137
+
138
+ {/* Hero */}
139
+ <Box sx={{
140
+ background: 'linear-gradient(135deg, #1e3a5f 0%, #2563eb 50%, #7c3aed 100%)',
141
+ color: 'white', py: { xs: 8, md: 14 },
142
+ position: 'relative', overflow: 'hidden',
143
+ }}>
144
+ <Container maxWidth="md" sx={{ textAlign: 'center', position: 'relative', zIndex: 1 }}>
145
+ <Stack direction="row" spacing={1} justifyContent="center" sx={{ mb: 3 }}>
146
+ <Chip label="Material UI" size="small" sx={{ color: 'white', borderColor: 'rgba(255,255,255,0.4)', fontWeight: 600, backdropFilter: 'blur(8px)', bgcolor: 'rgba(255,255,255,0.1)' }} />
147
+ <Chip label="TypeScript" size="small" sx={{ color: 'white', borderColor: 'rgba(255,255,255,0.4)', fontWeight: 600, backdropFilter: 'blur(8px)', bgcolor: 'rgba(255,255,255,0.1)' }} />
148
+ <Chip label="Next.js 15" size="small" sx={{ color: 'white', borderColor: 'rgba(255,255,255,0.4)', fontWeight: 600, backdropFilter: 'blur(8px)', bgcolor: 'rgba(255,255,255,0.1)' }} />
149
+ </Stack>
150
+ <Typography variant="h2" fontWeight={800} sx={{ fontSize: { xs: '2rem', md: '3.5rem' }, lineHeight: 1.15, letterSpacing: '-0.03em' }}>
151
+ Build Beautiful Apps with{' '}
152
+ <Box component="span" sx={{ background: 'linear-gradient(135deg, #93c5fd, #c4b5fd)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>
153
+ MUI Components
154
+ </Box>
155
+ </Typography>
156
+ <Typography variant="h6" sx={{ mt: 2, opacity: 0.9, fontWeight: 400, maxWidth: 600, mx: 'auto', lineHeight: 1.6 }}>
157
+ A production-ready component system built on Material UI — with form validation, dynamic tables, dialogs, and 21+ UI primitives.
158
+ </Typography>
159
+ <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} justifyContent="center" sx={{ mt: 5 }}>
160
+ <Link href="/examples" passHref legacyBehavior>
161
+ <Button
162
+ component="a"
163
+ variant="contained"
164
+ size="large"
165
+ endIcon={<ArrowForwardIcon />}
166
+ sx={{ bgcolor: 'white', color: '#2563eb', '&:hover': { bgcolor: 'rgba(255,255,255,0.9)' }, fontWeight: 600, px: 4, py: 1.5 }}
167
+ >
168
+ Explore Components
169
+ </Button>
170
+ </Link>
171
+ <Button
172
+ variant="outlined"
173
+ size="large"
174
+ startIcon={<CodeIcon />}
175
+ href="#features"
176
+ sx={{ color: 'white', borderColor: 'rgba(255,255,255,0.4)', '&:hover': { borderColor: 'white', bgcolor: 'rgba(255,255,255,0.1)' }, fontWeight: 600, px: 4, py: 1.5 }}
177
+ >
178
+ Learn More
179
+ </Button>
180
+ </Stack>
181
+ </Container>
182
+
183
+ {/* Decorative blobs */}
184
+ <Box sx={{ position: 'absolute', top: '-20%', right: '-10%', width: 400, height: 400, borderRadius: '50%', bgcolor: 'rgba(255,255,255,0.03)', pointerEvents: 'none' }} />
185
+ <Box sx={{ position: 'absolute', bottom: '-30%', left: '-5%', width: 500, height: 500, borderRadius: '50%', bgcolor: 'rgba(255,255,255,0.02)', pointerEvents: 'none' }} />
186
+ </Box>
187
+
188
+ {/* Feature Cards */}
189
+ <Box id="features" sx={{ py: { xs: 6, md: 10 }, scrollMarginTop: 80 }}>
190
+ <Container maxWidth="lg">
191
+ <Box sx={{ textAlign: 'center', mb: 6 }}>
192
+ <Typography variant="h4" fontWeight={800} gutterBottom>What&apos;s Included</Typography>
193
+ <Typography variant="body1" color="text.secondary" sx={{ maxWidth: 600, mx: 'auto' }}>
194
+ A complete component ecosystem — every piece is pre-built, pre-styled, and ready for production.
195
+ </Typography>
196
+ <Divider sx={{ mt: 2, maxWidth: 80, mx: 'auto', borderWidth: 2, borderColor: 'primary.main', borderRadius: 2 }} />
197
+ </Box>
198
+ <Grid container spacing={3}>
199
+ {features.map((f) => (
200
+ <Grid size={{ xs: 12, sm: 6 }} key={f.title}>
201
+ <Card
202
+ variant="outlined"
203
+ sx={{
204
+ height: '100%',
205
+ transition: 'all 0.25s ease',
206
+ cursor: 'default',
207
+ '&:hover': {
208
+ boxShadow: 6,
209
+ borderColor: f.color,
210
+ transform: 'translateY(-4px)',
211
+ },
212
+ }}
213
+ >
214
+ <CardContent sx={{ p: 3 }}>
215
+ <Box sx={{ color: f.color, mb: 2 }}>{f.icon}</Box>
216
+ <Typography variant="h6" fontWeight={700} gutterBottom>{f.title}</Typography>
217
+ <Typography variant="body2" color="text.secondary" sx={{ lineHeight: 1.7 }}>{f.desc}</Typography>
218
+ </CardContent>
219
+ </Card>
220
+ </Grid>
221
+ ))}
222
+ </Grid>
223
+ </Container>
224
+ </Box>
225
+
226
+ {/* Tech Stack */}
227
+ <Box sx={{ py: { xs: 6, md: 8 }, bgcolor: 'grey.50' }}>
228
+ <Container maxWidth="md" sx={{ textAlign: 'center' }}>
229
+ <Typography variant="h5" fontWeight={700} gutterBottom>Powered By</Typography>
230
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 4 }}>
231
+ Built on battle-tested libraries you already trust.
232
+ </Typography>
233
+ <Stack direction="row" spacing={1} justifyContent="center" flexWrap="wrap" useFlexGap>
234
+ {techStack.map((t) => (
235
+ <Chip key={t} label={t} variant="outlined" sx={{ fontWeight: 500, mb: 1 }} />
236
+ ))}
237
+ </Stack>
238
+ </Container>
239
+ </Box>
240
+
241
+ {/* CTA */}
242
+ <Box sx={{ py: { xs: 6, md: 10 }, textAlign: 'center' }}>
243
+ <Container maxWidth="sm">
244
+ <Typography variant="h4" fontWeight={800} gutterBottom>Ready to Explore?</Typography>
245
+ <Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}>
246
+ See every component in action — buttons, forms, tables, dialogs, and more.
247
+ </Typography>
248
+ <Link href="/examples" passHref legacyBehavior>
249
+ <Button component="a" variant="contained" size="large" endIcon={<ArrowForwardIcon />} sx={{ fontWeight: 600, px: 5, py: 1.5 }}>
250
+ View Component Showcase
251
+ </Button>
252
+ </Link>
253
+ </Container>
254
+ </Box>
255
+
256
+ {/* Footer */}
257
+ <Box sx={{ mt: 'auto', bgcolor: 'grey.900', color: 'white', py: 5 }}>
258
+ <Container maxWidth="lg">
259
+ <Grid container spacing={3} sx={{ mb: 4 }}>
260
+ <Grid size={{ xs: 12, md: 6 }}>
261
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
262
+ <Box sx={{ width: 28, height: 28, borderRadius: 1, bgcolor: 'primary.main', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
263
+ <Typography variant="caption" fontWeight={800} color="white">F</Typography>
264
+ </Box>
265
+ <Typography variant="subtitle2" fontWeight={700}>Nexstruct</Typography>
266
+ </Box>
267
+ <Typography variant="body2" sx={{ opacity: 0.6, maxWidth: 360 }}>
268
+ Scaffolding production-ready Next.js applications with composable, framework-specific component systems.
269
+ </Typography>
270
+ </Grid>
271
+ <Grid size={{ xs: 6, md: 3 }}>
272
+ <Typography variant="caption" fontWeight={700} sx={{ opacity: 0.5, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Navigate</Typography>
273
+ <Stack spacing={0.5} sx={{ mt: 1 }}>
274
+ {['Home', 'Components', 'GitHub'].map((l) => (
275
+ <Link key={l} href={l === 'Home' ? '/' : l === 'Components' ? '/examples' : '#'} style={{ textDecoration: 'none' }}>
276
+ <Typography variant="body2" sx={{ opacity: 0.7, '&:hover': { opacity: 1 } }}>{l}</Typography>
277
+ </Link>
278
+ ))}
279
+ </Stack>
280
+ </Grid>
281
+ <Grid size={{ xs: 6, md: 3 }}>
282
+ <Typography variant="caption" fontWeight={700} sx={{ opacity: 0.5, textTransform: 'uppercase', letterSpacing: '0.05em' }}>Tech</Typography>
283
+ <Stack spacing={0.5} sx={{ mt: 1 }}>
284
+ {['Material UI', 'Next.js 15', 'TypeScript', 'React Hook Form'].map((t) => (
285
+ <Typography key={t} variant="body2" sx={{ opacity: 0.7 }}>{t}</Typography>
286
+ ))}
287
+ </Stack>
288
+ </Grid>
289
+ </Grid>
290
+ <Divider sx={{ borderColor: 'rgba(255,255,255,0.1)', mb: 3 }} />
291
+ <Typography variant="caption" sx={{ opacity: 0.4, display: 'block', textAlign: 'center' }}>
292
+ Scaffolded with Nexstruct — {new Date().getFullYear()}
293
+ </Typography>
294
+ </Container>
295
+ </Box>
296
+ </Box>
297
+ );
298
+ }
@@ -0,0 +1,131 @@
1
+ 'use client';
2
+
3
+ import Table from '@mui/material/Table';
4
+ import TableBody from '@mui/material/TableBody';
5
+ import TableCell from '@mui/material/TableCell';
6
+ import TableContainer from '@mui/material/TableContainer';
7
+ import TableHead from '@mui/material/TableHead';
8
+ import TableRow from '@mui/material/TableRow';
9
+ import Paper from '@mui/material/Paper';
10
+ import Checkbox from '@mui/material/Checkbox';
11
+ import CircularProgress from '@mui/material/CircularProgress';
12
+ import Box from '@mui/material/Box';
13
+ import Typography from '@mui/material/Typography';
14
+
15
+ export type TableColumn = {
16
+ key: string;
17
+ header: string;
18
+ className?: string;
19
+ render?: (item: any, index: number) => React.ReactNode;
20
+ };
21
+
22
+ export type TableConfig = {
23
+ columns: TableColumn[];
24
+ emptyMessage?: string;
25
+ showPagination?: boolean;
26
+ rowClassName?: (item: any) => string;
27
+ renderExpandableRow?: (item: any, index: number) => React.ReactNode;
28
+ };
29
+
30
+ interface Pagination {
31
+ page: number;
32
+ total: number;
33
+ perPage?: number;
34
+ totalPages: number;
35
+ }
36
+
37
+ interface DynamicTableProps {
38
+ isLoading: boolean;
39
+ pagination?: Pagination;
40
+ currentPage: number;
41
+ setCurrentPage: (page: number) => void;
42
+ config: TableConfig;
43
+ data: any;
44
+ isCheckBox?: boolean;
45
+ selectedIds?: string[];
46
+ setSelectedIds?: (ids: string[]) => void;
47
+ setSelectObject?: (data: any[]) => void;
48
+ renderExpandedRow?: (item: any, index: number) => React.ReactNode;
49
+ }
50
+
51
+ export function DynamicTable({
52
+ data, isLoading, config, isCheckBox = false,
53
+ selectedIds = [], setSelectedIds = () => {}, setSelectObject = () => {},
54
+ }: DynamicTableProps) {
55
+ const isEmpty = !isLoading && (!data || data.length === 0);
56
+
57
+ const isRowSelected = (id: string) => selectedIds?.includes(id);
58
+
59
+ const toggleRowSelection = (id: string) => {
60
+ const newSelectedIds = isRowSelected(id)
61
+ ? selectedIds.filter((item: string) => item !== id)
62
+ : [...selectedIds, id];
63
+ setSelectedIds(newSelectedIds);
64
+ setSelectObject(data.filter((item: any) => newSelectedIds.includes(item.id)));
65
+ };
66
+
67
+ const toggleSelectAll = () => {
68
+ const allSelected = data?.every((item: any) => isRowSelected(item.id));
69
+ const newSelectedIds = allSelected ? [] : data.map((item: any) => item.id);
70
+ setSelectedIds(newSelectedIds);
71
+ setSelectObject(allSelected ? [] : data);
72
+ };
73
+
74
+ return (
75
+ <TableContainer component={Paper} variant="outlined" sx={{ borderRadius: 2 }}>
76
+ <Table>
77
+ <TableHead>
78
+ <TableRow>
79
+ {isCheckBox && (
80
+ <TableCell padding="checkbox">
81
+ <Checkbox
82
+ checked={data?.length > 0 && data?.every((item: any) => isRowSelected(item.id))}
83
+ indeterminate={data?.some((item: any) => isRowSelected(item.id)) && !data?.every((item: any) => isRowSelected(item.id))}
84
+ onChange={toggleSelectAll}
85
+ />
86
+ </TableCell>
87
+ )}
88
+ {config.columns.map((column) => (
89
+ <TableCell key={column.key} className={column.className}>
90
+ {column.header}
91
+ </TableCell>
92
+ ))}
93
+ </TableRow>
94
+ </TableHead>
95
+ <TableBody>
96
+ {isLoading ? (
97
+ <TableRow>
98
+ <TableCell colSpan={config.columns.length + (isCheckBox ? 1 : 0)} align="center" sx={{ height: 256 }}>
99
+ <CircularProgress />
100
+ </TableCell>
101
+ </TableRow>
102
+ ) : isEmpty ? (
103
+ <TableRow>
104
+ <TableCell colSpan={config.columns.length + (isCheckBox ? 1 : 0)} align="center" sx={{ height: 256 }}>
105
+ <Typography color="text.secondary">{config.emptyMessage || 'No data available'}</Typography>
106
+ </TableCell>
107
+ </TableRow>
108
+ ) : (
109
+ data?.map((row: any, rowIndex: number) => (
110
+ <TableRow key={rowIndex} hover className={config.rowClassName?.(row)}>
111
+ {isCheckBox && (
112
+ <TableCell padding="checkbox">
113
+ <Checkbox
114
+ checked={isRowSelected(row.id)}
115
+ onChange={() => toggleRowSelection(row.id)}
116
+ />
117
+ </TableCell>
118
+ )}
119
+ {config.columns.map((col, colIndex) => (
120
+ <TableCell key={colIndex} className={col.className}>
121
+ {col.render ? col.render(row, rowIndex) : row[col.key]}
122
+ </TableCell>
123
+ ))}
124
+ </TableRow>
125
+ ))
126
+ )}
127
+ </TableBody>
128
+ </Table>
129
+ </TableContainer>
130
+ );
131
+ }
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+
3
+ import { Button } from '@/components/ui/button.component';
4
+ import Tooltip from '@mui/material/Tooltip';
5
+ import CircularProgress from '@mui/material/CircularProgress';
6
+ import { forwardRef } from 'react';
7
+
8
+ interface ActionButtonProps {
9
+ type?: 'submit' | 'button' | 'reset';
10
+ btnSize?: 'small' | 'medium' | 'large';
11
+ btnStyle?: React.CSSProperties;
12
+ variant?: 'text' | 'outlined' | 'contained';
13
+ color?: 'inherit' | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning';
14
+ tooltipContent?: string;
15
+ buttonContent?: React.ReactNode;
16
+ icon?: React.ReactNode;
17
+ lastIcon?: React.ReactNode;
18
+ isPending?: boolean;
19
+ handleOpen?: (e?: React.MouseEvent<HTMLButtonElement>) => void;
20
+ side?: 'top' | 'right' | 'bottom' | 'left';
21
+ loadingContent?: React.ReactNode;
22
+ disabled?: boolean;
23
+ }
24
+
25
+ const ActionButton = forwardRef<HTMLButtonElement, ActionButtonProps>(
26
+ ({ type = 'button', btnSize = 'medium', btnStyle, variant = 'contained', color = 'primary',
27
+ tooltipContent, buttonContent, icon, lastIcon, isPending = false, handleOpen,
28
+ side = 'top', loadingContent, disabled = false }, ref) => {
29
+ const buttonEl = (
30
+ <Button
31
+ ref={ref}
32
+ type={type}
33
+ size={btnSize}
34
+ onClick={handleOpen}
35
+ variant={variant}
36
+ color={color}
37
+ disabled={isPending || disabled}
38
+ startIcon={!isPending && icon ? icon : undefined}
39
+ endIcon={!isPending && lastIcon ? lastIcon : undefined}
40
+ isLoading={isPending}
41
+ sx={{ textTransform: 'none', ...btnStyle }}
42
+ >
43
+ {isPending ? (loadingContent ?? buttonContent) : buttonContent}
44
+ </Button>
45
+ );
46
+
47
+ if (!tooltipContent) return buttonEl;
48
+ return (
49
+ <Tooltip title={tooltipContent} placement={side}>
50
+ <span>{buttonEl}</span>
51
+ </Tooltip>
52
+ );
53
+ }
54
+ );
55
+ ActionButton.displayName = 'ActionButton';
56
+
57
+ export { ActionButton };
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+
3
+ import Dialog from '@mui/material/Dialog';
4
+ import DialogTitle from '@mui/material/DialogTitle';
5
+ import DialogContent from '@mui/material/DialogContent';
6
+ import DialogActions from '@mui/material/DialogActions';
7
+ import DialogContentText from '@mui/material/DialogContentText';
8
+ import IconButton from '@mui/material/IconButton';
9
+ import CloseIcon from '@mui/icons-material/Close';
10
+ import type { ReactNode } from 'react';
11
+
12
+ interface DialogWrapperProps {
13
+ open: boolean;
14
+ setOpen: (open: boolean) => void;
15
+ triggerContent?: ReactNode;
16
+ title?: ReactNode;
17
+ description?: string;
18
+ children: ReactNode;
19
+ closer?: boolean;
20
+ footer?: ReactNode;
21
+ maxWidth?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
22
+ }
23
+
24
+ export function DialogWrapper({
25
+ open, setOpen, triggerContent, title, description,
26
+ children, closer = true, footer, maxWidth = 'sm',
27
+ }: DialogWrapperProps) {
28
+ return (
29
+ <>
30
+ {triggerContent}
31
+ <Dialog open={open} onClose={() => setOpen(false)} maxWidth={maxWidth} fullWidth scroll="paper">
32
+ {closer && (
33
+ <IconButton
34
+ onClick={() => setOpen(false)}
35
+ sx={{ position: 'absolute', right: 8, top: 8, zIndex: 1 }}
36
+ >
37
+ <CloseIcon />
38
+ </IconButton>
39
+ )}
40
+ {(title || description) && (
41
+ <DialogTitle sx={{ borderBottom: 1, borderColor: 'divider', pb: 2 }}>
42
+ {title && typeof title === 'string' ? title : title}
43
+ {description && (
44
+ <DialogContentText variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
45
+ {description}
46
+ </DialogContentText>
47
+ )}
48
+ </DialogTitle>
49
+ )}
50
+ <DialogContent sx={{ py: 3 }}>{children}</DialogContent>
51
+ {footer && <DialogActions sx={{ borderTop: 1, borderColor: 'divider', px: 3, py: 2 }}>{footer}</DialogActions>}
52
+ </Dialog>
53
+ </>
54
+ );
55
+ }
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+
3
+ import { useFormContext, Controller } from 'react-hook-form';
4
+ import FormControl from '@mui/material/FormControl';
5
+ import FormLabel from '@mui/material/FormLabel';
6
+ import FormGroup from '@mui/material/FormGroup';
7
+ import FormControlLabel from '@mui/material/FormControlLabel';
8
+ import FormHelperText from '@mui/material/FormHelperText';
9
+ import Checkbox from '@mui/material/Checkbox';
10
+ import type { CheckboxProps } from '../../assets/interface/input-props.type';
11
+
12
+ export function CheckField({ form, name, labelName, required, disabled, options = [] }: CheckboxProps) {
13
+ const fieldName = name || labelName?.toLowerCase().replace(/\s+/g, '_') || '';
14
+
15
+ if (form) {
16
+ return (
17
+ <Controller
18
+ name={fieldName}
19
+ control={form.control}
20
+ defaultValue={[]}
21
+ render={({ field, fieldState }) => (
22
+ <FormControl error={!!fieldState.error} required={required} disabled={disabled} component="fieldset">
23
+ {labelName && <FormLabel component="legend">{labelName}</FormLabel>}
24
+ <FormGroup>
25
+ {options.map((opt) => (
26
+ <FormControlLabel
27
+ key={opt.value}
28
+ control={
29
+ <Checkbox
30
+ checked={(field.value || []).includes(opt.value)}
31
+ onChange={(e) => {
32
+ const newVal = e.target.checked
33
+ ? [...(field.value || []), opt.value]
34
+ : (field.value || []).filter((v: string) => v !== opt.value);
35
+ field.onChange(newVal);
36
+ }}
37
+ />
38
+ }
39
+ label={opt.label}
40
+ />
41
+ ))}
42
+ </FormGroup>
43
+ {fieldState.error && <FormHelperText>{fieldState.error.message}</FormHelperText>}
44
+ </FormControl>
45
+ )}
46
+ />
47
+ );
48
+ }
49
+
50
+ return null;
51
+ }
@@ -0,0 +1,50 @@
1
+ 'use client';
2
+
3
+ import { useFormContext, Controller } from 'react-hook-form';
4
+ import TextField from '@mui/material/TextField';
5
+ import type { DatePickerProps } from '../../assets/interface/input-props.type';
6
+
7
+ export function DatePickerField({ form, name, labelName, placeholder, required, disabled, viewOnly, customMessage }: DatePickerProps) {
8
+ const fieldName = name || labelName?.toLowerCase().replace(/\s+/g, '_') || '';
9
+
10
+ if (form) {
11
+ return (
12
+ <Controller
13
+ name={fieldName}
14
+ control={form.control}
15
+ defaultValue=""
16
+ render={({ field, fieldState }) => (
17
+ <TextField
18
+ fullWidth
19
+ variant="outlined"
20
+ label={labelName}
21
+ placeholder={placeholder}
22
+ required={required}
23
+ disabled={disabled || viewOnly}
24
+ type="date"
25
+ error={!!fieldState.error}
26
+ helperText={fieldState.error?.message || customMessage}
27
+ InputLabelProps={{ shrink: true }}
28
+ InputProps={{ readOnly: viewOnly }}
29
+ {...field}
30
+ />
31
+ )}
32
+ />
33
+ );
34
+ }
35
+
36
+ return (
37
+ <TextField
38
+ fullWidth
39
+ variant="outlined"
40
+ label={labelName}
41
+ placeholder={placeholder}
42
+ required={required}
43
+ disabled={disabled || viewOnly}
44
+ type="date"
45
+ helperText={customMessage}
46
+ InputLabelProps={{ shrink: true }}
47
+ InputProps={{ readOnly: viewOnly }}
48
+ />
49
+ );
50
+ }
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+
3
+ import { useFormContext, Controller } from 'react-hook-form';
4
+ import FormControl from '@mui/material/FormControl';
5
+ import FormLabel from '@mui/material/FormLabel';
6
+ import FormGroup from '@mui/material/FormGroup';
7
+ import FormControlLabel from '@mui/material/FormControlLabel';
8
+ import FormHelperText from '@mui/material/FormHelperText';
9
+ import Checkbox from '@mui/material/Checkbox';
10
+ import type { CheckboxProps } from '../../assets/interface/input-props.type';
11
+
12
+ export function MultiCheckField({ form, name, labelName, required, disabled, options = [] }: CheckboxProps) {
13
+ return <CheckField form={form} name={name} labelName={labelName} required={required} disabled={disabled} options={options} />;
14
+ }