diff --git a/package-lock.json b/package-lock.json index ad1130c..25d6933 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,14 @@ "name": "skilld-admin", "version": "0.1.0", "dependencies": { + "@hookform/resolvers": "^3.3.4", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-hover-card": "^1.0.7", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", @@ -31,9 +33,11 @@ "next-themes": "^0.3.0", "react": "^18", "react-dom": "^18", + "react-hook-form": "^7.51.3", "react-resizable-panels": "^2.0.16", "tailwind-merge": "^2.2.2", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "zod": "^3.22.4" }, "devDependencies": { "@types/node": "^20", @@ -168,6 +172,14 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, + "node_modules/@hookform/resolvers": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz", + "integrity": "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -838,6 +850,29 @@ } } }, + "node_modules/@radix-ui/react-label": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", + "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-menu": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", @@ -4845,6 +4880,21 @@ "react": "^18.2.0" } }, + "node_modules/react-hook-form": { + "version": "7.51.3", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.3.tgz", + "integrity": "sha512-cvJ/wbHdhYx8aviSWh28w9ImjmVsb5Y05n1+FW786vEZQJV5STNM0pW6ujS+oiBecb0ARBxJFyAnXj9+GHXACQ==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -6075,6 +6125,14 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } } } diff --git a/package.json b/package.json index c0fad3e..1ccc1f6 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,14 @@ "lint": "next lint" }, "dependencies": { + "@hookform/resolvers": "^3.3.4", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-hover-card": "^1.0.7", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", @@ -32,9 +34,11 @@ "next-themes": "^0.3.0", "react": "^18", "react-dom": "^18", + "react-hook-form": "^7.51.3", "react-resizable-panels": "^2.0.16", "tailwind-merge": "^2.2.2", - "tailwindcss-animate": "^1.0.7" + "tailwindcss-animate": "^1.0.7", + "zod": "^3.22.4" }, "devDependencies": { "@types/node": "^20", diff --git a/src/app/(dashboard)/dashboard/change-password/page.tsx b/src/app/(dashboard)/dashboard/change-password/page.tsx new file mode 100644 index 0000000..9c32b58 --- /dev/null +++ b/src/app/(dashboard)/dashboard/change-password/page.tsx @@ -0,0 +1,17 @@ +import ChangePasswordForm from "@/components/change-password-form"; +import { Separator } from "@/components/ui/separator"; + +export default function SettingsProfilePage() { + return ( +
+ Change your password carefully. +
+
+ {JSON.stringify(data, null, 2)}
+
+ ),
+ });
+
+ form.reset();
+ }
+
+ return (
+
+
+ );
+}
diff --git a/src/components/ui/form.tsx b/src/components/ui/form.tsx
new file mode 100644
index 0000000..f6afdaf
--- /dev/null
+++ b/src/components/ui/form.tsx
@@ -0,0 +1,176 @@
+import * as React from "react"
+import * as LabelPrimitive from "@radix-ui/react-label"
+import { Slot } from "@radix-ui/react-slot"
+import {
+ Controller,
+ ControllerProps,
+ FieldPath,
+ FieldValues,
+ FormProvider,
+ useFormContext,
+} from "react-hook-form"
+
+import { cn } from "@/lib/utils"
+import { Label } from "@/components/ui/label"
+
+const Form = FormProvider
+
+type FormFieldContextValue<
+ TFieldValues extends FieldValues = FieldValues,
+ TName extends FieldPath+ {body} +
+ ) +}) +FormMessage.displayName = "FormMessage" + +export { + useFormField, + Form, + FormItem, + FormLabel, + FormControl, + FormDescription, + FormMessage, + FormField, +} diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx new file mode 100644 index 0000000..5341821 --- /dev/null +++ b/src/components/ui/label.tsx @@ -0,0 +1,26 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef