prettier code

This commit is contained in:
Romulus21
2025-10-31 20:48:27 +01:00
parent a94932059a
commit 76e99f574a
3 changed files with 2870 additions and 2665 deletions

View File

@@ -11,25 +11,25 @@
"generate-pwa-assets": "pwa-assets-generator"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"@vite-pwa/assets-generator": "^0.2.6",
"@vitejs/plugin-react-swc": "^3.7.1",
"autoprefixer": "^10.4.20",
"eslint": "^8.57.1",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.12",
"postcss": "^8.4.47",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/parser": "^8.46.0",
"@vite-pwa/assets-generator": "^1.0.0",
"@vitejs/plugin-react-swc": "^4.2.0",
"autoprefixer": "^10.4.21",
"eslint": "^9.0.0",
"eslint-plugin-react-hooks": "^7.0.0",
"eslint-plugin-react-refresh": "^0.4.24",
"postcss": "^8.5.6",
"rollup-plugin-copy": "^3.5.0",
"tailwindcss": "^3.4.13",
"typescript": "^5.6.2",
"vite": "^5.4.8",
"vite-plugin-pwa": "^0.17.5"
"tailwindcss": "^3.4.18",
"typescript": "^5.9.3",
"vite": "^7.0.0",
"vite-plugin-pwa": "^1.1.0"
}
}

5108
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,176 +1,251 @@
import {ChangeEvent, FormEvent, useEffect, useState} from "react";
import {useLocalStorage} from "./hooks/LocalStorageHooks.ts";
import {Birthday} from "./types.ts";
import {arrayRange, pad} from "./utilities.ts";
import { ChangeEvent, FormEvent, useEffect, useState } from "react";
import { useLocalStorage } from "./hooks/LocalStorageHooks.ts";
import { Birthday } from "./types.ts";
import { arrayRange, pad } from "./utilities.ts";
import BirthdayList from "./components/BirthdayList.tsx";
import {EditSVG, PlusSVG, TrashSVG} from "./components/SVG.tsx";
import cake from '../public/cake.svg'
import { EditSVG, PlusSVG, TrashSVG } from "./components/SVG.tsx";
import cake from "../public/cake.svg";
function App() {
const emptyAddForm: Birthday = {
id: 0,
name: "",
day: 1,
month: 1,
year: undefined,
birthday: "",
group: null,
};
const [addModal, setAddModal] = useState(false);
const [selectedPerson, setSelectedPerson] = useState<Birthday | null>(null);
const [addForm, setAddForm] = useState(emptyAddForm);
const [birthdays, setBirthdays] = useState<Birthday[]>([]);
const [data, setData] = useLocalStorage("birthdays-app-data", {
birthdays: [],
});
const emptyAddForm: Birthday = {id: 0, name: '', day: 1, month: 1, year: undefined, birthday: '', group: null}
const [addModal, setAddModal] = useState(false)
const [selectedPerson, setSelectedPerson] = useState<Birthday|null>(null)
const [addForm, setAddForm] = useState(emptyAddForm)
const [birthdays, setBirthdays] = useState<Birthday[]>([])
const [data, setData] = useLocalStorage('birthdays-app-data', {birthdays: []})
useEffect(() => {
setBirthdays(sortPersons(data.birthdays));
}, [data, data.birthdays]);
useEffect(() => {
setBirthdays(sortPersons(data.birthdays))
}, [data, data.birthdays])
const handleAddModal = () => {
if (selectedPerson) {
setAddForm(selectedPerson);
}
setAddModal(true);
};
const handleCloseModal = () => {
setAddModal(false);
setAddForm({ ...emptyAddForm, year: 0 });
setSelectedPerson(null);
};
const handleAddModal = () => {
if (selectedPerson) {
setAddForm(selectedPerson)
const sortPersons = (birthdays: Birthday[]) => {
birthdays = birthdays
.reduce((result: Birthday[], item: Birthday) => {
const birthday = `${new Date().getFullYear()}-${pad(item.month)}-${pad(item.day)}`;
item.birthday =
new Date().toISOString().split("T")[0] <= birthday
? birthday
: `${new Date().getFullYear() + 1}-${pad(item.month)}-${pad(item.day)}`;
result.push(item);
return result;
}, [])
.sort((a, b) => {
if (b.birthday < a.birthday) return 1;
if (b.birthday > a.birthday) return -1;
return 0;
});
return birthdays;
};
const handleChangeAddForm = (
event: ChangeEvent<HTMLInputElement | HTMLSelectElement>,
) => {
const value =
event.target.nodeName === "SELECT"
? Number(event.target.value)
: event.target.value;
setAddForm({ ...addForm, [event.target.name]: value });
};
const handleSubmitBirthday = (event: FormEvent) => {
event.preventDefault();
try {
if (
(!selectedPerson &&
birthdays.some((person: Birthday) => person.name === addForm.name)) ||
(selectedPerson && selectedPerson.id !== addForm.id)
) {
throw new Error("Une personne enregistré à déjà ce nom");
}
if (selectedPerson) {
const personIndex = data.birthdays.findIndex(
(p: Birthday) => p.id === selectedPerson.id,
);
if (personIndex >= 0) {
const newList = data.birthdays;
newList[personIndex] = addForm;
setData({ ...data, birthdays: newList });
} else {
throw new Error("Une personne non trouvé dans la liste");
}
setAddModal(true)
}
const handleCloseModal = () => {
setAddModal(false)
setAddForm({...emptyAddForm, year: 0})
setSelectedPerson(null)
}
const sortPersons = (birthdays: Birthday[]) => {
birthdays = birthdays.reduce((result: Birthday[], item: Birthday) => {
const birthday = `${(new Date()).getFullYear()}-${pad(item.month)}-${pad(item.day)}`
item.birthday = (new Date()).toISOString().split('T')[0] <= birthday ? birthday : `${(new Date()).getFullYear() + 1}-${pad(item.month)}-${pad(item.day)}`
result.push(item)
return result
}, [])
.sort((a, b) => {
if (b.birthday < a.birthday) return 1
if (b.birthday > a.birthday) return -1
return 0
})
return birthdays
}
const handleChangeAddForm = (event: ChangeEvent<HTMLInputElement|HTMLSelectElement>) => {
const value = event.target.nodeName === 'SELECT' ? Number(event.target.value) : event.target.value
setAddForm({...addForm, [event.target.name]: value})
}
const handleSubmitBirthday = (event: FormEvent) => {
event.preventDefault()
try {
if (!selectedPerson && birthdays.some(person => person.name === addForm.name) || (selectedPerson && selectedPerson.id !== addForm.id)) {
throw new Error('Une personne enregistré à déjà ce nom')
} else {
const maxId = data.birthdays.reduce(
(result: number, item: Birthday) => {
if (item.id > result) {
result = item.id;
}
if (selectedPerson) {
const personIndex = data.birthdays.findIndex((p: Birthday) => p.id === selectedPerson.id)
if (personIndex >= 0) {
const newList = data.birthdays
newList[personIndex] = addForm
setData({...data, birthdays: newList})
} else {
throw new Error('Une personne non trouvé dans la liste')
}
} else {
const maxId = data.birthdays.reduce((result: number, item: Birthday) => {
if (item.id > result) {result = item.id}
return result
}, 0)
setData({...data, birthdays: [...data.birthdays, {...addForm, id: maxId + 1}]})
}
handleCloseModal()
} catch (error) {
console.log(error)
}
return result;
},
0,
);
setData({
...data,
birthdays: [...data.birthdays, { ...addForm, id: maxId + 1 }],
});
}
handleCloseModal();
} catch (error) {
console.log(error);
}
};
const selectPerson = (person: Birthday) => setSelectedPerson(person)
const selectPerson = (person: Birthday) => setSelectedPerson(person);
const handleDelete = () => {
console.log(selectedPerson)
if (selectedPerson) {
const personIndex = data.birthdays.findIndex((p: Birthday) => p.id === selectedPerson.id)
if (personIndex >= 0) {
const newList = data.birthdays
newList.splice(personIndex, 1)
setData({...data, birthdays: newList})
setSelectedPerson(null)
} else {
throw new Error('Une personne non trouvé dans la liste')
}
}
const handleDelete = () => {
console.log(selectedPerson);
if (selectedPerson) {
const personIndex = data.birthdays.findIndex(
(p: Birthday) => p.id === selectedPerson.id,
);
if (personIndex >= 0) {
const newList = data.birthdays;
newList.splice(personIndex, 1);
setData({ ...data, birthdays: newList });
setSelectedPerson(null);
} else {
throw new Error("Une personne non trouvé dans la liste");
}
}
};
return (
<>
<header className="bg-gray-300 dark:bg-neutral-900 px-5 py-2.5 flex items-center font-bold text-3xl">
<img src={cake} alt="birthday cake" className="w-12 inline-block"/> Birthdays
</header>
return (
<>
<header className="bg-gray-300 dark:bg-neutral-900 px-5 py-2.5 flex items-center font-bold text-3xl">
<img src={cake} alt="birthday cake" className="w-12 inline-block" />{" "}
Birthdays
</header>
<BirthdayList birthdays={birthdays} selectedPerson={selectedPerson} selectPerson={selectPerson} />
<BirthdayList
birthdays={birthdays}
selectedPerson={selectedPerson}
selectPerson={selectPerson}
/>
<div className="sticky bottom-0 right-0">
<div className="flex flex-row-reverse justify-between p-2 w-full">
{selectedPerson ? <button type="button"
onClick={handleAddModal}
className={`${addModal ? 'translate-x-[100px] h-0' : 'translate-x-0 h-20'} transition bg-blue-700 rounded-full flex justify-center items-center text-white w-20 right-0`}>
<EditSVG className="w-10" />
</button>
: <button type="button"
onClick={handleAddModal}
className={`${addModal ? 'translate-x-[100px] h-0' : 'translate-x-0 h-20'} transition bg-amber-700 rounded-full flex justify-center items-center text-white w-20 right-0`}>
<PlusSVG className="w-10" />
</button>}
{selectedPerson && <button type="button"
onClick={handleDelete}
className={`h-20 transition bg-red-500 rounded-full flex justify-center items-center text-white w-20 right-0`}>
<TrashSVG className="w-10" />
</button>}
{(selectedPerson || addModal) && <button type="button"
className={`h-10 -mt-5 bg-gray-700 text-white p-2 rounded-full w-10 flex justify-center items-center`}
onClick={handleCloseModal}>
<PlusSVG className="w-6 rotate-45" />
</button>}
</div>
<form className={`${addModal ? 'h-18' : 'h-0 overflow-hidden'} flex`}
onSubmit={handleSubmitBirthday}>
<div className="p-2 w-full flex dark:text-neutral-800">
<input name="name"
type="text"
autoFocus
placeholder="nom"
className="border-2 p-2 flex-1 w-40 h-16 rounded-l-lg"
value={addForm.name}
onChange={handleChangeAddForm}/>
<select name="day"
className="px-1"
value={addForm.day}
onChange={handleChangeAddForm}>
{arrayRange(31, 1).map(day => <option key={'day-' + day} value={day}>{day}</option>)}
</select>
<select name="month"
className="px-1"
value={addForm.month}
onChange={handleChangeAddForm}>
{arrayRange(12, 1).map(month => <option key={'month-' + month}
value={month}>{month}</option>)}
</select>
<select name="year"
className="px-1 text-center"
value={addForm.year}
onChange={handleChangeAddForm}>
<option>--</option>
{arrayRange(2024, 1900).reverse()
.map(year => <option key={'year-' + year}
value={year}>
{year}
</option>)}
</select>
<button type="submit"
className="bg-green-800 text-white p-2 h-16 rounded-r-lg">
Valider
</button>
</div>
</form>
</div>
</>
)
<div className="sticky bottom-0 right-0">
<div className="flex flex-row-reverse justify-between p-2 w-full">
{selectedPerson ? (
<button
type="button"
onClick={handleAddModal}
className={`${addModal ? "translate-x-[100px] h-0" : "translate-x-0 h-20"} transition bg-blue-700 rounded-full flex justify-center items-center text-white w-20 right-0`}
>
<EditSVG className="w-10" />
</button>
) : (
<button
type="button"
onClick={handleAddModal}
className={`${addModal ? "translate-x-[100px] h-0" : "translate-x-0 h-20"} transition bg-amber-700 rounded-full flex justify-center items-center text-white w-20 right-0`}
>
<PlusSVG className="w-10" />
</button>
)}
{selectedPerson && (
<button
type="button"
onClick={handleDelete}
className={`h-20 transition bg-red-500 rounded-full flex justify-center items-center text-white w-20 right-0`}
>
<TrashSVG className="w-10" />
</button>
)}
{(selectedPerson || addModal) && (
<button
type="button"
className={`h-10 -mt-5 bg-gray-700 text-white p-2 rounded-full w-10 flex justify-center items-center`}
onClick={handleCloseModal}
>
<PlusSVG className="w-6 rotate-45" />
</button>
)}
</div>
<form
className={`${addModal ? "h-18" : "h-0 overflow-hidden"} flex`}
onSubmit={handleSubmitBirthday}
>
<div className="p-2 w-full flex dark:text-neutral-800">
<input
name="name"
type="text"
autoFocus
placeholder="nom"
className="border-2 p-2 flex-1 w-40 h-16 rounded-l-lg"
value={addForm.name}
onChange={handleChangeAddForm}
/>
<select
name="day"
className="px-1"
value={addForm.day}
onChange={handleChangeAddForm}
>
{arrayRange(31, 1).map((day) => (
<option key={"day-" + day} value={day}>
{day}
</option>
))}
</select>
<select
name="month"
className="px-1"
value={addForm.month}
onChange={handleChangeAddForm}
>
{arrayRange(12, 1).map((month) => (
<option key={"month-" + month} value={month}>
{month}
</option>
))}
</select>
<select
name="year"
className="px-1 text-center"
value={addForm.year}
onChange={handleChangeAddForm}
>
<option>--</option>
{arrayRange(2024, 1900)
.reverse()
.map((year) => (
<option key={"year-" + year} value={year}>
{year}
</option>
))}
</select>
<button
type="submit"
className="bg-green-800 text-white p-2 h-16 rounded-r-lg"
>
Valider
</button>
</div>
</form>
</div>
</>
);
}
export default App
export default App;