feat: make forms functional

This commit is contained in:
Stavros
2025-05-08 18:08:56 +03:00
parent fd96f39d3a
commit 56ae246ff4
18 changed files with 870 additions and 3387 deletions

View File

@@ -1,8 +1,8 @@
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
@@ -55,7 +55,7 @@ export const ContinuePage = () => {
/>
</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-2 items-stretch">
<CardFooter className="flex flex-col items-stretch gap-2">
<Button
onClick={() => window.location.replace(redirectURI)}
variant="destructive"
@@ -65,7 +65,7 @@ export const ContinuePage = () => {
<Button onClick={() => navigate("/")} variant="outline">
{t("cancelTitle")}
</Button>
</CardContent>
</CardFooter>
</Card>
);
}
@@ -89,7 +89,7 @@ export const ContinuePage = () => {
/>
</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-2 items-stretch">
<CardFooter className="flex flex-col items-stretch gap-2">
<Button
onClick={() => window.location.replace(redirectURI)}
variant="warning"
@@ -99,7 +99,7 @@ export const ContinuePage = () => {
<Button onClick={() => navigate("/")} variant="outline">
{t("cancelTitle")}
</Button>
</CardContent>
</CardFooter>
</Card>
);
}
@@ -110,11 +110,11 @@ export const ContinuePage = () => {
<CardTitle className="text-3xl">{t("continueTitle")}</CardTitle>
<CardDescription>{t("continueSubtitle")}</CardDescription>
</CardHeader>
<CardContent className="flex flex-col items-stretch">
<CardFooter className="flex flex-col items-stretch">
<Button onClick={() => window.location.replace(redirectURI)}>
{t("continueTitle")}
</Button>
</CardContent>
</CardFooter>
</Card>
);
};

View File

@@ -0,0 +1,26 @@
import {
Card,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { useTranslation } from "react-i18next";
import Markdown from "react-markdown";
export const ForgotPasswordPage = () => {
const { t } = useTranslation();
return (
<Card className="min-w-xs md:max-w-sm">
<CardHeader>
<CardTitle className="text-3xl">{t("forgotPasswordTitle")}</CardTitle>
<CardDescription>
<Markdown>
You can reset your password by changing the `USERS` environment
variable.
</Markdown>
</CardDescription>
</CardHeader>
</Card>
);
};

View File

@@ -1,8 +1,7 @@
import { OAuthButton } from "@/components/auth/oauth-button";
import { LoginForm } from "@/components/auth/login-form";
import { GenericIcon } from "@/components/icons/generic";
import { GithubIcon } from "@/components/icons/github";
import { GoogleIcon } from "@/components/icons/google";
import { Button } from "@/components/ui/button";
import {
Card,
CardHeader,
@@ -10,9 +9,8 @@ import {
CardDescription,
CardContent,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";
import { OAuthButton } from "@/components/ui/oauth-button";
import { SeperatorWithChildren } from "@/components/ui/separator";
import { useTranslation } from "react-i18next";
export const LoginPage = () => {
@@ -35,9 +33,9 @@ export const LoginPage = () => {
</CardDescription>
)}
</CardHeader>
<CardContent className="flex flex-col gap-4">
<CardContent className="flex flex-col gap-5">
{oauthConfigured && (
<div className="flex flex-row gap-3 flex-wrap items-center justify-center">
<div className="flex flex-row flex-wrap gap-3 items-center justify-center">
{configuredProviders.includes("google") && (
<OAuthButton title="Google" icon={<GoogleIcon />} />
)}
@@ -50,45 +48,9 @@ export const LoginPage = () => {
</div>
)}
{userAuthConfigured && oauthConfigured && (
<div className="flex items-center gap-4">
<Separator className="flex-1" />
<span className="text-sm text-muted-foreground">
{t("loginDivider")}
</span>
<Separator className="flex-1" />
</div>
)}
{userAuthConfigured && (
<div className="flex flex-col gap-4">
<div>
<Label htmlFor="#username">{t("loginUsername")}</Label>
<Input
id="username"
placeholder={t("loginUsername")}
className="mt-2"
/>
</div>
<div>
<Label htmlFor="#password">
<div className="flex flex-row min-w-full items-center justify-between">
<span>{t("loginPassword")}</span>
<a
href="/forgot"
className="text-muted-foreground font-normal"
>
{t("forgotPasswordTitle")}
</a>
</div>
</Label>
<Input
id="password"
placeholder={t("loginPassword")}
className="mt-2"
/>
</div>
<Button>{t("loginSubmit")}</Button>
</div>
<SeperatorWithChildren>{t("loginDivider")}</SeperatorWithChildren>
)}
{userAuthConfigured && <LoginForm />}
{configuredProviders.length == 0 && (
<h3 className="text-center text-xl text-red-600">
{t("failedToFetchProvidersTitle")}

View File

@@ -1,8 +1,8 @@
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
@@ -19,9 +19,9 @@ export const NotFoundPage = () => {
<CardTitle className="text-3xl">{t("notFoundTitle")}</CardTitle>
<CardDescription>{t("notFoundSubtitle")}</CardDescription>
</CardHeader>
<CardContent className="flex flex-col items-stretch">
<CardFooter className="flex flex-col items-stretch">
<Button onClick={() => navigate("/")}>{t("notFoundButton")}</Button>
</CardContent>
</CardFooter>
</Card>
);
};

View File

@@ -1,21 +1,23 @@
import { FormValues, TotpForm } from "@/components/auth/totp-form";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
InputOTP,
InputOTPGroup,
InputOTPSeparator,
InputOTPSlot,
} from "@/components/ui/input-otp";
import { useId } from "react";
import { useTranslation } from "react-i18next";
export const TotpPage = () => {
const { t } = useTranslation();
const formId = useId();
const onSubmit = (data: FormValues) => {
console.log("TOTP data:", data);
};
return (
<Card className="min-w-xs md:max-w-sm">
@@ -23,22 +25,14 @@ export const TotpPage = () => {
<CardTitle className="text-3xl">{t("totpTitle")}</CardTitle>
<CardDescription>{t("totpSubtitle")}</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-6 items-stretch">
<InputOTP maxLength={6}>
<InputOTPGroup>
<InputOTPSlot index={0} />
<InputOTPSlot index={1} />
<InputOTPSlot index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot index={3} />
<InputOTPSlot index={4} />
<InputOTPSlot index={5} />
</InputOTPGroup>
</InputOTP>
<Button>{t("continueTitle")}</Button>
<CardContent className="flex flex-col items-center">
<TotpForm formId={formId} onSubmit={onSubmit} />
</CardContent>
<CardFooter className="flex flex-col items-stretch">
<Button form={formId} type="submit">
{t("continueTitle")}
</Button>
</CardFooter>
</Card>
);
};