mirror of
https://github.com/vercel/next-learn.git
synced 2026-06-11 09:51:47 +00:00
Add components for home and login pages (#128)
* Run create-next-app * Add READMEs * Remove stuff we don't need * Add dummy data * Add types for dummy data * Add dummy routes * Remove unused CSS * Split dummy data and definitions * Add prettier plugin for tailwind * Create background-blur.tsx * Create hero.tsx * Create login-form.tsx * Tweak * Fix ts error
This commit is contained in:
committed by
GitHub
parent
8dd0d1d863
commit
4376abb821
@@ -16,7 +16,7 @@ export default function RootLayout({
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<body className={`bg-white ${inter.className}`}>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import LoginForm from "@/app/ui/login-form";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
<div>Replace with login-form.tsx</div>
|
||||
</div>
|
||||
)
|
||||
<main>
|
||||
<LoginForm />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import Hero from "@/app/ui/hero";
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
Landing page. Login button should be in content to avoid root layouts
|
||||
and route groups complexity.
|
||||
<button>Login</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
<main>
|
||||
<Hero />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
8
dashboard/15-final/app/ui/background-blur.tsx
Normal file
8
dashboard/15-final/app/ui/background-blur.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
export default function BackgroundBlur() {
|
||||
return (
|
||||
<div className="-z-10">
|
||||
<div className="absolute left-[55%] top-[10%] h-40 w-40 rounded-full bg-gradient-to-r from-blue-200 via-blue-300 to-blue-500 opacity-90 blur-3xl"></div>
|
||||
<div className="absolute left-[50%] top-[18%] h-40 w-40 transform rounded-full bg-gradient-to-r from-blue-200 via-blue-300 to-blue-500 opacity-60 blur-3xl"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
30
dashboard/15-final/app/ui/hero.tsx
Normal file
30
dashboard/15-final/app/ui/hero.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import BackgroundBlur from "@/app/ui/background-blur";
|
||||
|
||||
export default function Hero() {
|
||||
return (
|
||||
<>
|
||||
<div className="mx-auto mt-20 flex flex-col items-center space-y-6 p-2 md:w-1/3">
|
||||
<BackgroundBlur />
|
||||
<h1 className="text-center text-4xl font-bold tracking-tight text-zinc-900 sm:text-5xl">
|
||||
Next.js Dashboard
|
||||
</h1>
|
||||
<p className="text-center leading-6 text-zinc-900">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut vulputate
|
||||
dapibus consectetur. Duis quis eros euismod.
|
||||
</p>
|
||||
<a href="/login">
|
||||
<button className="rounded-md bg-black px-4 py-2 text-sm font-semibold text-white hover:bg-zinc-700">
|
||||
Log in
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto mt-12 w-full px-4 lg:w-2/3">
|
||||
<img
|
||||
src="https://vercel.com/_next/image?url=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Finsights%2Fanalytics_dashboard.png&w=3840&q=75&dpl=dpl_9Tp4gaAJ1QFc4eSRJ99UwWvWgZ73"
|
||||
alt="Dashboard image"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
71
dashboard/15-final/app/ui/login-form.tsx
Normal file
71
dashboard/15-final/app/ui/login-form.tsx
Normal file
@@ -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 (
|
||||
<div className="mt-40 flex h-screen flex-col items-center space-y-6">
|
||||
<BackgroundBlur />
|
||||
<a href="/">
|
||||
<img className="h-6 w-auto" src="/logo.svg" alt="Next.js Logo" />
|
||||
</a>
|
||||
<p className="text-center font-semibold text-zinc-900">
|
||||
Log in to your dashboard
|
||||
</p>
|
||||
<div className="w-full max-w-sm">
|
||||
<form onSubmit={handleSubmit} className="px-4">
|
||||
<div>
|
||||
<label
|
||||
className="block text-sm font-medium leading-8 text-zinc-900"
|
||||
htmlFor="email"
|
||||
>
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
className="block w-full rounded-md border-0 p-1.5 text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 sm:text-sm"
|
||||
id="email"
|
||||
type="text"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<label
|
||||
className="block text-sm font-medium leading-8 text-zinc-900"
|
||||
htmlFor="password"
|
||||
>
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
className="block w-full rounded-md border-0 p-1.5 text-zinc-900 shadow-sm ring-1 ring-inset ring-zinc-300 sm:text-sm"
|
||||
id="password"
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<button
|
||||
className="w-full rounded-md bg-black px-4 py-2 text-center text-sm font-semibold text-white hover:bg-zinc-700"
|
||||
type="submit"
|
||||
>
|
||||
Log in
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
104
dashboard/15-final/package-lock.json
generated
104
dashboard/15-final/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
3
dashboard/15-final/prettier.config.js
Normal file
3
dashboard/15-final/prettier.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
plugins: ["prettier-plugin-tailwindcss"],
|
||||
};
|
||||
Reference in New Issue
Block a user