diff --git a/fonts/fonts.ts b/fonts/fonts.ts index 86fc498..1b6b331 100644 --- a/fonts/fonts.ts +++ b/fonts/fonts.ts @@ -1,6 +1,8 @@ -import { Inter as inter, Roboto_Mono as roboto } from "next/font/google"; +import { Inter as inter, Lora as lora, Roboto_Mono as roboto } from "next/font/google"; const Inter = inter({ subsets: ["latin"] }); const Roboto = roboto({ weight: ["400", "700"], subsets: ["latin"] }); +const Lora = lora({ weight: ["400", ], subsets: ["latin"] }); + +export { Inter, Lora, Roboto }; -export { Inter, Roboto }; diff --git a/src/app/components/Button/Button.tsx b/src/app/components/Button/Button.tsx index f1a017a..85ed96a 100644 --- a/src/app/components/Button/Button.tsx +++ b/src/app/components/Button/Button.tsx @@ -8,14 +8,17 @@ export default function Button({ children, className, variant = "secondary", + block = false, ...props }: ButtonHTMLAttributes & { children: ReactNode; variant?: "primary" | "secondary"; + block?: boolean; }) { - const buttonClassname = cn("button", className, { + const buttonClassname = cn("btn", className, { [`${variant}`]: variant, + block, }); return ( diff --git a/src/app/components/Button/button.scss b/src/app/components/Button/button.scss index a2628f9..00b07ad 100644 --- a/src/app/components/Button/button.scss +++ b/src/app/components/Button/button.scss @@ -1,4 +1,4 @@ -button.button { +.btn { color: var(--text-color); padding: 8px 16px; border: 2px solid var(--text-color); @@ -7,7 +7,7 @@ button.button { font-size: 1rem; font-weight: 700; background: var(--bg-color); - width: 100%; + width: fit-content; box-shadow: none; transition: all 0.2s ease-in-out; @@ -20,4 +20,8 @@ button.button { box-shadow: 3px 3px 0 1px var(--text-color); } + &.block { + width: 100%; + } + } \ No newline at end of file diff --git a/src/app/components/Footer/Footer.tsx b/src/app/components/Footer/Footer.tsx index 2888fa6..6fd3394 100644 --- a/src/app/components/Footer/Footer.tsx +++ b/src/app/components/Footer/Footer.tsx @@ -1,13 +1,15 @@ -import React from "react"; +"use server"; +import React from "react"; +import { Lora, Roboto } from "../../../../fonts/fonts"; import "./footer.scss"; -export default function Footer() { +export default async function Footer() { return ( ) }; \ No newline at end of file diff --git a/src/app/components/Footer/footer.scss b/src/app/components/Footer/footer.scss index f4a87c6..172a1dd 100644 --- a/src/app/components/Footer/footer.scss +++ b/src/app/components/Footer/footer.scss @@ -4,5 +4,10 @@ footer.footer { width: 100%; text-align: center; padding-block: 1rem; - border-top: 1px solid #eaeaea; + background: var(--primary-btn-bg); + + a { + text-decoration: underline; + } + } \ No newline at end of file diff --git a/src/app/components/Input/input.scss b/src/app/components/Input/input.scss index 381541e..3dc5f33 100644 --- a/src/app/components/Input/input.scss +++ b/src/app/components/Input/input.scss @@ -50,12 +50,12 @@ border-radius: 8px; } - &:user-invalid { + &:not(:placeholder-shown):user-invalid { border-color: var(--danger-color); box-shadow: 3px 3px 0 1px var(--danger-color); } - &:user-valid { + &:not(:placeholder-shown):user-valid { border-color: var(--success-color); box-shadow: 3px 3px 0 1px var(--success-color); } diff --git a/src/app/login/page.tsx b/src/app/components/LoginBox/LoginBox.tsx similarity index 63% rename from src/app/login/page.tsx rename to src/app/components/LoginBox/LoginBox.tsx index 29e1db7..34f4b10 100644 --- a/src/app/login/page.tsx +++ b/src/app/components/LoginBox/LoginBox.tsx @@ -3,22 +3,13 @@ import { useRouter } from "next/navigation"; import React from "react"; -import Button from "../components/Button/Button"; -import Input from "../components/Input/Input"; - -import { supabaseAuth } from "../../../supabaseClient"; +import Button from "../Button/Button"; +import Input from "../Input/Input"; +import { supabaseAuth } from "../../../../supabaseClient"; import "./login.scss"; -const arr: Array<"xs" | "sm" | "md" | "lg" | "xl"> = [ - "xs", - "sm", - "md", - "lg", - "xl", -]; - -export default function Login() { +export default function LoginBox() { const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const router = useRouter(); @@ -39,18 +30,25 @@ export default function Login() { console.log("Sign up response:", { error, data }); }; + const handleLogout = async () => { + const [error, data] = await supabaseAuth.signOut(); + console.log("Logout response:", { error, data }); + }; + const handleSubmit = async (action: string) => { if (action === "login") { handleLogin(); - } else { + } else if (action === "signup") { handleSignUp(); + } else { + handleLogout(); } }; return ( -
+
e.preventDefault()}> -

Login

+

Login

- + +
-
+ ); } diff --git a/src/app/login/login.scss b/src/app/components/LoginBox/login.scss similarity index 61% rename from src/app/login/login.scss rename to src/app/components/LoginBox/login.scss index 0b82ef6..61af9d4 100644 --- a/src/app/login/login.scss +++ b/src/app/components/LoginBox/login.scss @@ -1,24 +1,31 @@ -.main { +.login-wrapper { display: flex; justify-content: center; align-items: center; - min-height: 100vh; + flex-grow: 1; + width: 100%; .login-box { - width: 400px; + min-width: 400px; border: 2px solid black; box-shadow: 4px 4px 0 black; border-radius: 20px; padding: 1.5rem; - h2 { - margin-bottom: 3rem; - } - .input-wrapper { width: 100%; } + .error-message { + color: var(--danger-color); + font-size: 0.875rem; + padding: 0.5rem; + border: 1px solid var(--danger-color); + border-radius: 4px; + margin-bottom: 1rem; + background-color: var(--danger-bg-color); + } + .login-divider { width: 100%; border-bottom: 2px solid; @@ -41,5 +48,11 @@ right: 0; } } + + .actions-wrapper { + display: flex; + flex-direction: column; + gap: 1rem; + } } } \ No newline at end of file diff --git a/src/app/components/PageTitle/PageTitle.tsx b/src/app/components/PageTitle/PageTitle.tsx new file mode 100644 index 0000000..35def0f --- /dev/null +++ b/src/app/components/PageTitle/PageTitle.tsx @@ -0,0 +1,18 @@ +"use server"; +import cn from "classnames"; +export default async function PageTitle({ + subtitle, + className +}: Readonly<{ subtitle?: string, className?: string }>) { + + const headClassName = cn("page-title heading", { + [`${className}`]: className, + }); + + return ( + <> +

Timetables

+ {!!subtitle &&

{subtitle}

} + + ); +} diff --git a/src/app/components/TicTac.tsx b/src/app/components/TicTac.tsx new file mode 100644 index 0000000..8e1a227 --- /dev/null +++ b/src/app/components/TicTac.tsx @@ -0,0 +1,40 @@ +"use client"; + +import React, { useEffect, useState } from 'react'; +const TicTac: React.FC = () => { + const [text, setText] = useState(''); + + useEffect(() => { + const interval = setInterval(() => { + const randomText = text === 'tic' ? 'tac' : 'tic'; + const x = Math.random() * 100; + const y = Math.random() * 100; + setText(randomText); + const ticTacElement = document.getElementById('tic-tac'); + if (ticTacElement) { + ticTacElement.style.left = `${x}vw`; + ticTacElement.style.top = `${y}vh`; + } + }, 1000); + + return () => clearInterval(interval); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( +
+ {text} +
+ ); +}; + +export default TicTac; diff --git a/src/app/home.module.css b/src/app/home.module.css deleted file mode 100644 index e1ca8bf..0000000 --- a/src/app/home.module.css +++ /dev/null @@ -1,251 +0,0 @@ -/* .main { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - overflow: hidden; -} */ - -.heading { - font-size: 120px; -} - -.pageWrapper { - display: flex; - flex-direction: column; - justify-content: space-between; - align-items: center; - padding: 6rem; - flex-grow: 1; - overflow: hidden; -} - -.layout { - display: flex; - flex-direction: column; - height: 100vh; -} - -.description { - display: inherit; - justify-content: inherit; - align-items: inherit; - font-size: 0.85rem; - max-width: var(--max-width); - width: 100%; - z-index: 2; - font-family: var(--font-mono); -} - -.description a { - display: flex; - justify-content: center; - align-items: center; - gap: 0.5rem; -} - -.description p { - position: relative; - margin: 0; - padding: 1rem; - background-color: rgba(var(--callout-rgb), 0.5); - border: 1px solid rgba(var(--callout-border-rgb), 0.3); - border-radius: var(--border-radius); -} - -.code { - font-weight: 700; - font-family: var(--font-mono); -} - -.grid { - display: grid; - grid-template-columns: repeat(4, minmax(25%, auto)); - max-width: 100%; - width: var(--max-width); -} - -.card { - padding: 1rem 1.2rem; - border-radius: var(--border-radius); - background: rgba(var(--card-rgb), 0); - border: 1px solid rgba(var(--card-border-rgb), 0); - transition: background 200ms, border 200ms; -} - -.card span { - display: inline-block; - transition: transform 200ms; -} - -.card h2 { - font-weight: 600; - margin-bottom: 0.7rem; -} - -.card p { - margin: 0; - opacity: 0.6; - font-size: 0.9rem; - line-height: 1.5; - max-width: 30ch; - text-wrap: balance; -} - -.center { - display: flex; - justify-content: center; - align-items: center; - position: relative; - padding: 4rem 0; -} - -.center::before { - background: var(--secondary-glow); - border-radius: 50%; - width: 480px; - height: 360px; - margin-left: -400px; -} - -.center::after { - /* background: var(--primary-glow); */ - width: 240px; - height: 180px; - z-index: -1; -} - -.center::before, -.center::after { - content: ""; - left: 50%; - position: absolute; - filter: blur(45px); - transform: translateZ(0); -} - -.logo { - position: relative; -} - -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - .card:hover { - background: rgba(var(--card-rgb), 0.1); - border: 1px solid rgba(var(--card-border-rgb), 0.15); - } - - .card:hover span { - transform: translateX(4px); - } -} - -@media (prefers-reduced-motion) { - .card:hover span { - transform: none; - } -} - -/* Mobile */ -@media (max-width: 700px) { - .content { - padding: 4rem; - } - - .grid { - grid-template-columns: 1fr; - margin-bottom: 120px; - max-width: 320px; - text-align: center; - } - - .card { - padding: 1rem 2.5rem; - } - - .card h2 { - margin-bottom: 0.5rem; - } - - .center { - padding: 8rem 0 6rem; - } - - .center::before { - transform: none; - height: 300px; - } - - .description { - font-size: 0.8rem; - } - - .description a { - padding: 1rem; - } - - .description p, - .description div { - display: flex; - justify-content: center; - position: fixed; - width: 100%; - } - - .description p { - align-items: center; - inset: 0 0 auto; - padding: 2rem 1rem 1.4rem; - border-radius: 0; - border: none; - border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); - background: linear-gradient( - to bottom, - rgba(var(--background-start-rgb), 1), - rgba(var(--callout-rgb), 0.5) - ); - background-clip: padding-box; - backdrop-filter: blur(24px); - } - - .description div { - align-items: flex-end; - pointer-events: none; - inset: auto 0 0; - padding: 2rem; - height: 200px; - background: linear-gradient( - to bottom, - transparent 0%, - rgb(var(--background-end-rgb)) 40% - ); - z-index: 1; - } -} - -/* Tablet and Smaller Desktop */ -@media (min-width: 701px) and (max-width: 1120px) { - .grid { - grid-template-columns: repeat(2, 50%); - } -} - -@media (prefers-color-scheme: dark) { - .vercelLogo { - filter: invert(1); - } - - .logo { - filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); - } -} - -@keyframes rotate { - from { - transform: rotate(360deg); - } - to { - transform: rotate(0deg); - } -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index ca89b63..21b07bb 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,24 +1,28 @@ -import type { Metadata } from "next"; +"use server"; + import { Roboto } from "../../fonts/fonts"; import Footer from "./components/Footer/Footer"; -import styles from "./home.module.css"; import "./style/globals/globals.css"; +import "./style/globals/reset.css"; import "./style/globals/utilities.css"; +import "./style/layout.css"; -export const metadata: Metadata = { - title: "Timetables", - description: "Il tool per capire a che ora puoi uscire venerdì dall' ufficio", -}; - -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( - -
{children}
+ + Timetables + + + + {children}