convert setting modals + associate function

This commit is contained in:
p2405951
2026-01-30 16:35:48 +01:00
parent 62a88dab83
commit 2389ca88e4
19 changed files with 670 additions and 294 deletions
-16
View File
@@ -1,16 +0,0 @@
import styles from "./button.module.css";
const Button = ({ children, variant = "primary", onClick, className }) => {
let btnStyle;
if (variant === "primary") btnStyle = styles.primary;
else if (variant === "danger") btnStyle = styles.danger;
else if(variant === "transparent") btnStyle = styles.transparent;
else btnStyle = styles.default;
return <div className={`${styles.btn} ${btnStyle} ${className}`} onClick={onClick}>
{children}
</div>;
};
export default Button;
+53
View File
@@ -0,0 +1,53 @@
/*import styles from "./button.module.css";
const Button = ({ children, variant = "primary", onClick, className }) => {
let btnStyle;
if (variant === "primary") btnStyle = styles.primary;
else if (variant === "danger") btnStyle = styles.danger;
else if(variant === "transparent") btnStyle = styles.transparent;
else btnStyle = styles.default;
return <div className={`${styles.btn} ${btnStyle} ${className}`} onClick={onClick}>
{children}
</div>;
};
export default Button;
*/
import styles from "./button.module.css";
import { ReactNode, MouseEvent } from "react";
interface ButtonProps {
children: ReactNode;
variant?: "primary" | "danger" | "transparent" | "default";
onClick?: (event: MouseEvent<HTMLDivElement>) => void;
className?: string;
}
const Button = ({
children,
variant = "primary",
onClick,
className = "",
}: ButtonProps) => {
const variantStyles = {
primary: styles.primary,
danger: styles.danger,
transparent: styles.transparent,
default: styles.default,
};
const btnStyle = variantStyles[variant in variantStyles ? variant : "default"];
return (
<div
className={`${styles.btn} ${btnStyle} ${className}`}
onClick={onClick}
>
{children}
</div>
);
};
export default Button;
-38
View File
@@ -1,38 +0,0 @@
import styles from "./input.module.css";
import { useState } from "react";
const TextInput = ({ placeholder, onChange, value, borderStyle, password, className, ...props }) => {
const [showPassword, setShowPassword] = useState(false);
let inputBorderStyle = styles.square;
if (borderStyle === "square") inputBorderStyle = styles.square;
if(borderStyle === "rounded") inputBorderStyle = styles.rounded;
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
if(password) return (
<div className={styles.passwordContainer}>
<TextInput
type={showPassword ? "text" : "password"}
value={value}
placeholder={placeholder}
onChange={onChange}
className={styles.passwordInput}
/>
<button
type="button"
onClick={toggleShowPassword}
className={styles.passwordBtn}
>
{showPassword ? '👁️' : '🔒'}
</button>
</div>
);
return <input className={`${styles.input} ${inputBorderStyle} ${className}`} onChange={onChange} placeholder={placeholder} value={value} {...props} />
};
export default TextInput;
+107
View File
@@ -0,0 +1,107 @@
/*import styles from "./input.module.css";
import { useState } from "react";
const TextInput = ({ placeholder, onChange, value, borderStyle, password, className, ...props }) => {
const [showPassword, setShowPassword] = useState(false);
let inputBorderStyle = styles.square;
if (borderStyle === "square") inputBorderStyle = styles.square;
if(borderStyle === "rounded") inputBorderStyle = styles.rounded;
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
if(password) return (
<div className={styles.passwordContainer}>
<TextInput
type={showPassword ? "text" : "password"}
value={value}
placeholder={placeholder}
onChange={onChange}
className={styles.passwordInput}
/>
<button
type="button"
onClick={toggleShowPassword}
className={styles.passwordBtn}
>
{showPassword ? '👁️' : '🔒'}
</button>
</div>
);
return <input className={`${styles.input} ${inputBorderStyle} ${className}`} onChange={onChange} placeholder={placeholder} value={value} {...props} />
};
export default TextInput;*/
import styles from "./input.module.css";
import { useState, InputHTMLAttributes, ChangeEvent } from "react";
interface TextInputProps extends InputHTMLAttributes<HTMLInputElement> {
placeholder?: string;
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
value: string;
borderStyle?: "square" | "rounded";
password?: boolean;
className?: string;
}
const TextInput = ({
placeholder,
onChange,
value,
borderStyle = "square",
password = false,
className = "",
...props
}: TextInputProps) => {
const [showPassword, setShowPassword] = useState(false);
const borderStyles = {
square: styles.square,
rounded: styles.rounded,
};
const inputBorderStyle = borderStyles[borderStyle] || styles.square;
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
if (password) {
return (
<div className={styles.passwordContainer}>
<input
type={showPassword ? "text" : "password"}
value={value}
placeholder={placeholder}
onChange={onChange}
className={`${styles.input} ${styles.passwordInput} ${inputBorderStyle} ${className}`}
{...props}
/>
<button
type="button"
onClick={toggleShowPassword}
className={styles.passwordBtn}
>
{showPassword ? "👁️" : "🔒"}
</button>
</div>
);
}
return (
<input
className={`${styles.input} ${inputBorderStyle} ${className}`}
onChange={onChange}
placeholder={placeholder}
value={value}
{...props}
/>
);
};
export default TextInput;
-31
View File
@@ -1,31 +0,0 @@
import { createPortal } from "react-dom";
import styles from "./modal.module.css";
import Button from "../button/button.jsx";
const Modal = ({ open, onClose, children, title }) => {
if (!open) return null;
const handleOverlayClick = () => {
onClose();
};
const handleModalClick = (e) => {
e.stopPropagation();
};
return createPortal(
<div className={styles.overlay} onClick={handleOverlayClick}>
<div className={styles.modal} onClick={handleModalClick}>
{title && <h2>{title}</h2>}
{children}
<div className={styles.modalFooter}>
<Button onClick={onClose}>Fermer</Button>
</div>
</div>
</div>,
document.body
);
};
export default Modal;
+71
View File
@@ -0,0 +1,71 @@
/*import { createPortal } from "react-dom";
import styles from "./modal.module.css";
import Button from "../button/button.jsx";
const Modal = ({ open, onClose, children, title }) => {
if (!open) return null;
const handleOverlayClick = () => {
onClose();
};
const handleModalClick = (e) => {
e.stopPropagation();
};
return createPortal(
<div className={styles.overlay} onClick={handleOverlayClick}>
<div className={styles.modal} onClick={handleModalClick}>
{title && <h2>{title}</h2>}
{children}
<div className={styles.modalFooter}>
<Button onClick={onClose}>Fermer</Button>
</div>
</div>
</div>,
document.body
);
};
export default Modal;*/
import { createPortal } from "react-dom";
import styles from "./modal.module.css";
import Button from "../button/button";
import { ReactNode, MouseEvent } from "react";
interface ModalProps {
open: boolean;
onClose: () => void;
children: ReactNode;
title?: string;
}
const Modal = ({ open, onClose, children, title }: ModalProps) => {
if (!open) return null;
const handleOverlayClick = () => {
onClose();
};
const handleModalClick = (e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
};
return createPortal(
<div className={styles.overlay} onClick={handleOverlayClick}>
<div className={styles.modal} onClick={handleModalClick}>
{title && <h2>{title}</h2>}
{children}
<div className={styles.modalFooter}>
<Button onClick={onClose}>Fermer</Button>
</div>
</div>
</div>,
document.body
);
};
export default Modal;
@@ -1,32 +0,0 @@
import Button from "../button/button.jsx";
import { useState, useEffect } from "react";
import styles from "./ThemeSwitcher.module.css";
export default function ThemeSwitcher() {
const [theme, setTheme] = useState("");
useEffect(() => {
const t = localStorage.getItem("theme");
if(t) setTheme(t);
else setTheme("light");
}, []);
const switchTheme = () => {
let newTheme = theme === "light" ? "dark" : "light";
if(theme === null || theme === "") newTheme = "dark";
localStorage.setItem("theme", newTheme);
setTheme(newTheme);
window.dispatchEvent(new Event("theme-changed"));
};
return <Button variant={"default"} onClick={switchTheme} className={styles.themeBtn}>
<img src={`/icons/theme/${theme}.svg`} alt={`${theme} icon`} className={styles.themeIcon} />
<p>Changer de thème </p>
</Button>
}
@@ -0,0 +1,73 @@
/*import Button from "../button/button.jsx";
import { useState, useEffect } from "react";
import styles from "./ThemeSwitcher.module.css";
export default function ThemeSwitcher() {
const [theme, setTheme] = useState("");
useEffect(() => {
const t = localStorage.getItem("theme");
if(t) setTheme(t);
else setTheme("light");
}, []);
const switchTheme = () => {
let newTheme = theme === "light" ? "dark" : "light";
if(theme === null || theme === "") newTheme = "dark";
localStorage.setItem("theme", newTheme);
setTheme(newTheme);
window.dispatchEvent(new Event("theme-changed"));
};
return <Button variant={"default"} onClick={switchTheme} className={styles.themeBtn}>
<img src={`/icons/theme/${theme}.svg`} alt={`${theme} icon`} className={styles.themeIcon} />
<p>Changer de thème </p>
</Button>
}*/
import Button from "../button/button";
import { useState, useEffect } from "react";
import styles from "./ThemeSwitcher.module.css";
type Theme = "light" | "dark";
export default function ThemeSwitcher() {
const [theme, setTheme] = useState<Theme | "">("");
useEffect(() => {
const savedTheme = localStorage.getItem("theme") as Theme | null;
if (savedTheme) {
setTheme(savedTheme);
} else {
setTheme("light");
}
}, []);
const switchTheme = () => {
const newTheme: Theme = theme === "light" ? "dark" : "light";
localStorage.setItem("theme", newTheme);
setTheme(newTheme);
window.dispatchEvent(new Event("theme-changed"));
};
return (
<Button
variant="default"
onClick={switchTheme}
className={styles.themeBtn}
>
<img
src={`/icons/theme/${theme}.svg`}
alt={`${theme} icon`}
className={styles.themeIcon}
/>
<p>Changer de thème</p>
</Button>
);
}