Ajout puzzles & composants

This commit is contained in:
Théo 2023-02-04 22:54:51 +01:00
parent 1fb8420786
commit 7a368bebe2
9 changed files with 109 additions and 10 deletions

View file

@ -3,9 +3,9 @@ import { type ReactNode } from 'react';
export default function Layout({ children }: { children: ReactNode }) {
return (
<div className="pl-60">
<div className="mx-4 min-h-screen md:pl-60 xl:mx-0">
<Sidenav />
<div className="mx-auto max-w-5xl">{children}</div>
<div className="mx-auto h-screen max-w-5xl py-8">{children}</div>
</div>
);
}

File diff suppressed because one or more lines are too long

View file

@ -5,7 +5,7 @@ import { type ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="fr" dir="ltr" className={cn('[color-scheme:dark] scroll-smooth bg-light-dark')}>
<html lang="fr" dir="ltr" className={cn('scroll-smooth bg-light-dark [color-scheme:dark]')}>
<head />
<body className="relative min-h-screen">
<main>{children}</main>

3
ui/ErrorMessage.tsx Normal file
View file

@ -0,0 +1,3 @@
export default function ErrorMessage({ children }: { children: React.ReactNode }) {
return <p className="text-xs text-orange-500">{children}</p>;
}

27
ui/Input.tsx Normal file
View file

@ -0,0 +1,27 @@
import { forwardRef } from 'react';
import ErrorMessage from './ErrorMessage';
import Label from './Label';
const Input = forwardRef<
HTMLInputElement,
React.InputHTMLAttributes<HTMLInputElement> & {
label: React.ReactNode;
error?: React.ReactNode;
description?: React.ReactNode;
}
>(({ className, label, description, error, ...props }, ref) => (
<>
<Label label={label} description={description} required={props.required} className={className}>
<input
ref={ref}
className="w-full rounded-lg border-0 bg-[#424242] px-5 py-2.5 text-sm font-medium outline-none transition-colors hover:border-gray-400 focus:outline-none focus:ring-0 disabled:opacity-50"
{...props}
/>
</Label>
{error && <ErrorMessage>{error}</ErrorMessage>}
</>
));
Input.displayName = 'Input';
export default Input;

26
ui/Label.tsx Normal file
View file

@ -0,0 +1,26 @@
import { cn } from '@/lib/utils';
export default function Label({
label,
description,
className,
required,
children
}: {
className?: string;
label: React.ReactNode;
description?: React.ReactNode;
required?: boolean;
children: React.ReactNode;
}) {
return (
<label className={cn('flex flex-col gap-1 text-left', className)}>
<span className="text-sm">
{label}
{required && <span className="ml-1 text-orange-600">*</span>}
</span>
{description && <span className="text-xs text-gray-500">{description}</span>}
{children}
</label>
);
}

23
ui/Tips.tsx Normal file
View file

@ -0,0 +1,23 @@
import { cn } from '@/lib/utils';
interface TipsProps {
className?: string;
kind?: 'success' | 'error' | 'warning' | 'info';
text: string;
}
export default function Tips({ className, kind = 'info', text }: TipsProps) {
return (
<div
className={cn('w-full rounded-md ', {
'bg-green-500': kind === 'success',
'bg-red-500': kind === 'error',
'bg-yellow-500': kind === 'warning',
'bg-blue-500': kind === 'info',
className
})}
>
<p className="py-2 px-4">{text}</p>
</div>
);
}

12
ui/ToHTML.tsx Normal file
View file

@ -0,0 +1,12 @@
import { cn } from '@/lib/utils';
interface ToHTMLProps {
html: string;
className?: string;
}
export default function ToHTML({ html, className }: ToHTMLProps) {
return (
<div className={cn('select-none', className)} dangerouslySetInnerHTML={{ __html: html }} />
);
}

View file

@ -7,7 +7,7 @@ import AppLink from '../AppLink';
export default function Sidenav() {
return (
<div className="fixed top-0 left-0 h-full w-60 space-y-4 bg-dark shadow-md">
<div className="fixed top-0 left-0 hidden h-full w-60 space-y-4 bg-dark shadow-md md:block">
<div className="px-6 pt-4">
<div className="flex items-center">
<div className="mx-auto">