Add registration and login pages
Added new pages for user registration and login. Also implemented registration and login forms. Updated dependencies in package.json and modified layout design in header and theme-selector components.
This commit is contained in:
parent
4559bc1431
commit
43f9d8204c
45
.idea/workspace.xml
generated
45
.idea/workspace.xml
generated
@ -5,12 +5,17 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="42d2b9e8-8d19-46be-8636-69ddba4519e4" name="Changes" comment="">
|
<list default="true" id="42d2b9e8-8d19-46be-8636-69ddba4519e4" name="Changes" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/app/account/login/page.tsx" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/app/account/register/page.tsx" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/components/login-form.tsx" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/components/register-form.tsx" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/pnpm-lock.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pnpm-lock.yaml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pnpm-lock.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pnpm-lock.yaml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/globals.css" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/globals.css" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/layout.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/layout.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/app/layout.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/layout.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/page.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/app/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/page.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/tailwind.config.ts" beforeDir="false" afterPath="$PROJECT_DIR$/tailwind.config.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/components/header.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/header.tsx" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/components/theme-selector.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/components/theme-selector.tsx" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@ -28,6 +33,9 @@
|
|||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="PackageJsonUpdateNotifier">
|
||||||
|
<dismissed value="$PROJECT_DIR$/package.json" />
|
||||||
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
"associatedIndex": 2
|
"associatedIndex": 2
|
||||||
}</component>
|
}</component>
|
||||||
@ -36,23 +44,23 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"last_opened_file_path": "/home/avnyr/workspace/Simplon/brief-06-front",
|
"last_opened_file_path": "/home/avnyr/workspace/Simplon/brief-06-front",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"npm.dev.executor": "Run",
|
"npm.dev.executor": "Run",
|
||||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||||
"ts.external.directory.path": "/home/avnyr/workspace/Simplon/brief-06-front/node_modules/typescript/lib",
|
"ts.external.directory.path": "/home/avnyr/monoliths/Simplon/brief-06-front/node_modules/typescript/lib",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RunManager">
|
<component name="RunManager">
|
||||||
<configuration name="dev" type="js.build_tools.npm" nameIsGenerated="true">
|
<configuration name="dev" type="js.build_tools.npm" nameIsGenerated="true">
|
||||||
<package-json value="$PROJECT_DIR$/package.json" />
|
<package-json value="$PROJECT_DIR$/package.json" />
|
||||||
@ -83,6 +91,7 @@
|
|||||||
<updated>1715776265663</updated>
|
<updated>1715776265663</updated>
|
||||||
<workItem from="1715776267209" duration="3260000" />
|
<workItem from="1715776267209" duration="3260000" />
|
||||||
<workItem from="1715781823049" duration="3317000" />
|
<workItem from="1715781823049" duration="3317000" />
|
||||||
|
<workItem from="1715794057604" duration="8757000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
@ -12,9 +12,11 @@
|
|||||||
"@fontsource-variable/kode-mono": "^5.0.3",
|
"@fontsource-variable/kode-mono": "^5.0.3",
|
||||||
"@fontsource/ubuntu": "^5.0.13",
|
"@fontsource/ubuntu": "^5.0.13",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
"@radix-ui/react-dropdown-menu": "^2.0.6",
|
||||||
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
"@radix-ui/react-toast": "^1.1.5",
|
"@radix-ui/react-toast": "^1.1.5",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7",
|
"@radix-ui/react-tooltip": "^1.0.7",
|
||||||
|
"@tailwindcss/forms": "^0.5.7",
|
||||||
"class-variance-authority": "^0.7.0",
|
"class-variance-authority": "^0.7.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"framer-motion": "^11.2.0",
|
"framer-motion": "^11.2.0",
|
||||||
|
2093
pnpm-lock.yaml
generated
2093
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
12
src/app/account/login/page.tsx
Normal file
12
src/app/account/login/page.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {Button} from "@/components/ui/button";
|
||||||
|
import {KeyRound, Rss, UserRoundPlus} from "lucide-react";
|
||||||
|
import {LoginForm} from "@/components/login-form";
|
||||||
|
|
||||||
|
export default function LoginPage() {
|
||||||
|
return (
|
||||||
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full">
|
||||||
|
<LoginForm/>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
19
src/app/account/page.tsx
Normal file
19
src/app/account/page.tsx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {Button} from "@/components/ui/button";
|
||||||
|
import {KeyRound, Rss, UserRoundPlus} from "lucide-react";
|
||||||
|
|
||||||
|
export default function AccountPage() {
|
||||||
|
return (
|
||||||
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full">
|
||||||
|
<section className={"flex flex-col justify-evenly items-center md:h-1/3 mt-4 p-2 w-full h-full gap-1"}>
|
||||||
|
<h1 className={"text-4xl md:text-6xl font-bold"}>Only<em className={"text-primary opacity-65"}>Devs</em></h1>
|
||||||
|
<h2 className={"text-xl md:text-3xl text-center mt-1"}>A social network for you the <em className={"text-primary opacity-65"}>nerdy</em> developer !</h2>
|
||||||
|
<div className={"flex flex-col md:flex-row justify-evenly max-w-64 w-full md:max-w-full mt-2 gap-1"}>
|
||||||
|
<Button className={"mt-3 md:scale-125 gap-2 bg-purple-600"}><KeyRound />Login</Button>
|
||||||
|
<Button className={"mt-3 md:scale-125 gap-2 bg-purple-800"}><UserRoundPlus />Register</Button>
|
||||||
|
<Button className={"mt-3 md:scale-125 gap-2"}><Rss />Go see the posts</Button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
11
src/app/account/register/page.tsx
Normal file
11
src/app/account/register/page.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {Button} from "@/components/ui/button";
|
||||||
|
import {RegisterForm} from "@/components/register-form";
|
||||||
|
|
||||||
|
export default function RegisterPage() {
|
||||||
|
return (
|
||||||
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full">
|
||||||
|
<RegisterForm/>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
@ -4,6 +4,8 @@ import "./globals.css";
|
|||||||
import {ThemeProvider} from "@/components/theme-provider";
|
import {ThemeProvider} from "@/components/theme-provider";
|
||||||
import {ToastProvider} from "@/components/ui/toast";
|
import {ToastProvider} from "@/components/ui/toast";
|
||||||
import Header from "@/components/header";
|
import Header from "@/components/header";
|
||||||
|
import {BackgroundBeams} from "@/components/ui/background-beams";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
@ -18,7 +20,7 @@ export default function RootLayout({
|
|||||||
}>) {
|
}>) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body className={"flex flex-col justify-center items-center"}>
|
<body className={"flex flex-col justify-center items-center relative"}>
|
||||||
<ThemeProvider
|
<ThemeProvider
|
||||||
attribute="class"
|
attribute="class"
|
||||||
defaultTheme="system"
|
defaultTheme="system"
|
||||||
@ -29,6 +31,7 @@ export default function RootLayout({
|
|||||||
{children}
|
{children}
|
||||||
<ToastProvider/>
|
<ToastProvider/>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
<BackgroundBeams className={"-z-10 w-full h-full fixed"}/>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
import Image from "next/image";
|
|
||||||
import {BackgroundBeams} from "@/components/ui/background-beams";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {Button} from "@/components/ui/button";
|
import {Button} from "@/components/ui/button";
|
||||||
import {KeyRound, Rss, UserRoundPlus} from "lucide-react";
|
import {KeyRound, Rss, UserRoundPlus} from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
<main className="flex flex-col justify-center items-center antialiased h-full">
|
<main className="flex flex-col justify-evenly items-center antialiased h-full w-full">
|
||||||
<section className={"flex flex-col justify-center items-center md:h-1/3 mt-4 p-2 w-full gap-1"}>
|
<section className={"flex flex-col justify-evenly items-center md:h-1/3 mt-4 p-2 w-full h-full gap-1"}>
|
||||||
<h1 className={"text-4xl md:text-6xl font-bold"}>Only<em className={"text-primary"}>Devs</em></h1>
|
<h1 className={"text-4xl md:text-6xl font-bold"}>Only<em className={"text-primary opacity-65"}>Devs</em></h1>
|
||||||
<h2 className={"text-xl md:text-3xl text-center"}>A social network for you the nerdy developer !</h2>
|
<h2 className={"text-xl md:text-3xl text-center mt-1"}>A social network for you the <em className={"text-primary opacity-65"}>nerdy</em> developer !</h2>
|
||||||
<div className={"flex flex-col md:flex-row justify-evenly w-full"}>
|
<div className={"flex flex-col md:flex-row justify-evenly max-w-64 w-full md:max-w-full mt-2 gap-1"}>
|
||||||
<Button className={"mt-3 md:scale-125 gap-2"}><KeyRound />Login</Button>
|
<Button className={"mt-3 md:scale-125 bg-purple-600"} asChild><Link href={"/account/login"} className={"flex flex-row gap-2"}><KeyRound />Login</Link></Button>
|
||||||
<Button className={"mt-3 md:scale-125 gap-2"}><UserRoundPlus />Register</Button>
|
<Button className={"mt-3 md:scale-125 gap-2 bg-purple-800"} asChild><Link href={"/account/register"}><UserRoundPlus />Register</Link></Button>
|
||||||
<Button className={"mt-3 md:scale-125 gap-2"}><Rss />Go see the posts</Button>
|
<Button className={"mt-3 md:scale-125 gap-2"} asChild><Link href={"/threads"}><Rss />Go see the posts</Link></Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<BackgroundBeams className={"-z-10"}/>
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,12 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Button} from "@/components/ui/button";
|
import {Button} from "@/components/ui/button";
|
||||||
import {ThemeSelector} from "@/components/theme-selector";
|
import {ThemeSelector} from "@/components/theme-selector";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
return (
|
return (
|
||||||
<header className="flex flex-row justify-between items-center p-2 w-full z-50">
|
<header className="flex flex-row justify-between items-center p-2 w-full z-50">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h1 className={"text-2xl font-bold"}>Only<em className={"text-primary"}>Devs</em></h1>
|
<Link href={"/"}><h1 className={"text-2xl font-bold"}>Only<em className={"text-primary"}>Devs</em></h1></Link>
|
||||||
</div>
|
</div>
|
||||||
<ThemeSelector/>
|
<ThemeSelector/>
|
||||||
</header>
|
</header>
|
||||||
|
99
src/components/login-form.tsx
Normal file
99
src/components/login-form.tsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import {Label} from "@/components/ui/label";
|
||||||
|
import {Input} from "@/components/ui/input";
|
||||||
|
import {cn} from "@/lib/utils";
|
||||||
|
import {User} from "lucide-react";
|
||||||
|
|
||||||
|
export function LoginForm() {
|
||||||
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log("Form submitted");
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="max-w-md w-full mx-auto rounded-none md:rounded-2xl p-4 md:p-8 shadow-input">
|
||||||
|
<h2 className="font-bold text-xl text-neutral-800 dark:text-neutral-200">
|
||||||
|
Welcome to OnlyDevs
|
||||||
|
</h2>
|
||||||
|
<p className="text-neutral-600 text-sm max-w-sm mt-2 dark:text-neutral-300">
|
||||||
|
Login to aceternity if you can because we don't have a login flow
|
||||||
|
yet
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form className="my-8" onSubmit={handleSubmit}>
|
||||||
|
<div className="flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-2 mb-4">
|
||||||
|
<LabelInputContainer>
|
||||||
|
<Label htmlFor="firstname">First name</Label>
|
||||||
|
<Input id="firstname" placeholder="John" type="text" />
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer>
|
||||||
|
<Label htmlFor="lastname">Last name</Label>
|
||||||
|
<Input id="lastname" placeholder="Doe" type="text" />
|
||||||
|
</LabelInputContainer>
|
||||||
|
</div>
|
||||||
|
<LabelInputContainer className="mb-4">
|
||||||
|
<Label htmlFor="email">Email Address</Label>
|
||||||
|
<Input id="email" placeholder="projectmayhem@fc.com" type="email" />
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer className="mb-4">
|
||||||
|
<Label htmlFor="password">Password</Label>
|
||||||
|
<Input id="password" placeholder="••••••••" type="password" />
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer className="mb-8">
|
||||||
|
<Label htmlFor="twitterpassword">Your twitter password</Label>
|
||||||
|
<Input
|
||||||
|
id="twitterpassword"
|
||||||
|
placeholder="••••••••"
|
||||||
|
type="twitterpassword"
|
||||||
|
/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="bg-gradient-to-br relative group/btn from-black dark:from-zinc-900 dark:to-zinc-900 to-neutral-600 block dark:bg-zinc-800 w-full text-white rounded-md h-10 font-medium shadow-[0px_1px_0px_0px_#ffffff40_inset,0px_-1px_0px_0px_#ffffff40_inset] dark:shadow-[0px_1px_0px_0px_var(--zinc-800)_inset,0px_-1px_0px_0px_var(--zinc-800)_inset]"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
Sign up →
|
||||||
|
<BottomGradient />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="bg-gradient-to-r from-transparent via-neutral-300 dark:via-neutral-700 to-transparent my-8 h-[1px] w-full" />
|
||||||
|
|
||||||
|
<div className="flex flex-col space-y-4">
|
||||||
|
<button
|
||||||
|
className=" relative group/btn flex space-x-2 items-center justify-start px-4 w-full text-black rounded-md h-10 font-medium shadow-input bg-gray-50 dark:bg-zinc-900 dark:shadow-[0px_0px_1px_1px_var(--neutral-800)]"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<User className="h-4 w-4 text-neutral-800 dark:text-neutral-300" />
|
||||||
|
<span className="text-neutral-700 dark:text-neutral-300 text-sm">
|
||||||
|
OnlyFans
|
||||||
|
</span>
|
||||||
|
<BottomGradient />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const BottomGradient = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span className="group-hover/btn:opacity-100 block transition duration-500 opacity-0 absolute h-px w-full -bottom-px inset-x-0 bg-gradient-to-r from-transparent via-cyan-500 to-transparent" />
|
||||||
|
<span className="group-hover/btn:opacity-100 blur-sm block transition duration-500 opacity-0 absolute h-px w-1/2 mx-auto -bottom-px inset-x-10 bg-gradient-to-r from-transparent via-indigo-500 to-transparent" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const LabelInputContainer = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className={cn("flex flex-col space-y-2 w-full", className)}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
94
src/components/register-form.tsx
Normal file
94
src/components/register-form.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
"use client";
|
||||||
|
import React from "react";
|
||||||
|
import {Label} from "@/components/ui/label";
|
||||||
|
import {Input} from "@/components/ui/input";
|
||||||
|
import {cn} from "@/lib/utils";
|
||||||
|
import {User} from "lucide-react";
|
||||||
|
|
||||||
|
export function RegisterForm() {
|
||||||
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log("Form submitted");
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="max-w-md w-full mx-auto rounded-none md:rounded-2xl p-4 md:p-8 shadow-input">
|
||||||
|
<h2 className="font-bold text-xl text-neutral-800 dark:text-neutral-200">
|
||||||
|
Create an account
|
||||||
|
</h2>
|
||||||
|
<p className="text-neutral-600 text-sm max-w-sm mt-2 dark:text-neutral-300">
|
||||||
|
By creating an account you can discuss on our platform.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form className="my-8" onSubmit={handleSubmit}>
|
||||||
|
<div className="flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-2 mb-4">
|
||||||
|
<LabelInputContainer>
|
||||||
|
<Label htmlFor="firstname">First name</Label>
|
||||||
|
<Input id="firstname" placeholder="John" type="text"/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer>
|
||||||
|
<Label htmlFor="lastname">Last name</Label>
|
||||||
|
<Input id="lastname" placeholder="Doe" type="text"/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
</div>
|
||||||
|
<LabelInputContainer className="mb-4">
|
||||||
|
<Label htmlFor="email">Email Address</Label>
|
||||||
|
<Input id="email" placeholder="john.doe@foo.bar" type="email"/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
<div
|
||||||
|
className="bg-gradient-to-r from-transparent via-neutral-300 dark:via-neutral-700 to-transparent my-8 h-[1px] w-full"/>
|
||||||
|
<LabelInputContainer className="mb-4">
|
||||||
|
<Label htmlFor="username">Username</Label>
|
||||||
|
<Input id="username" placeholder="john.doe68" type="text"/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer className="mb-4">
|
||||||
|
<Label htmlFor="displayName">Displayname</Label>
|
||||||
|
<Input id="displayName" placeholder="Johny" type="text"/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer className="mb-4">
|
||||||
|
<Label htmlFor="password">Password</Label>
|
||||||
|
<Input id="password" placeholder="••••••••" type="password"/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
<LabelInputContainer className="mb-8">
|
||||||
|
<Label htmlFor="re-password">Re-type password</Label>
|
||||||
|
<Input
|
||||||
|
id="re-password"
|
||||||
|
placeholder="••••••••"
|
||||||
|
type="password"
|
||||||
|
/>
|
||||||
|
</LabelInputContainer>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="bg-gradient-to-br relative group/btn from-black dark:from-zinc-900 dark:to-zinc-900 to-neutral-600 block dark:bg-zinc-800 w-full text-white rounded-md h-10 font-medium shadow-[0px_1px_0px_0px_#ffffff40_inset,0px_-1px_0px_0px_#ffffff40_inset] dark:shadow-[0px_1px_0px_0px_var(--zinc-800)_inset,0px_-1px_0px_0px_var(--zinc-800)_inset]"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
Register →
|
||||||
|
<BottomGradient/>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const BottomGradient = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span
|
||||||
|
className="group-hover/btn:opacity-100 block transition duration-500 opacity-0 absolute h-px w-full -bottom-px inset-x-0 bg-gradient-to-r from-transparent via-cyan-500 to-transparent" />
|
||||||
|
<span className="group-hover/btn:opacity-100 blur-sm block transition duration-500 opacity-0 absolute h-px w-1/2 mx-auto -bottom-px inset-x-10 bg-gradient-to-r from-transparent via-indigo-500 to-transparent" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const LabelInputContainer = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className={cn("flex flex-col space-y-2 w-full", className)}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -20,14 +20,14 @@ export function ThemeSelector() {
|
|||||||
//TODO i18n
|
//TODO i18n
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild className={""}>
|
||||||
<Button variant="outline" size="icon">
|
<Button variant="outline" size="icon">
|
||||||
<Sun className="h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:-rotate-90 dark:scale-100 text-primary animate-in" />
|
<Sun className="h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:-rotate-90 dark:scale-100 text-primary animate-in" />
|
||||||
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:rotate-0 dark:scale-0 text-primary animate-in" />
|
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:rotate-0 dark:scale-0 text-primary animate-in" />
|
||||||
<span className="sr-only">Toggle theme</span>
|
<span className="sr-only">Toggle theme</span>
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="flex flex-col m-2">
|
<DropdownMenuContent className="flex flex-col m-2 z-50">
|
||||||
<DropdownMenuLabel>Theme de couleur</DropdownMenuLabel>
|
<DropdownMenuLabel>Theme de couleur</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuGroup>
|
<DropdownMenuGroup>
|
||||||
|
25
src/components/ui/input.tsx
Normal file
25
src/components/ui/input.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
export interface InputProps
|
||||||
|
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||||
|
|
||||||
|
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||||
|
({ className, type, ...props }, ref) => {
|
||||||
|
return (
|
||||||
|
<input
|
||||||
|
type={type}
|
||||||
|
className={cn(
|
||||||
|
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
ref={ref}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Input.displayName = "Input"
|
||||||
|
|
||||||
|
export { Input }
|
26
src/components/ui/label.tsx
Normal file
26
src/components/ui/label.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const labelVariants = cva(
|
||||||
|
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Label = React.forwardRef<
|
||||||
|
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
||||||
|
VariantProps<typeof labelVariants>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<LabelPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(labelVariants(), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Label.displayName = LabelPrimitive.Root.displayName
|
||||||
|
|
||||||
|
export { Label }
|
Loading…
x
Reference in New Issue
Block a user