Files
stripstream/src/components/auth/LoginForm.tsx
Froidefond Julien 7e4c48469a feat: enhance Stripstream configuration handling
- Introduced a new resolver function to streamline fetching Stripstream configuration from the database or environment variables.
- Updated various components and API routes to utilize the new configuration resolver, improving code maintainability and reducing direct database calls.
- Added optional environment variables for Stripstream URL and token in the .env.example file.
- Refactored image loading logic in the reader components to improve performance and error handling.
2026-03-11 21:25:58 +01:00

107 lines
3.1 KiB
TypeScript

"use client";
import { useState } from "react";
import { signIn } from "next-auth/react";
import { ErrorMessage } from "@/components/ui/ErrorMessage";
import { useTranslate } from "@/hooks/useTranslate";
import type { AppErrorType } from "@/types/global";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
interface LoginFormProps {
from?: string;
}
export function LoginForm({ from }: LoginFormProps) {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<AppErrorType | null>(null);
const { t } = useTranslate();
const getSafeRedirectPath = (path?: string) => {
if (!path || !path.startsWith("/") || path.startsWith("//")) {
return "/";
}
return path;
};
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setIsLoading(true);
setError(null);
const formData = new FormData(event.currentTarget);
const email = formData.get("email") as string;
const password = formData.get("password") as string;
const remember = formData.get("remember") === "on";
try {
const result = await signIn("credentials", {
email,
password,
remember,
redirect: false,
});
if (!result || result.error || !result.ok) {
setError({
code: "AUTH_INVALID_CREDENTIALS",
name: "Login failed",
message: "Email ou mot de passe incorrect",
});
return;
}
const redirectPath = getSafeRedirectPath(from);
window.location.href = redirectPath;
} catch {
setError({
code: "AUTH_FETCH_ERROR",
name: "Login error",
message: "Une erreur est survenue lors de la connexion",
});
} finally {
setIsLoading(false);
}
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">{t("login.form.email")}</Label>
<Input
id="email"
name="email"
type="email"
autoComplete="email"
required
defaultValue="demo@stripstream.local"
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">{t("login.form.password")}</Label>
<Input
id="password"
name="password"
type="password"
autoComplete="current-password"
required
defaultValue="fft$VSD96dis"
/>
</div>
<div className="flex items-center space-x-2">
<Checkbox id="remember" name="remember" defaultChecked />
<Label htmlFor="remember" className="cursor-pointer">
{t("login.form.remember")}
</Label>
</div>
{error && <ErrorMessage errorCode={error.code} variant="form" />}
<Button type="submit" disabled={isLoading} className="w-full">
{isLoading ? t("login.form.submit.loading.login") : t("login.form.submit.login")}
</Button>
</form>
);
}