160 lines
3.6 KiB
TypeScript
160 lines
3.6 KiB
TypeScript
import React from "react";
|
|
import { cn } from "~/lib/utils";
|
|
|
|
|
|
interface LoginLayoutProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoginLayout({ children, className }: LoginLayoutProps) {
|
|
return (
|
|
<div className={cn("min-h-screen flex", className)} dir="ltr">
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface LoginContentProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoginContent({ children, className }: LoginContentProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"flex-1 flex items-center justify-center p-4 sm:p-8",
|
|
className,
|
|
)}
|
|
style={{
|
|
background:
|
|
"linear-gradient(135deg, var(--color-login-dark-start) 0%, var(--color-login-dark-end) 100%)",
|
|
}}
|
|
>
|
|
<div className="w-full max-w-md space-y-8">{children}</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface LoginSidebarProps {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoginSidebar({ children, className }: LoginSidebarProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"hidden lg:flex lg:w-2/5 relative overflow-hidden",
|
|
className,
|
|
)}
|
|
style={{
|
|
backgroundColor: "var(--color-login-primary)",
|
|
}}
|
|
>
|
|
<div className="absolute inset-0 flex flex-col justify-between p-8">
|
|
{children}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface LoginHeaderProps {
|
|
title: string;
|
|
subtitle: string;
|
|
description?: string;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoginHeader({
|
|
title,
|
|
subtitle,
|
|
description,
|
|
className,
|
|
}: LoginHeaderProps) {
|
|
return (
|
|
<div className={cn(" space-y-4 flex text-right flex-col", className)}>
|
|
<div className="space-y-2">
|
|
<h1 className="text-white text-base font-medium font-persian">{title}</h1>
|
|
<h2 className="text-white text-3xl sm:text-3xl font-bold font-persian leading-relaxed">
|
|
{subtitle}
|
|
</h2>
|
|
{description && (
|
|
<p className="text-slate-300 text-sm text-[#ACACAC] font-persian leading-relaxed mx-auto">
|
|
{description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
interface LoginBrandingProps {
|
|
brandName: string;
|
|
companyName: string;
|
|
logo?: React.ReactNode;
|
|
className?: string;
|
|
engSub ?: string;
|
|
}
|
|
|
|
export function LoginBranding({
|
|
brandName,
|
|
companyName,
|
|
logo,
|
|
className,
|
|
engSub
|
|
}: LoginBrandingProps) {
|
|
return (
|
|
<>
|
|
<div className="flex justify-end">
|
|
<div className="text-slate-800 font-persian">
|
|
<div className="text-lg font-bold leading-tight">
|
|
<img
|
|
src="/brand.svg?v=1"
|
|
alt="Brand Logo"
|
|
className="w-auto h-16" // اضافه کردن سایز مشخص
|
|
onError={(e) => {
|
|
e.target.style.display = 'none';
|
|
console.log('Image failed to load');
|
|
}}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Bottom Section */}
|
|
<div className="flex flex-col gap-2 mb-4 items-end justify-end">
|
|
{logo && <div className="flex items-center">{logo}</div>}
|
|
<h3 className="text-[#3F415A] text-sm font-persian font-light leading-relaxed max-w-xs">{engSub}</h3>
|
|
<div className="text-[#3F415A] text-sm font-persian leading-relaxed font-light max-w-xs">
|
|
{companyName}
|
|
</div>
|
|
{/* Logo */}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
interface LoginFormContainerProps {
|
|
children: React.ReactNode;
|
|
onSubmit: (e: React.FormEvent) => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function LoginFormContainer({
|
|
children,
|
|
onSubmit,
|
|
className,
|
|
}: LoginFormContainerProps) {
|
|
return (
|
|
<form onSubmit={onSubmit} className={cn("space-y-6", className)}>
|
|
{children}
|
|
</form>
|
|
);
|
|
}
|