Newer
Older
import { SearchOutlined } from "@ant-design/icons";
Form,
Input,
Row,
Select,
Slider,
Space,
Table,
} from "antd";

Lukáš Kratochvíl
committed
import { useEffect, useState } from "react";
import axiosConfig from "../axios-config";
import { CategoryDTO, DirectorDTO, MovieDTO } from "../dto";
const runtimeMarks = {
0: "0",
30: "30",
60: "60",
90: "90",
120: "120",
150: "150",
180: "180",
210: "210",
240: "240",
270: "270",
300: "300",
};
const yearMarks = {
1920: "1920",
1940: "1940",
1960: "1960",
1980: "1980",
2000: "2000",
2020: "2020",
};
interface IFormProps {
name: string;
originalName: string;
runTimeMinutes: number[];
publishedAt: number[];
categoryId: string;
directorId: string;
};
//for searching movies
export const SearchPage = () => {
const [categories, setCategories] = useState<CategoryDTO[]>([]);
const [directors, setDirectors] = useState<DirectorDTO[]>([]);
const [resultMovies, setResultMovies] = useState<MovieDTO[]>([]);
useEffect(() => {
const fetchData = async () => {
const catResponsePromise = axiosConfig.get<CategoryDTO[]>('/categories');
const dirResponsePromise = axiosConfig.get<DirectorDTO[]>('/directors');
setCategories([ ...((await catResponsePromise).data) ]);
setDirectors([ ...((await dirResponsePromise).data) ]);
};
void fetchData();
}, []);
const onSubmit = async (values: IFormProps) => {

Lukáš Kratochvíl
committed
try {
const response = await axiosConfig.get<MovieDTO[]>('/movies', {
params: {
name: values.name,
origName: values.originalName,
runtime: {
gte: values.runTimeMinutes ? values.runTimeMinutes[0] : undefined,
lte: values.runTimeMinutes ? values.runTimeMinutes[1] : undefined,
},
published: {
gte: values.publishedAt ? values.publishedAt[0] : undefined,
lte: values.publishedAt ? values.publishedAt[1] : undefined,
},
categoryId: values.categoryId,
directorId: values.directorId,

Lukáš Kratochvíl
committed
}

Lukáš Kratochvíl
committed
setResultMovies([ ...response.data ]);
} catch {
// TODO: on error
}
};
const onReset = () => {
form.resetFields();
};

Lukáš Kratochvíl
committed
const columns = [
{
title: "Name",
dataIndex: "name",
sorter: (a: MovieDTO, b: MovieDTO) => {

Lukáš Kratochvíl
committed
if (a.name < b.name) {return -1;}
if (a.name > b.name) {return 1;}
render: (text: string, record: MovieDTO) => (
<Link to={`/movie/${record.id}`}>
<a>{record.name}</a>
</Link>
),
},
{
title: "Original name",
className: "original-name",
dataIndex: "originalName",
sorter: (a: MovieDTO, b: MovieDTO) => {

Lukáš Kratochvíl
committed
if (a.originalName < b.originalName) {return -1;}
if (a.originalName > b.originalName) {return 1;}
},
{
title: "Release Date",
dataIndex: "published",
sorter: (a: MovieDTO, b: MovieDTO) => {
const first = a.publishedAt.split(".").reverse();
const second = b.publishedAt.split(".").reverse();

Lukáš Kratochvíl
committed
// year
if (first[0] > second[0]) {return 1;}
if (first[0] < second[0]) {return -1;}

Lukáš Kratochvíl
committed
// month
if (first[1] > second[1]) {return 1;}
if (first[1] < second[1]) {return -1;}
// day
if (first[2] > second[2]) {return 1;}
if (first[2] < second[2]) {return -1;}
sorter: (a: MovieDTO, b: MovieDTO) => a.runTimeMinutes - b.runTimeMinutes,
sorter: (a: MovieDTO, b: MovieDTO) => {

Lukáš Kratochvíl
committed
//surname has higher priority than name
if (a.director.surname < b.director.surname) {return -1;}
if (a.director.surname > b.director.surname) {return 1;}

Lukáš Kratochvíl
committed
if (a.director.name < b.director.name) {return -1;}
if (a.director.name > b.director.name) {return 1;}
render: (text: string, record: MovieDTO) => (
<Link to={`/director/${record.director.id}`}>
<a>
{record.director.name} {record.director.surname}
</a>

Lukáš Kratochvíl
committed
<Space
direction="vertical"
style={{ display: "flex", padding: 24, textAlign: "center" }}
>
<Form form={form} onFinish={onSubmit}>
<Row gutter={20}>
<Form.Item name="name" label="Name">
<Input></Input>
</Form.Item>
<Form.Item name="originalName" label="Original name">
<Input></Input>
</Form.Item>
</Col>
</Row>
<Row gutter={20}>
<Col span={12}>
<Form.Item name="runTimeMinutes" label="Runtime minutes">
<Slider
marks={runtimeMarks}
range={{ draggableTrack: true }}
step={10}
max={300}
defaultValue={[60, 120]}
></Slider>
</Form.Item>
<Form.Item name="publishedAt" label="Year published">
<Slider
marks={yearMarks}
range={{ draggableTrack: true }}
min={1920}

Lukáš Kratochvíl
committed
max={new Date().getFullYear()}
<Form.Item name="categoryId" label="Category">
<Select
showSearch
style={{ width: "100%" }}

Lukáš Kratochvíl
committed
placeholder="Search or Select"
optionFilterProp="children"
filterOption={(input, option) =>
(option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
}
filterSort={(optionA, optionB) =>
(optionA!.children as unknown as string)
.toLowerCase()

Lukáš Kratochvíl
committed
.localeCompare((optionB!.children as unknown as string).toLowerCase())
{categories.map((category: CategoryDTO) => {

Lukáš Kratochvíl
committed
return (
<Option key={category.id} value={category.id}>

Lukáš Kratochvíl
committed
{category.name}
</Option>
);
<Form.Item name="directorId" label="Director">
<Select
showSearch
style={{ width: "100%" }}

Lukáš Kratochvíl
committed
placeholder="Search or Select"
optionFilterProp="children"
filterOption={(input, option) =>
(option!.children as unknown as string).toLowerCase().includes(input.toLowerCase())
}
filterSort={(optionA, optionB) =>
(optionA!.children as unknown as string)
.toLowerCase()

Lukáš Kratochvíl
committed
.localeCompare((optionB!.children as unknown as string).toLowerCase())
{directors.map((director: DirectorDTO) => {
<Option key={director.id} value={director.id}>

Lukáš Kratochvíl
committed
{`${director.name} ${director.surname}`}
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
<Divider></Divider>
</Col>
</Row>
<Row gutter={20}>
<Col span={6}>
<Form.Item name="searchbutton">
<Button
htmlType="submit"
style={{ width: "100%" }}
type="primary"
icon={<SearchOutlined />}
size="large"
>
Search
</Button>
</Form.Item>
</Col>
<Col span={6}>
<Form.Item name="reset">
<Button
size="large"
type="default"
style={{ width: "100%" }}
onClick={onReset}
>
Reset
</Button>
</Form.Item>
<Space
direction="vertical"
style={{ display: "flex", padding: 24, textAlign: "left" }}
>
<Table
onRow={(record, rowIndex) => {
return {
onClick: (event) => {
console.log(record.id); // TODO: remove later
},
}; // TODO: here change to view movie
}}
columns={columns}
dataSource={resultMovies}
rowKey='id'
bordered
title={() => "Results"}
/>
</Space>