diff --git a/dashboard/15-final/app/layout.tsx b/dashboard/15-final/app/layout.tsx index b2b260c..ca1f757 100644 --- a/dashboard/15-final/app/layout.tsx +++ b/dashboard/15-final/app/layout.tsx @@ -1,3 +1,4 @@ +import clsx from 'clsx'; import '@/app/ui/global.css'; import type { Metadata } from 'next'; import { inter } from '@/app/ui/fonts'; @@ -14,7 +15,7 @@ export default function RootLayout({ }) { return ( - {children} + {children} ); } diff --git a/dashboard/15-final/app/ui/button.tsx b/dashboard/15-final/app/ui/button.tsx new file mode 100644 index 0000000..545f1cc --- /dev/null +++ b/dashboard/15-final/app/ui/button.tsx @@ -0,0 +1,19 @@ +import clsx from 'clsx'; + +interface ButtonProps extends React.ButtonHTMLAttributes { + children: React.ReactNode; +} + +export function Button({ children, className, ...rest }: ButtonProps) { + return ( + + ); +} diff --git a/dashboard/15-final/app/ui/login-form.tsx b/dashboard/15-final/app/ui/login-form.tsx index 540a58f..b903a05 100644 --- a/dashboard/15-final/app/ui/login-form.tsx +++ b/dashboard/15-final/app/ui/login-form.tsx @@ -1,10 +1,14 @@ 'use client'; -import Link from 'next/link'; import { signIn } from 'next-auth/react'; import { useRouter } from 'next/navigation'; import React, { useState } from 'react'; -import Image from 'next/image'; +import { lusitana } from '@/app/ui/fonts'; +import clsx from 'clsx'; +import { AtSymbolIcon, KeyIcon } from '@heroicons/react/24/outline'; +import { Button } from './button'; +import { ArrowRightIcon } from '@heroicons/react/20/solid'; +import { Logo } from './logo'; export default function LoginForm() { const [email, setEmail] = useState(''); @@ -33,65 +37,69 @@ export default function LoginForm() { } }; return ( -
-
- - The Next.js Symbol, a white N inside a black circle - -
-
-
- - setEmail(e.target.value)} - /> -
-
- - setPassword(e.target.value)} - /> -
- {error && ( -

- {error} -

- )} - - -
+
+
+
+
+
+
+

+ Please log in to continue. +

+
+
+ +
+ setEmail(e.target.value)} + /> + +
+
+
+ +
+ setPassword(e.target.value)} + /> + +
+
+ {error && ( +

+ {error} +

+ )} +
+
+ +
); diff --git a/dashboard/15-final/app/ui/logo.tsx b/dashboard/15-final/app/ui/logo.tsx new file mode 100644 index 0000000..ca0a05c --- /dev/null +++ b/dashboard/15-final/app/ui/logo.tsx @@ -0,0 +1,46 @@ +export function Logo() { + return ( + + + + + + + + + + + + + + + ); +} diff --git a/dashboard/15-final/package.json b/dashboard/15-final/package.json index d2824ad..284ce0e 100644 --- a/dashboard/15-final/package.json +++ b/dashboard/15-final/package.json @@ -31,7 +31,8 @@ }, "devDependencies": { "@types/bcrypt": "^5.0.0", - "dotenv": "^16.3.1" + "dotenv": "^16.3.1", + "prettier": "^3.0.3" }, "engines": { "node": ">=18" diff --git a/dashboard/15-final/tailwind.config.ts b/dashboard/15-final/tailwind.config.ts index aec8276..23e3b47 100644 --- a/dashboard/15-final/tailwind.config.ts +++ b/dashboard/15-final/tailwind.config.ts @@ -11,6 +11,11 @@ const config: Config = { gridTemplateColumns: { '13': 'repeat(13, minmax(0, 1fr))', }, + colors: { + blue: { + 600: '#2F6FEB', + }, + }, }, keyframes: { shimmer: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2272283..2f6b147 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -37,7 +37,7 @@ importers: version: 4.0.3 next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -55,7 +55,7 @@ importers: dependencies: next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -73,7 +73,7 @@ importers: version: 4.0.3 next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -91,7 +91,7 @@ importers: dependencies: next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -109,7 +109,7 @@ importers: version: 4.0.3 next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -130,7 +130,7 @@ importers: version: 4.0.3 next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -145,7 +145,7 @@ importers: version: 4.0.3 next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -157,7 +157,7 @@ importers: dependencies: next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -169,7 +169,7 @@ importers: dependencies: next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -274,6 +274,9 @@ importers: dotenv: specifier: ^16.3.1 version: 16.3.1 + prettier: + specifier: ^3.0.3 + version: 3.0.3 seo/demo: dependencies: @@ -285,7 +288,7 @@ importers: version: 4.17.21 next: specifier: latest - version: 13.5.3(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) + version: 13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -639,6 +642,10 @@ packages: resolution: {integrity: sha512-X4te86vsbjsB7iO4usY9jLPtZ827Mbx+WcwNBGUOIuswuTAKQtzsuoxc/6KLxCMvogKG795MhrR1LDhYgDvasg==} dev: false + /@next/env@13.5.4: + resolution: {integrity: sha512-LGegJkMvRNw90WWphGJ3RMHMVplYcOfRWf2Be3td3sUa+1AaxmsYyANsA+znrGCBjXJNi4XAQlSoEfUxs/4kIQ==} + dev: false + /@next/eslint-plugin-next@13.4.19: resolution: {integrity: sha512-N/O+zGb6wZQdwu6atMZHbR7T9Np5SUFUjZqCbj0sXm+MwQO35M8TazVB4otm87GkXYs2l6OPwARd3/PUWhZBVQ==} dependencies: @@ -654,6 +661,15 @@ packages: dev: false optional: true + /@next/swc-darwin-arm64@13.5.4: + resolution: {integrity: sha512-Df8SHuXgF1p+aonBMcDPEsaahNo2TCwuie7VXED4FVyECvdXfRT9unapm54NssV9tF3OQFKBFOdlje4T43VO0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@next/swc-darwin-x64@13.5.3: resolution: {integrity: sha512-UpBKxu2ob9scbpJyEq/xPgpdrgBgN3aLYlxyGqlYX5/KnwpJpFuIHU2lx8upQQ7L+MEmz+fA1XSgesoK92ppwQ==} engines: {node: '>= 10'} @@ -663,6 +679,15 @@ packages: dev: false optional: true + /@next/swc-darwin-x64@13.5.4: + resolution: {integrity: sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-arm64-gnu@13.5.3: resolution: {integrity: sha512-5AzM7Yx1Ky+oLY6pHs7tjONTF22JirDPd5Jw/3/NazJ73uGB05NqhGhB4SbeCchg7SlVYVBeRMrMSZwJwq/xoA==} engines: {node: '>= 10'} @@ -672,6 +697,15 @@ packages: dev: false optional: true + /@next/swc-linux-arm64-gnu@13.5.4: + resolution: {integrity: sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-arm64-musl@13.5.3: resolution: {integrity: sha512-A/C1shbyUhj7wRtokmn73eBksjTM7fFQoY2v/0rTM5wehpkjQRLOXI8WJsag2uLhnZ4ii5OzR1rFPwoD9cvOgA==} engines: {node: '>= 10'} @@ -681,6 +715,15 @@ packages: dev: false optional: true + /@next/swc-linux-arm64-musl@13.5.4: + resolution: {integrity: sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-x64-gnu@13.5.3: resolution: {integrity: sha512-FubPuw/Boz8tKkk+5eOuDHOpk36F80rbgxlx4+xty/U71e3wZZxVYHfZXmf0IRToBn1Crb8WvLM9OYj/Ur815g==} engines: {node: '>= 10'} @@ -690,6 +733,15 @@ packages: dev: false optional: true + /@next/swc-linux-x64-gnu@13.5.4: + resolution: {integrity: sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-x64-musl@13.5.3: resolution: {integrity: sha512-DPw8nFuM1uEpbX47tM3wiXIR0Qa+atSzs9Q3peY1urkhofx44o7E1svnq+a5Q0r8lAcssLrwiM+OyJJgV/oj7g==} engines: {node: '>= 10'} @@ -699,6 +751,15 @@ packages: dev: false optional: true + /@next/swc-linux-x64-musl@13.5.4: + resolution: {integrity: sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-win32-arm64-msvc@13.5.3: resolution: {integrity: sha512-zBPSP8cHL51Gub/YV8UUePW7AVGukp2D8JU93IHbVDu2qmhFAn9LWXiOOLKplZQKxnIPUkJTQAJDCWBWU4UWUA==} engines: {node: '>= 10'} @@ -708,6 +769,15 @@ packages: dev: false optional: true + /@next/swc-win32-arm64-msvc@13.5.4: + resolution: {integrity: sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@next/swc-win32-ia32-msvc@13.5.3: resolution: {integrity: sha512-ONcL/lYyGUj4W37D4I2I450SZtSenmFAvapkJQNIJhrPMhzDU/AdfLkW98NvH1D2+7FXwe7yclf3+B7v28uzBQ==} engines: {node: '>= 10'} @@ -717,6 +787,15 @@ packages: dev: false optional: true + /@next/swc-win32-ia32-msvc@13.5.4: + resolution: {integrity: sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@next/swc-win32-x64-msvc@13.5.3: resolution: {integrity: sha512-2Vz2tYWaLqJvLcWbbTlJ5k9AN6JD7a5CN2pAeIzpbecK8ZF/yobA39cXtv6e+Z8c5UJuVOmaTldEAIxvsIux/Q==} engines: {node: '>= 10'} @@ -726,6 +805,15 @@ packages: dev: false optional: true + /@next/swc-win32-x64-msvc@13.5.4: + resolution: {integrity: sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: @@ -3681,6 +3769,45 @@ packages: - babel-plugin-macros dev: false + /next@13.5.4(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-+93un5S779gho8y9ASQhb/bTkQF17FNQOtXLKAj3lsNgltEcF0C5PMLLncDmH+8X1EnJH1kbqAERa29nRXqhjA==} + engines: {node: '>=16.14.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + sass: + optional: true + dependencies: + '@next/env': 13.5.4 + '@swc/helpers': 0.5.2 + busboy: 1.6.0 + caniuse-lite: 1.0.30001541 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.1(@babel/core@7.23.0)(react@18.2.0) + watchpack: 2.4.0 + optionalDependencies: + '@next/swc-darwin-arm64': 13.5.4 + '@next/swc-darwin-x64': 13.5.4 + '@next/swc-linux-arm64-gnu': 13.5.4 + '@next/swc-linux-arm64-musl': 13.5.4 + '@next/swc-linux-x64-gnu': 13.5.4 + '@next/swc-linux-x64-musl': 13.5.4 + '@next/swc-win32-arm64-msvc': 13.5.4 + '@next/swc-win32-ia32-msvc': 13.5.4 + '@next/swc-win32-x64-msvc': 13.5.4 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + dev: false + /node-addon-api@5.1.0: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} dev: false @@ -4103,6 +4230,15 @@ packages: source-map-js: 1.0.2 dev: false + /postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: false + /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'}