Skip to content
Snippets Groups Projects
Commit e09fa458 authored by Tomáš Havlíček's avatar Tomáš Havlíček
Browse files

Merge branch 'fr-prep' into 'main'

Fr prep

See merge request xhavlic/pb138-film-database-group-project!3
parents 5ee82422 1a18363b
No related branches found
No related tags found
No related merge requests found
......@@ -31,7 +31,8 @@ Infrastructure:
- dockercompose
UI:
-Mantis
- Ant
- Mantis
## Usage
......@@ -56,6 +57,18 @@ To login to Adminer in your browser you need to specify:
* Password: same as `DB_PASSWORD` in your .env file
* Database: same as `DB_NAME` in your .env file
## REST API
| requirement |endpoint | method | criteria |
| ------------- | ------------- | ------------- | ------------- |
| Search for a movie | /movies | get | returns array of movies as a result of search
| Show a single movie | /movie/:id | get | return movie
| Show popular movies | /movie/preview | get | returns array of few movies (popular) to preview
| Show a single director | /director/:id | get | returns director
| Show categories to browse | /categories | get | returns all categories
| Show a single category | /category/:id | get | returns category with movies that belong to it
## TODO
More TBA as features are implemented.
......@@ -15,8 +15,8 @@
"react-router-dom": "^6.3.0"
},
"devDependencies": {
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/react": "^18.0.12",
"@types/react-dom": "^18.0.5",
"@vitejs/plugin-react": "^1.3.0",
"typescript": "^4.6.3",
"vite": "^2.9.9"
......
......@@ -15,8 +15,8 @@
"react-router-dom": "^6.3.0"
},
"devDependencies": {
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@types/react": "^18.0.12",
"@types/react-dom": "^18.0.5",
"@vitejs/plugin-react": "^1.3.0",
"typescript": "^4.6.3",
"vite": "^2.9.9"
......
import { useState } from 'react'
import logo from './logo.svg'
import './App.css'
import { useState } from "react";
import 'antd/dist/antd.css'
import "./App.css";
import MainPage from "./components/MainPage";
import { Routes, Route, Outlet, Link, BrowserRouter } from "react-router-dom";
import { NavigationBar } from "./components/NavigationBar";
import { About } from "./components/About";
import React from "react";
import { Browse } from "./components/Browse";
import { SearchPage } from "./components/SearchPage";
import { ErrorPage } from "./components/ErrorPage";
function App() {
const [count, setCount] = useState(0)
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>Hello Vite + React!</p>
<p>
<button type="button" onClick={() => setCount((count) => count + 1)}>
count is: {count}
</button>
</p>
<p>
Edit <code>App.tsx</code> and save to test HMR updates.
</p>
<p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{' | '}
<a
className="App-link"
href="https://vitejs.dev/guide/features.html"
target="_blank"
rel="noopener noreferrer"
>
Vite Docs
</a>
</p>
</header>
<div className="app">
<NavigationBar/>
<Routes>
<Route path="/" element={<MainPage/>}></Route>
<Route path="/browse" element={<Browse/>}></Route>
<Route path="/search" element={<SearchPage/>}></Route>
<Route path="/about" element={<About/>}></Route>
<Route path="*" element={<ErrorPage/>}></Route>
</Routes>
</div>
)
);
}
export default App
export default App;
frontend/src/LogoMovieBase.png

2.45 KiB

import { Space, Typography, Card } from "antd"
import React from "react";
const { Title, Paragraph, Text, Link } = Typography;
export const About = () => {
return (
<>
<Typography>
<Space direction="vertical" size="middle" style={{ display: 'flex' , padding:16, textAlign: 'center'}}>
<Card title={<Title>About</Title>}>
<Paragraph> Movie Base is database of movies.</Paragraph>
<Paragraph> It is possible to view popular movies, search for your favourites or checkout details of every movie possible </Paragraph>
</Card>
</Space>
</Typography>
</>
)
}
\ No newline at end of file
import { Card, Image} from "antd"
import React from "react"
// for browsing movies by categories
const gridStyle: React.CSSProperties = {
width: '25%',
textAlign: 'center',
};
interface CategoryIO{
id: string,
name: string,
movies: MovieIO[]
}
interface MovieIO{
id: string,
name: string,
originalName: string,
intro: string,
picture: string,
published: string,
runTimeMinutes: number
director: DirectorIO
}
interface DirectorIO{
id: string,
name: string,
surname: string,
birthdate: string
}
const categories: CategoryIO[] = [
{id: "12345", name : "Horror", movies:[{id: "789", name: "Saw", originalName: "Saw", intro: "Jigsaw is the bad guy and this is the game",
picture: "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Ftse3.mm.bing.net%2Fth%3Fid%3DOIP.Jo6M-3oyAlMsB4-F__Z9bwHaHa%26pid%3DApi&f=1",
published: "1.1.2000", runTimeMinutes : 120, director: {id: "123456789", name: "Karel", surname: "Vomacka", birthdate: "20.2.1987"} },
{id: "999", name: "Saw 2", originalName: "Saw 2", intro: "The sequel to the first one",
picture: "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fimages01.kaleidescape.com%2Ftransformed%2Fcovers%2F1134x1624s%2F189%2F18976008.jpg&f=1&nofb=1",
published: "1.1.2002", runTimeMinutes : 150, director: {id: "123456789", name: "Karel", surname: "Vomacka", birthdate: "20.2.1987"} }
]},
{id: "56789", name : "Comedy", movies:[{id: "445", name: "Kdo zabil kapitána Alexe", originalName: "Who killed Cpt Alex", intro: "SUPAKICKA",
picture: "https://external-content.duckduckgo.com/iu/?u=http%3A%2F%2F2ht1mik98ka4dogie28vqc4y.wpengine.netdna-cdn.com%2Fwp-content%2Fuploads%2F2015%2F10%2FWho-Killed-Capt-Alex.jpg&f=1&nofb=1",
published: "8.8.2015", runTimeMinutes: 60, director: {id: "2323", name: "Pastor", surname: "LUL", birthdate: "unknown"}
}]}]
export const Browse = () => {
return (
<div className="browse-container">
{categories.map((category) =>{
return ( <Card title = {category.name}>
{category.movies.map( (movie ) => {
return (<Card.Grid style={gridStyle}><h1>{movie.name}</h1><Image src= {movie.picture}></Image> {movie.intro}</Card.Grid>)
})}
</Card>)
})}
</div>)
}
\ No newline at end of file
import React from "react"
export const ErrorPage = () => {
return (
<div className="error-page">
Something went wrong...
</div>)
}
\ No newline at end of file
import { Breadcrumb, Button, Layout, Menu, Image } from 'antd';
import React from 'react';
const { Header, Content, Footer } = Layout;
import 'antd/dist/antd.css'
import Preview from './Preview';
const MainPage = () => (
<Layout className="layout">
<Content
style={{
padding: '0 50px',
}}
>
<Preview></Preview>
</Content>
<Footer
style={{
textAlign: 'center',
}}
>
Ant Design ©2018 Created by Ant UED
</Footer>
</Layout>
);
export default MainPage;
import React from "react"
import logo from '../LogoMovieBase.png'
import { Menu, Image } from "antd"
import { Header } from "antd/lib/layout/layout"
import { Link } from "react-router-dom"
// on top of the screen at all times, links to each feature of site
export const NavigationBar = () => {
return (
<div className="navigation-bar">
<Header>
<Menu theme="dark" mode="horizontal" defaultSelectedKeys={["2"]}>
<Image src={logo} width={50}></Image>
<Menu.Item><Link to="/">Home</Link></Menu.Item>
<Menu.Item><Link to="/browse">Browse</Link></Menu.Item>
<Menu.Item><Link to="/search">Search</Link></Menu.Item>
<Menu.Item><Link to="/about">About</Link></Menu.Item>
</Menu>
</Header>
</div>)
}
\ No newline at end of file
import { Card, Carousel, Image, Space } from "antd";
import Meta from "antd/lib/card/Meta";
import Title from "antd/lib/skeleton/Title";
import React from "react";
const contentStyle: React.CSSProperties = {
height: "320px",
color: "#fff",
lineHeight: "160px",
textAlign: "center",
background: "#364d79",
};
interface DisplayCards{
title: string;
altitle: string;
image: string
}
//example
const cardsData: DisplayCards[] =[
{title: "Cars", altitle: "Auta", image: "https://upload.wikimedia.org/wikipedia/en/3/34/Cars_2006.jpg"},
{title: "Monster House", altitle: "V tom domě straší", image:"https://images-na.ssl-images-amazon.com/images/S/pv-target-images/9a996123e0b01f618ab2291b479f9d5034de354b2d1bb58979ddc6937588dfa8._RI_V_TTW_.jpg"},
{title: "Pokemon", altitle: "Pokémon", image:"https://www.obchod.crew.cz/im/coc/1280/0/content/629080/cover_image.1607432614.jpg"},
{title: "The Can", altitle: "Gympl", image:"https://img.csfd.cz/files/images/user/profile/162/847/162847510_91e839.jpg"},
{title: "Toy Story", altitle: "Příběh hraček", image:"https://m.media-amazon.com/images/M/MV5BMDU2ZWJlMjktMTRhMy00ZTA5LWEzNDgtYmNmZTEwZTViZWJkXkEyXkFqcGdeQXVyNDQ2OTk4MzI@._V1_.jpg"},
{title: "Smoke", altitle: "Kouř", image: "https://img.csfd.cz/files/images/user/profile/164/556/164556101_d8e43b.jpg"},
]
const Preview: React.FC = () => (
<div>
<h1>Popular movies</h1>
<Space>
{cardsData.map((movie) => {
return (
<>
<Card
hoverable
style={{
width: 240,
}}
cover={
<img
alt={movie.title}
src={movie.image}
/>
}
>
<Meta title={movie.title} description={movie.altitle} />
</Card>
</>)
})}
</Space>
<Carousel autoplay>
<div>
<h3 style={contentStyle}>Avengers</h3>
</div>
<div>
<h3 style={contentStyle}>Morbius</h3>
</div>
<div>
<h3 style={contentStyle}>Princezna a Bubeník</h3>
</div>
<div>
<h3 style={contentStyle}>Scary Movie</h3>
</div>
<div>
<h3 style={contentStyle}>Scary Movie 2</h3>
</div>
<div>
<h3 style={contentStyle}>Scary Movie 3</h3>
</div>
</Carousel>
</div>
);
export default Preview;
import { AudioOutlined } from '@ant-design/icons';
import { Input, Space } from 'antd';
import React from 'react';
const { Search } = Input;
//function that happens when search button is pressed
const onSearch = (value: string) => console.log(value);
//for searching movies
export const SearchPage = () => {
return (
<>
<Space direction="vertical" style={{ display: 'flex', padding: 24, textAlign: 'center' }}>
<Search
placeholder="input search text"
allowClear
enterButton="Search"
size="large"
onSearch={onSearch}
width="400 px" />
</Space>
<Space>
Results here
</Space>
</>
);
};
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment