diff --git a/client/package-lock.json b/client/package-lock.json index 54f5d87a876650722ee90a7acfd78257c9268af2..c880543cdb2ec08971a862d22da32a8cf566b330 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9847,6 +9847,24 @@ "minimist": "^1.2.5" } }, + "mobx": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.3.5.tgz", + "integrity": "sha512-MeDfqtiSbhVoJgXqQsrJwvq2klj7Xk9pPdMThCdFiwFt33vgWJe82ATppPwVzQoz0AI3QpSSwQzcp3TBDK4syg==" + }, + "mobx-react": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-7.2.1.tgz", + "integrity": "sha512-LZS99KFLn75VWDXPdRJhILzVQ7qLcRjQbzkK+wVs0Qg4kWw5hOI2USp7tmu+9zP9KYsVBmKyx2k/8cTTBfsymw==", + "requires": { + "mobx-react-lite": "^3.2.0" + } + }, + "mobx-react-lite": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-3.2.1.tgz", + "integrity": "sha512-hwURgfmP2apX3HQrB55V9DN47kuN3C6KlQvI5UIfJRibXma72C/JudcNt2r9dWjAdFMrcZoz1ivvtXMCkJ2aQA==" + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", diff --git a/client/package.json b/client/package.json index 18e7122b1693dac4dbf4d990bf6ac0830d101126..085e0ba5f6f1d814cc7ee287829ed9f2f5da95a5 100644 --- a/client/package.json +++ b/client/package.json @@ -12,6 +12,8 @@ "@types/react": "^17.0.28", "@types/react-dom": "^17.0.9", "dotenv": "^10.0.0", + "mobx": "^6.3.5", + "mobx-react": "^7.2.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", diff --git a/client/src/App.css b/client/src/App.css index 74b5e053450a48a6bdb4d71aad648e7af821975c..6ec89a0ffb80ce4a1ce554579bdf52cc29e2643a 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -13,9 +13,9 @@ } } -.App-header { - background-color: #282c34; - min-height: 100vh; +.header { + background-color: gray; + min-height: 5vh; display: flex; flex-direction: column; align-items: center; diff --git a/client/src/App.tsx b/client/src/App.tsx index ce245c7802e50ae9ac4c1006a1df863ff86fb57f..1e9820ec525b4a96c59ee4d91d32702c32bec278 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,11 +1,14 @@ - import './App.css'; import Movies from './components/Movies' +import Header from './components/Header' +import { MoviesStore } from "./components/MoviesStore"; function App() { + return ( <div className="App"> - <Movies /> + <Header moviesStore={MoviesStore}/> + <Movies moviesStore={MoviesStore}/> </div> ); } diff --git a/client/src/components/Header.tsx b/client/src/components/Header.tsx new file mode 100644 index 0000000000000000000000000000000000000000..70a6a2f37cf400be4acfbf8bf9f3a12d23fe1fe5 --- /dev/null +++ b/client/src/components/Header.tsx @@ -0,0 +1,54 @@ + +import React, { Component } from 'react' +import { MoviesStoreImplementation } from "./MoviesStore"; +import { inject, observer } from 'mobx-react'; +import * as services from './services'; + +type MyState = { + input: string +}; + +interface MoviesProps { + moviesStore: MoviesStoreImplementation +} + +class Header extends React.Component<MoviesProps, MyState> { + constructor(props: any) { + super(props); + + this.state = { + input: '' + } + } + + + render() { + return ( + <div className="header"> + <input type="text" placeholder="Search for movies..." onChange={this.handleChange}></input> + + <button onClick={this.search}>Search</button> + </div> + ) + } + + + handleChange = (e: any) => { + this.setState({ input: e.target.value }) + } + + + search = () => { + this.getMovieByColumnType(services.ColumnType.Title, this.state.input, 'id title genre description'); + } + + + getMovieByColumnType(columnType : services.ColumnType, value: string, neededData: string) { + services.queryFetch(services.generateQuery(columnType, value, neededData) , 'POST') + .then(res => res.json()) + .then(res => this.props.moviesStore.setMovies(res.data.getMovieByColumnType)) + } +} + + +export default inject('moviesStore')(observer(Header)) \ No newline at end of file diff --git a/client/src/components/Movies.tsx b/client/src/components/Movies.tsx index 7b9b5e90cc7e6c3c53c0ecbc749a26877e2febc7..1300856957c36c842aec250218b7e8825ea36fc2 100644 --- a/client/src/components/Movies.tsx +++ b/client/src/components/Movies.tsx @@ -1,126 +1,61 @@ import React from 'react'; -import './movies.css'; +import { MoviesStore, MoviesStoreImplementation } from "./MoviesStore"; +import { inject, observer } from 'mobx-react'; +import * as services from './services'; type MyProps = {}; type MyState = { movies: any }; -enum ColumnType{ - Id, - Title, - Genre, - Rating, - Year, - DirectorFirstName, - DirectorLastName, - Description +interface MoviesProps { + moviesStore: MoviesStoreImplementation } -class Movies extends React.Component<MyProps, MyState> { +// interface movie { + +// } + +class Movies extends React.Component<MoviesProps, MyState> { constructor(props: any) { super(props); - this.state = { - movies: [] - } + // this.state = { + // movies: [] + // } } - getAllMoviesQuery = ` - query { - getAllMovies { - id,title,genre,rating_dice_throw,year,director_first_name,director_last_name,description,cover_image - } - }` - createMovieQuery = ` - mutation { - createMovie(title: "testing", genre: "gaming", rating_dice_throw: 1, year: '2000', director_first_name: "torje", director_last_name: "the_gamer", description: "amazing", cover_image: "url123") { - id - } - }` - - getAllMovies() { - this.queryFetch(this.getAllMoviesQuery, 'POST') + services.queryFetch(services.getAllMoviesQuery, 'POST') .then(res => res.json()) - .then(res => this.setState({ movies: res.data.getAllMovies })) - .then(res => console.log(this.state.movies)) + .then(res => this.props.moviesStore.setMovies(res.data.getAllMovies)) } - generateQuery(columnType: ColumnType, value: string, neededData: string){ - - let column = ''; - - switch(columnType){ - case ColumnType.Title: - column = 'title'; - break; - case ColumnType.Genre: - column = 'genre'; - break; - case ColumnType.Rating: - column = 'rating_dice_throw'; - break; - case ColumnType.Year: - column = 'year'; - break; - case ColumnType.DirectorFirstName: - column = 'director_first_name'; - break; - case ColumnType.DirectorLastName: - column = 'director_last_name'; - break; - case ColumnType.Description: - column = 'description'; - break; - default: - column = 'id'; - break; - - } - return ` - query { - getMovieByColumnType(${column}: "${value}") { - ${neededData} - } - }`; - } - - getMovieByColumnType(columnType : ColumnType, value: string, neededData: string) { - this.queryFetch(this.generateQuery(columnType, value, neededData) , 'POST') + getMovieByColumnType(columnType : services.ColumnType, value: string, neededData: string) { + services.queryFetch(services.generateQuery(columnType, value, neededData) , 'POST') .then(res => res.json()) - .then(res => this.setState({ movies: res.data.getMovieByColumnType })) - .then(res => console.log(this.state.movies)) + .then(res => this.props.moviesStore.setMovies(res)) } componentDidMount() { - //this.getAllMovies(); - this.getMovieByColumnType(ColumnType.Genre, 'Drama', 'id title genre description'); - } - - - queryFetch(query: String, method: string) { - return fetch('/graphql', { - method: method, - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - query: query, - // variables: variables - }) - }) + this.getAllMovies(); + // this.getMovieByColumnType(services.ColumnType.Genre, 'Drama', 'id title genre description'); } render() { return ( <ul> - {this.state.movies.map((movie: any) => <li key={movie.title}>{JSON.stringify(movie)}</li>)} + {/* {this.state.movies.map((movie: any) => <li key={movie.title}>{JSON.stringify(movie)}</li>)} */} + {/* {this.props.moviesStore.movies.map((movie: any) => <li key={movie.id}>{JSON.stringify(movie)}</li>)} */} + {JSON.stringify(MoviesStore.movies)} </ul> ); } } -export default Movies; + +export default inject('moviesStore')(observer(Movies)) diff --git a/client/src/components/MoviesStore.tsx b/client/src/components/MoviesStore.tsx new file mode 100644 index 0000000000000000000000000000000000000000..fa9cb8ed43a58c79d7705dbb8b17e6726621648a --- /dev/null +++ b/client/src/components/MoviesStore.tsx @@ -0,0 +1,23 @@ +import { action, makeObservable, observable } from "mobx"; + +interface Movie { + +} + +export class MoviesStoreImplementation { + + movies: Movie[] = []; + + constructor() { + makeObservable(this, { + movies: observable, + setMovies: action + }); + } + + setMovies(movies: any) { + this.movies = movies; + } +} + +export const MoviesStore = new MoviesStoreImplementation(); \ No newline at end of file diff --git a/client/src/components/movies.css b/client/src/components/movies.css deleted file mode 100644 index add70cca91dde93d4cc7d955e89445f9b723be74..0000000000000000000000000000000000000000 --- a/client/src/components/movies.css +++ /dev/null @@ -1,6 +0,0 @@ -.App { - margin: auto -} -.App-header { - height: auto -} \ No newline at end of file diff --git a/client/src/components/services.ts b/client/src/components/services.ts index 98167943468bee83ffe28364e72624e8dc517651..f88cff23bcff0bcbdd97f464e1cfe3e1c0149486 100644 --- a/client/src/components/services.ts +++ b/client/src/components/services.ts @@ -1,55 +1,76 @@ -//@ts-nocheck -// const continentSelect = document.getElementById('continent-select') -// const countryList = document.getElementById('countries-list') - -// queryFetch(` -// query { -// continents { -// name -// code -// } -// } -// `) -// .then(data => { -// data.data.movies.forEach(movie => { -// option.innerText = continent.name -// continentSelect.append(option) -// }) -// }) - -// continentSelect.addEventListener('change', async e => { -// const continentCode = e.target.value -// const countries = await getContinentCountries(continentCode) -// countryList.innerHTML = '' -// countries.forEach(country => { -// const element = document.createElement('div') -// element.innerText = country.name -// countryList.append(element) -// }) -// }) - -// function getContinentCountries(continentCode) { -// return queryFetch(` -// query getCountries($code: String) { -// continent(code: $code) { -// countries { -// name -// } -// } -// } -// `, { code: continentCode }).then(data => { -// return data.data.continent.countries -// }) -// } - -// export function queryFetch(query, variables) { -// return fetch('https://countries.trevorblades.com/', { -// method: 'POST', -// headers: { "Content-Type": "application/json" }, -// body: JSON.stringify({ -// query: query, -// variables: variables -// }) -// }).then(res => res.json()) -// } -export {} \ No newline at end of file +export function queryFetch(query: String, method: string) { + return fetch('/graphql', { + method: method, + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + query: query, + // variables: variables + }) + }) +} + +export enum ColumnType{ + Id, + Title, + Genre, + Rating, + Year, + DirectorFirstName, + DirectorLastName, + Description +} + +export function generateQuery(columnType: ColumnType, value: string, neededData: string){ + + let column = ''; + + switch(columnType){ + case ColumnType.Title: + column = 'title'; + break; + case ColumnType.Genre: + column = 'genre'; + break; + case ColumnType.Rating: + column = 'rating_dice_throw'; + break; + case ColumnType.Year: + column = 'year'; + break; + case ColumnType.DirectorFirstName: + column = 'director_first_name'; + break; + case ColumnType.DirectorLastName: + column = 'director_last_name'; + break; + case ColumnType.Description: + column = 'description'; + break; + default: + column = 'id'; + break; + + } + + return ` + query { + getMovieByColumnType(${column}: "${value}") { + ${neededData} + } + }`; +} + + +export const getAllMoviesQuery = ` +query { + getAllMovies { + id,title,genre,rating_dice_throw,year,director_first_name,director_last_name,description,cover_image + } +}` + +export const createMovieQuery = ` +mutation { + createMovie(title: "testing", genre: "gaming", rating_dice_throw: 1, year: '2000', director_first_name: "torje", director_last_name: "the_gamer", description: "amazing", cover_image: "url123") { + id + } +}` diff --git a/server/src/server.ts b/server/src/server.ts index 34ffe9e13ef239ac782324f4c8c0fdb9e96ccda8..9724f9b4bf3a8f7f532e23d005a26c8161b6d175 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -38,7 +38,7 @@ const RootQuery = new GraphQLObjectType({ getMovieByColumnType: { type: new GraphQLList(MovieType), args: { - id: { type: GraphQLString }, + id: { type: GraphQLInt }, title: { type: GraphQLString }, genre: { type: GraphQLString }, rating_dice_throw: { type: GraphQLInt },