diff --git a/dashboard/15-final/app/layout.tsx b/dashboard/15-final/app/layout.tsx index ef077d2..139fcc0 100644 --- a/dashboard/15-final/app/layout.tsx +++ b/dashboard/15-final/app/layout.tsx @@ -16,7 +16,7 @@ export default function RootLayout({ }) { return ( - {children} + {children} ) } diff --git a/dashboard/15-final/app/login/page.tsx b/dashboard/15-final/app/login/page.tsx index e65cbe6..522ecd1 100644 --- a/dashboard/15-final/app/login/page.tsx +++ b/dashboard/15-final/app/login/page.tsx @@ -1,7 +1,9 @@ +import LoginForm from "@/app/ui/login-form"; + export default function Page() { return ( -
-
Replace with login-form.tsx
-
- ) +
+ +
+ ); } diff --git a/dashboard/15-final/app/page.tsx b/dashboard/15-final/app/page.tsx index 5de4f25..76bab6f 100644 --- a/dashboard/15-final/app/page.tsx +++ b/dashboard/15-final/app/page.tsx @@ -1,11 +1,9 @@ +import Hero from "@/app/ui/hero"; + export default function Page() { return ( -
-
- Landing page. Login button should be in content to avoid root layouts - and route groups complexity. - -
-
- ) +
+ +
+ ); } diff --git a/dashboard/15-final/app/ui/background-blur.tsx b/dashboard/15-final/app/ui/background-blur.tsx new file mode 100644 index 0000000..64c23d5 --- /dev/null +++ b/dashboard/15-final/app/ui/background-blur.tsx @@ -0,0 +1,8 @@ +export default function BackgroundBlur() { + return ( +
+
+
+
+ ); +} diff --git a/dashboard/15-final/app/ui/hero.tsx b/dashboard/15-final/app/ui/hero.tsx new file mode 100644 index 0000000..06f8a30 --- /dev/null +++ b/dashboard/15-final/app/ui/hero.tsx @@ -0,0 +1,30 @@ +import BackgroundBlur from "@/app/ui/background-blur"; + +export default function Hero() { + return ( + <> +
+ +

+ Next.js Dashboard +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vulputate + dapibus consectetur. Duis quis eros euismod. +

+ + + +
+ +
+ Dashboard image +
+ + ); +} diff --git a/dashboard/15-final/app/ui/login-form.tsx b/dashboard/15-final/app/ui/login-form.tsx new file mode 100644 index 0000000..1ca08a6 --- /dev/null +++ b/dashboard/15-final/app/ui/login-form.tsx @@ -0,0 +1,71 @@ +"use client"; + +import BackgroundBlur from "@/app/ui/background-blur"; +import React, { useState } from "react"; + +// This component contains basic logic for a React Form. +// We'll be updating it in Chapter 8 - Adding Authentication. + +export default function LoginForm() { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + const handleSubmit = (e: { preventDefault: () => void }) => { + e.preventDefault(); + console.log(`Email: ${email}, Password: ${password}`); + }; + + return ( +
+ + + Next.js Logo + +

+ Log in to your dashboard +

+
+
+
+ + setEmail(e.target.value)} + /> +
+
+ + setPassword(e.target.value)} + /> +
+
+ +
+
+
+
+ ); +} diff --git a/dashboard/15-final/package-lock.json b/dashboard/15-final/package-lock.json index 6caf7d0..e4182fa 100644 --- a/dashboard/15-final/package-lock.json +++ b/dashboard/15-final/package-lock.json @@ -20,6 +20,10 @@ "react-dom": "18.2.0", "tailwindcss": "3.3.3", "typescript": "5.2.2" + }, + "devDependencies": { + "prettier": "^3.0.3", + "prettier-plugin-tailwindcss": "^0.5.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -3122,6 +3126,93 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.3.tgz", + "integrity": "sha512-M5K80V21yM+CTm/FEFYRv9/9LyInYbCSXpIoPAKMm8zy89IOwdiA2e4JVbcO7tvRtAQWz32zdj7/WKcsmFyAVg==", + "dev": true, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@shufo/prettier-plugin-blade": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@shufo/prettier-plugin-blade": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "prettier-plugin-twig-melody": { + "optional": true + } + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -6111,6 +6202,19 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, + "prettier": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", + "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "dev": true + }, + "prettier-plugin-tailwindcss": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.3.tgz", + "integrity": "sha512-M5K80V21yM+CTm/FEFYRv9/9LyInYbCSXpIoPAKMm8zy89IOwdiA2e4JVbcO7tvRtAQWz32zdj7/WKcsmFyAVg==", + "dev": true, + "requires": {} + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", diff --git a/dashboard/15-final/package.json b/dashboard/15-final/package.json index aa074b9..48cd717 100644 --- a/dashboard/15-final/package.json +++ b/dashboard/15-final/package.json @@ -21,5 +21,9 @@ "react-dom": "18.2.0", "tailwindcss": "3.3.3", "typescript": "5.2.2" + }, + "devDependencies": { + "prettier": "^3.0.3", + "prettier-plugin-tailwindcss": "^0.5.3" } } diff --git a/dashboard/15-final/prettier.config.js b/dashboard/15-final/prettier.config.js new file mode 100644 index 0000000..d573118 --- /dev/null +++ b/dashboard/15-final/prettier.config.js @@ -0,0 +1,3 @@ +module.exports = { + plugins: ["prettier-plugin-tailwindcss"], +};