Skip to content
Snippets Groups Projects
SearchPage.tsx 9.66 KiB
Newer Older
import { SearchOutlined } from "@ant-design/icons";
import {
  Button,
  Col,
  Form,
  Input,
  Row,
  Select,
  Slider,
  Space,
  Table,
} from "antd";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import axiosConfig from "../axios-config";
import { CategoryDTO, DirectorDTO, MovieDTO } from "../dto";
const { Option } = Select;
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 [form] = Form.useForm();

  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) ]);
  const onSubmit = async (values: IFormProps) => {
      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,
      setResultMovies([ ...response.data ]);
    } catch {
      // TODO: on error
    }
  };

  const onReset = () => {
    form.resetFields();
  };
  //columns stays the same
  const columns = [
    {
      title: "Name",
      dataIndex: "name",
      sorter: (a: MovieDTO, b: MovieDTO) => {
        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) => {
        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();
        // year
        if (first[0] > second[0]) {return 1;}
        if (first[0] < second[0]) {return -1;}
        // 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;}
    },
    {
      title: "Runtime",
      dataIndex: "runtimeMinutes",
      sorter: (a: MovieDTO, b: MovieDTO) => a.runTimeMinutes - b.runTimeMinutes,
      title: "Director",
      dataIndex: ["director", "surname"],
      sorter: (a: MovieDTO, b: MovieDTO) => {
        //surname has higher priority than name
        if (a.director.surname < b.director.surname) {return -1;}
        if (a.director.surname > b.director.surname) {return 1;}
        if (a.director.name < b.director.name) {return -1;}
        if (a.director.name > b.director.name) {return 1;}
        return 0;
      render: (text: string, record: MovieDTO) => (
        <Link to={`/director/${record.director.id}`}>
          <a>
            {record.director.name} {record.director.surname}
          </a>
      <Space
        direction="vertical"
        style={{ display: "flex", padding: 24, textAlign: "center" }}
      >
        <Form form={form} onFinish={onSubmit}>
          <Row gutter={20}>
            <Col span={6}>
              <Form.Item name="name" label="Name">
                <Input></Input>
              </Form.Item>
            </Col>
            <Col span={6}>
              <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>
          <Row gutter={20}>
            <Col span={12}>
              <Form.Item name="publishedAt" label="Year published">
              <Slider
                marks={yearMarks}
                range={{ draggableTrack: true }}
                min={1920}
                defaultValue={[2000, 2010]}
              ></Slider>
            </Col>
            <Col></Col>
          </Row>
          <Row gutter={20}>
            <Col span={6}>
              <Form.Item name="categoryId" label="Category">
              <Select
                showSearch
                style={{ width: "100%" }}
                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()
                    .localeCompare((optionB!.children as unknown as string).toLowerCase())
                {categories.map((category: CategoryDTO) => {
                    <Option key={category.id} value={category.id}>
                })}
              </Select>
            </Col>
            <Col span={6}>
              <Form.Item name="directorId" label="Director">
              <Select
                showSearch
                style={{ width: "100%" }}
                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()
                    .localeCompare((optionB!.children as unknown as string).toLowerCase())
                {directors.map((director: DirectorDTO) => {
                    <Option key={director.id} value={director.id}>
                      {`${director.name} ${director.surname}`}
              </Select>
            </Col>
          </Row>
          <Row>
            <Col span={12}>
              <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>
            </Col>
          </Row>
        </Form>
      <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>