Skip to content

Commit

Permalink
Добавлены новые страницы и клиенты, реализован CRUD на Employees.
Browse files Browse the repository at this point in the history
  • Loading branch information
sckwokyboom committed May 19, 2024
1 parent d0ebd71 commit 625f0ea
Show file tree
Hide file tree
Showing 19 changed files with 679 additions and 58 deletions.
35 changes: 18 additions & 17 deletions src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ import PlaysPage from "./plays/PlaysPage.tsx";
import "../HomePage.css"
import PerformancesPage from "./performances/PerformancesPage.tsx";
import AuthorsPage from "./authors/AuthorsPage.tsx";
import CastingsPage from "./castings/CastingsPage.tsx";

export default function HomeApp() {
return (
<Routes>
<Route path="/" element={<Layout/>}>
<Route path="employees" element={<EmployeesPage/>}/>
<Route path="plays" element={<PlaysPage/>}/>
<Route path="performances" element={<PerformancesPage/>}/>
{/*<Route path="performances" element={<PerformancesPage/>}/>*/}
<Route path="actors" element={<PlaysPage/>}/>
<Route path="authors" element={<AuthorsPage/>}/>
<Route path="incomes" element={<PlaysPage/>}/>
<Route path="tickets" element={<PlaysPage/>}/>
<Route path="castings" element={<PlaysPage/>}/>
<Route path="castings" element={<CastingsPage/>}/>
<Route path="roles" element={<PlaysPage/>}/>
</Route>
{/*<Route path="*" element={<NoMatch />} />*/}
Expand All @@ -40,27 +41,27 @@ function Layout() {
<li>
<Link to="/plays">Пьесы</Link>
</li>
<li>
<Link to="/performances">Спектакли</Link>
</li>
{/*<li>*/}
{/* <Link to="/performances">Спектакли</Link>*/}
{/*</li>*/}
<li>
<Link to="/authors">Авторы</Link>
</li>
<li>
<Link to="/actors">Актёры</Link>
</li>
{/*<li>*/}
{/* <Link to="/actors">Актёры</Link>*/}
{/*</li>*/}
<li>
<Link to="/castings">Кастинги</Link>
</li>
<li>
<Link to="/roles">Роли</Link>
</li>
<li>
<Link to="/incomes">Доходы</Link>
</li>
<li>
<Link to="/tickets">Свободные места</Link>
</li>
{/*<li>*/}
{/* <Link to="/roles">Роли</Link>*/}
{/*</li>*/}
{/*<li>*/}
{/* <Link to="/incomes">Доходы</Link>*/}
{/*</li>*/}
{/*<li>*/}
{/* <Link to="/tickets">Свободные места</Link>*/}
{/*</li>*/}
{/* <li>*/}
{/* /!* Use a normal <a> when linking to the "Inbox" app so the browser*/}
{/*does a full document reload, which is what we want when exiting*/}
Expand Down
40 changes: 20 additions & 20 deletions src/pages/authors/FilterAuthorsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,26 +105,26 @@ const FilterAuthorsForm: React.FC<FilterProps<FilterAuthorCriteria>> = ({onFilte
</label>


<label className="form-label">
Век, в котором жил автор:
<input type="number"
name="centuryOfLiving"
value={filters.centuryOfLiving}
onChange={handleInputChange}
className="form-input"/>
</label>

<label className="form-label">
Ставился ли спектакль по пьесам автора:
<select name="wasPerformed"
value={filters.wasPerformed}
onChange={handleInputChange}
className="form-select">
<option value=""></option>
<option value="true">Да</option>
<option value="false">Нет</option>
</select>
</label>
{/*<label className="form-label">*/}
{/* Век, в котором жил автор:*/}
{/* <input type="number"*/}
{/* name="centuryOfLiving"*/}
{/* value={filters.centuryOfLiving}*/}
{/* onChange={handleInputChange}*/}
{/* className="form-input"/>*/}
{/*</label>*/}

{/*<label className="form-label">*/}
{/* Ставился ли спектакль по пьесам автора:*/}
{/* <select name="wasPerformed"*/}
{/* value={filters.wasPerformed}*/}
{/* onChange={handleInputChange}*/}
{/* className="form-select">*/}
{/* <option value=""></option>*/}
{/* <option value="true">Да</option>*/}
{/* <option value="false">Нет</option>*/}
{/* </select>*/}
{/*</label>*/}

<label className="form-label">
Жанр, в котором автор писал пьесы:
Expand Down
104 changes: 104 additions & 0 deletions src/pages/castings/CastingsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import '../../App.css'
import React, {useState} from "react";
import "react-datepicker/dist/react-datepicker.css";
import FilteredTable from "../FilteredTable.tsx";
import {CastingClient} from "../../webclients/casting/CastingClient.ts";
import {FilterCastingCriteria} from "../../webclients/casting/FilterCastingCriteria.ts";
import {Casting} from "../../webclients/casting/Casting.ts";
import FilterCastingsForm from "./FilterCastingsForm.tsx";

function CastingsPage() {
const castingClient = new CastingClient()
const fetchData = async (filters: FilterCastingCriteria): Promise<Casting[]> => {
try {
const data = await castingClient.fetchData("castings/filter", filters)
if (data) {
setCastings(data)
return data
}
return []
} catch (error) {
console.error('Error fetching data:', error);
return []
}
}
const [castings, setCastings] = useState<Casting[]>([]);
const [editingCastingIndex, setEditingCastingIndex] = useState<number | null>(null);
const [editedCasting, setEditedCasting] = useState<Casting | null>(null);

const toggleEditMode = (index: number) => {
setEditingCastingIndex(index);
setEditedCasting(castings[index]);
};
//
// const handleUpdateCasting = async () => {
// try {
// if (editedCasting) {
// const updatedEmployee = await castingClient.updateData("castings", editedCasting.id, editedCasting)
// if (updatedEmployee) {
// const updatedCastings = [...castings];
// updatedCastings[editingCastingIndex!] = editedCasting;
// setCastings(updatedCastings);
// setEditingCastingIndex(null);
// setEditedCasting(null);
// }
// }
// } catch (error) {
// console.error('Error updating employee:', error);
// }
// };
//
// const handleDeleteCasting = async (castingId: number) => {
// try {
// const deleted = await castingClient.deleteData("castings", castingId)
// if (deleted) {
// setCastings(castings.filter(casting => casting.id !== castingId));
// setEditingCastingIndex(null);
// setEditedCasting(null);
// }
// } catch (error) {
// console.error('Error deleting employee:', error);
// }
// };

const renderRow = (casting: Casting, index: number) => (
<tr key={casting.actorId}
onClick={() => {
if (index !== editingCastingIndex) {
toggleEditMode(index);
}
}}>
<td>{casting.actorId}</td>
<td>{casting.actorFirstName}</td>
<td>{casting.actorSecondName}</td>
<td>{casting.playTitle}</td>
<td>{casting.performanceDate}</td>
<td>{casting.performanceId}</td>
<td>{casting.doubleId}</td>
<td>{casting.roleId}</td>
<td>{casting.roleName}</td>
<td>{casting.roleDescription}</td>
</tr>
);


return (
<FilteredTable<Casting, FilterCastingCriteria>
fetchData={fetchData}
filterInitialState={{
actorId: undefined,
dateOfStart: undefined,
dateOfEnd: undefined,
playGenreId: undefined,
productionDirectorId: undefined,
ageCategory: undefined
}}
renderRow={renderRow}
FilterComponent={FilterCastingsForm}
tableHeaders={["ID актёра", "Имя актёра", "Фамилия актёра", "Название пьесы", "Дата спектакля", "ID спектакля", "ID дублёра", "ID роли", "Название роли", "Описание роли"]}
tableData={castings}
/>
)
}

export default CastingsPage
173 changes: 173 additions & 0 deletions src/pages/castings/FilterCastingsForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import React, {useEffect, useState} from 'react';
import '../../Filter.css';
import {FilterProps} from "../../FilterProps.ts";
import {FilterCastingCriteria} from "../../webclients/casting/FilterCastingCriteria.ts";
import {GenreClient} from "../../webclients/genre/GenreClient.ts";
import {Genre} from "../../webclients/genre/Genre.ts";
import {ActorClient} from "../../webclients/actor/ActorClient.ts";
import {DatePicker} from "antd";
import {Actor} from "../../webclients/actor/Actor.ts";

const FilterCastingsForm: React.FC<FilterProps<FilterCastingCriteria>> = ({onFilterChange}) => {
const [filters, setFilters] = useState<FilterCastingCriteria>({
actorId: undefined,
dateOfStart: undefined,
dateOfEnd: undefined,
playGenreId: undefined,
productionDirectorId: undefined,
ageCategory: undefined
});

const [actorsOptions, setActorsOptions] = useState<Actor[]>([])
const [genresOptions, setGenresOptions] = useState<Genre[]>([])
const [startDate, setStartDate] = useState<string | undefined | null>();
const [endDate, setEndDate] = useState<string | undefined | null>();
const [error, setError] = useState<string>('');

const handleInputChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const {name, value} = event.target;
setFilters({...filters, [name]: value});
};

const handleStartDateChange = (date: string | null) => {
setStartDate(date);
setFilters({
...filters,
dateOfStart: date ? formatDate(new Date(date)) : undefined
});
};

const handleEndDateChange = (date: string | null) => {
setEndDate(date);
setFilters({
...filters,
dateOfEnd: date ? formatDate(new Date(date)) : undefined
});
};

function formatDate(date: Date): string {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}


const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
onFilterChange(filters);
console.log(filters)
};

useEffect(() => {
const fetchActorsOptions = async () => {
const countriesClient = ActorClient.getInstance()
try {
const actors = await countriesClient.fetchAllActors()
if (actors) {
setActorsOptions(actors);
}
} catch (error) {
console.error('There was a problem with the fetch operation:', error);
}
};

const fetchGenresOptions = async () => {
const genresClient = GenreClient.getInstance()
try {
const genres = await genresClient.fetchAllGenres()
if (genres) {
setGenresOptions(genres);
}
} catch (error) {
console.error('There was a problem with the fetch operation:', error);
}
};

fetchGenresOptions().then()
fetchActorsOptions().then()
}, []);

return (
<form onSubmit={handleSubmit} className="filter-form">
<label className="form-label">
Актёр:
<select
name="actorId"
value={filters.actorId}
onChange={handleInputChange}
className="form-input">
{actorsOptions.map(actor => (
<option key={actor.id} value={actor.id}>
{actor.firstName} {actor.secondName} {actor.patronymic}
</option>
))}
</select>
</label>

<label className="form-label">
Рассматривать спектакли, начиная с даты:
<DatePicker
allowClear={true}
name="dateOfStart"
onChange={handleStartDateChange}
value={startDate}
className="form-input"
/>
</label>

<label className="form-label">
Рассматривать спектакли, заканчивая датой:
<DatePicker
allowClear={true}
name="dateOfEnd"
onChange={handleEndDateChange}
value={startDate}
className="form-input"
/>
</label>

<label className="form-label">
Жанр:
<select
name="genreId"
value={filters.playGenreId}
onChange={handleInputChange}
className="form-input">
{genresOptions.map(genre => (
<option key={genre.id} value={genre.id}>
{genre.title}
</option>
))}
</select>
</label>

{/*<label className="form-label">*/}
{/* Режиссёр-постановщик:*/}
{/* <input type="number"*/}
{/* name="amountOfChildren"*/}
{/* value={filters.amountOfChildren}*/}
{/* onChange={handleInputChange}*/}
{/* className="form-input"/>*/}
{/*</label>*/}

<label className="form-label">
Возрастная категория спектакля:
<select name="ageCategory"
value={filters.ageCategory}
onChange={handleInputChange}
className="form-select">
<option value="">Любая</option>
<option value="0">0+</option>
<option value="6">6+</option>
<option value="12">12+</option>
<option value="16">16+</option>
<option value="18">18+</option>
</select>
</label>
<button type="submit" className="form-button">Применить фильтр</button>
</form>
);
};

export default FilterCastingsForm;
Loading

0 comments on commit 625f0ea

Please sign in to comment.