diff --git a/dashboard/final-example/app/lib/actions.ts b/dashboard/final-example/app/lib/actions.ts index 84007c9..2a6355b 100644 --- a/dashboard/final-example/app/lib/actions.ts +++ b/dashboard/final-example/app/lib/actions.ts @@ -24,7 +24,6 @@ const FormSchema = z.object({ const CreateInvoice = FormSchema.omit({ id: true, date: true }); const UpdateInvoice = FormSchema.omit({ date: true, id: true }); -// This is temporary export type State = { errors?: { customerId?: string[]; diff --git a/dashboard/final-example/app/ui/invoices/create-form.tsx b/dashboard/final-example/app/ui/invoices/create-form.tsx index 6012b30..e3cdc47 100644 --- a/dashboard/final-example/app/ui/invoices/create-form.tsx +++ b/dashboard/final-example/app/ui/invoices/create-form.tsx @@ -10,14 +10,14 @@ import { } from '@heroicons/react/24/outline'; import { Button } from '@/app/ui/button'; import { createInvoice, State } from '@/app/lib/actions'; -import { useFormState } from 'react-dom'; +import { useActionState } from 'react'; export default function Form({ customers }: { customers: CustomerField[] }) { const initialState: State = { message: null, errors: {} }; - const [state, dispatch] = useFormState(createInvoice, initialState); + const [state, formAction] = useActionState(createInvoice, initialState); return ( -
+
{/* Customer Name */}
diff --git a/dashboard/final-example/app/ui/invoices/edit-form.tsx b/dashboard/final-example/app/ui/invoices/edit-form.tsx index a1e7140..5aa4ece 100644 --- a/dashboard/final-example/app/ui/invoices/edit-form.tsx +++ b/dashboard/final-example/app/ui/invoices/edit-form.tsx @@ -10,7 +10,7 @@ import { import Link from 'next/link'; import { Button } from '@/app/ui/button'; import { updateInvoice, State } from '@/app/lib/actions'; -import { useFormState } from 'react-dom'; +import { useActionState } from 'react'; export default function EditInvoiceForm({ invoice, @@ -21,10 +21,10 @@ export default function EditInvoiceForm({ }) { const initialState: State = { message: null, errors: {} }; const updateInvoiceWithId = updateInvoice.bind(null, invoice.id); - const [state, dispatch] = useFormState(updateInvoiceWithId, initialState); + const [state, formAction] = useActionState(updateInvoiceWithId, initialState); return ( - +
{/* Customer Name */}
diff --git a/dashboard/final-example/app/ui/login-form.tsx b/dashboard/final-example/app/ui/login-form.tsx index 601e6e0..1fc4a5b 100644 --- a/dashboard/final-example/app/ui/login-form.tsx +++ b/dashboard/final-example/app/ui/login-form.tsx @@ -9,13 +9,16 @@ import { } from '@heroicons/react/24/outline'; import { ArrowRightIcon } from '@heroicons/react/20/solid'; import { Button } from './button'; -import { useFormState, useFormStatus } from 'react-dom'; +import { useActionState } from 'react'; export default function LoginForm() { - const [errorMessage, dispatch] = useFormState(authenticate, undefined); + const [errorMessage, formAction, isPending] = useActionState( + authenticate, + undefined, + ); return ( - +

Please log in to continue. @@ -61,7 +64,9 @@ export default function LoginForm() {

- +
); } - -function LoginButton() { - const { pending } = useFormStatus(); - - return ( - - ); -} diff --git a/dashboard/final-example/package.json b/dashboard/final-example/package.json index 7214ca0..04709cb 100644 --- a/dashboard/final-example/package.json +++ b/dashboard/final-example/package.json @@ -29,8 +29,8 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.1", - "@types/react": "18.2.21", - "@types/react-dom": "18.2.14", + "@types/react": "18.3.3", + "@types/react-dom": "18.3.0", "@vercel/style-guide": "^5.0.1", "dotenv": "^16.3.1", "eslint": "^8.52.0", diff --git a/dashboard/final-example/pnpm-lock.yaml b/dashboard/final-example/pnpm-lock.yaml index 94b2351..f6f2839 100644 --- a/dashboard/final-example/pnpm-lock.yaml +++ b/dashboard/final-example/pnpm-lock.yaml @@ -59,11 +59,11 @@ devDependencies: specifier: ^5.0.1 version: 5.0.2 '@types/react': - specifier: 18.2.21 - version: 18.2.21 + specifier: 18.3.3 + version: 18.3.3 '@types/react-dom': - specifier: 18.2.14 - version: 18.2.14 + specifier: 18.3.0 + version: 18.3.0 '@vercel/style-guide': specifier: ^5.0.1 version: 5.2.0(eslint@8.57.0)(prettier@3.3.2)(typescript@5.2.2) @@ -844,24 +844,19 @@ packages: resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} dev: true - /@types/react-dom@18.2.14: - resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} + /@types/react-dom@18.3.0: + resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} dependencies: - '@types/react': 18.2.21 + '@types/react': 18.3.3 dev: true - /@types/react@18.2.21: - resolution: {integrity: sha512-neFKG/sBAwGxHgXiIxnbm3/AAVQ/cMRS93hvBpg8xYRbeQSPVABp9U2bRnPf0iI4+Ucdv3plSxKK+3CW2ENJxA==} + /@types/react@18.3.3: + resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} dependencies: '@types/prop-types': 15.7.12 - '@types/scheduler': 0.23.0 csstype: 3.1.3 dev: true - /@types/scheduler@0.23.0: - resolution: {integrity: sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==} - dev: true - /@types/semver@7.5.8: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true @@ -1166,7 +1161,7 @@ packages: eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1) eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.57.0)(typescript@5.2.2) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-playwright: 0.16.0(eslint-plugin-jest@27.9.0)(eslint@8.57.0) @@ -1955,7 +1950,7 @@ packages: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.2(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) @@ -1980,7 +1975,7 @@ packages: peerDependencies: eslint-plugin-import: '>=1.4.0' dependencies: - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) dev: true /eslint-import-resolver-node@0.3.9: @@ -2004,7 +1999,7 @@ packages: enhanced-resolve: 5.17.0 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -2027,7 +2022,7 @@ packages: enhanced-resolve: 5.17.0 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -2039,6 +2034,36 @@ packages: - supports-color dev: true + /eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.2.2) + debug: 3.2.7 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + dev: true + /eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} engines: {node: '>=4'} @@ -2138,6 +2163,41 @@ packages: ignore: 5.3.1 dev: true + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.2.2) + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} @@ -2173,41 +2233,6 @@ packages: - supports-color dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): - resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.2.2) - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.5 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - hasown: 2.0.2 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.0 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: true - /eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@6.21.0)(eslint@8.57.0)(typescript@5.2.2): resolution: {integrity: sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} diff --git a/dashboard/starter-example/app/ui/login-form.tsx b/dashboard/starter-example/app/ui/login-form.tsx index 80d4b17..2976b67 100644 --- a/dashboard/starter-example/app/ui/login-form.tsx +++ b/dashboard/starter-example/app/ui/login-form.tsx @@ -55,7 +55,9 @@ export default function LoginForm() {
- +
{/* Add form errors here */}
@@ -63,11 +65,3 @@ export default function LoginForm() { ); } - -function LoginButton() { - return ( - - ); -} diff --git a/dashboard/starter-example/next.config.mjs b/dashboard/starter-example/next.config.mjs index 4678774..81aa05b 100644 --- a/dashboard/starter-example/next.config.mjs +++ b/dashboard/starter-example/next.config.mjs @@ -1,4 +1,5 @@ /** @type {import('next').NextConfig} */ + const nextConfig = {}; export default nextConfig;