-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
4,617 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
.next |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,57 @@ | ||
# 前端面試題目 | ||
# Ani Search (FE Coding Assignments) | ||
|
||
## Expected Result Example | ||
|
||
<img src="demo.gif" alt="demo"> | ||
|
||
## Features | ||
|
||
- Search character by keyword, show character name and image from search result | ||
- Search staff by keyword, show staff name and photo from search result | ||
|
||
Please implement above feature with | ||
|
||
- React.js (Next.js) and Hook | ||
- Material-UI | ||
- GraphQL (Apollo GraphQL) | ||
|
||
### Improvements | ||
|
||
- No matched result handling | ||
- Error handling | ||
- and any improvements you want to do... | ||
|
||
## Development | ||
|
||
```bash | ||
$ yarn install --frozen-lockfile | ||
$ yarn dev | ||
``` | ||
|
||
## GraphQL API Document | ||
|
||
- [anilist GraphiQL](https://anilist.co/graphiql) | ||
|
||
- Character | ||
- Staff | ||
|
||
- [API docs](https://anilist.gitbook.io/anilist-apiv2-docs/) | ||
|
||
## Material-UI component you may want to use | ||
|
||
- Box | ||
- Button | ||
- CircularProgress | ||
- Container | ||
- FormControl | ||
- InputLabel | ||
- MenuItem | ||
- Select | ||
- TextField | ||
- and any components you want to use... | ||
|
||
[Material-UI](https://material-ui.com/) | ||
|
||
## Contact | ||
|
||
If you have any problems, please contact [email protected] or open an issue. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { useMemo } from "react"; | ||
import { ApolloClient, HttpLink, InMemoryCache } from "@apollo/client"; | ||
|
||
let apolloClient = null; | ||
|
||
function createApolloClient() { | ||
return new ApolloClient({ | ||
ssrMode: false, | ||
link: new HttpLink({ | ||
uri: "https://graphql.anilist.co", | ||
}), | ||
cache: new InMemoryCache(), | ||
}); | ||
} | ||
|
||
export function initializeApollo(initialState = null) { | ||
const _apolloClient = apolloClient ?? createApolloClient(); | ||
|
||
if (initialState) { | ||
const existingCache = _apolloClient.extract(); | ||
|
||
_apolloClient.cache.restore({ ...existingCache, ...initialState }); | ||
} | ||
|
||
if (typeof window === "undefined") return _apolloClient; | ||
|
||
if (!apolloClient) apolloClient = _apolloClient; | ||
return _apolloClient; | ||
} | ||
|
||
export function useApollo(initialState) { | ||
const store = useMemo(() => initializeApollo(initialState), [initialState]); | ||
return store; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/// <reference types="next" /> | ||
/// <reference types="next/types/global" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start" | ||
}, | ||
"dependencies": { | ||
"@apollo/client": "^3.3.6", | ||
"@material-ui/core": "^4.11.2", | ||
"graphql": "^15.4.0", | ||
"next": "^10.0.5", | ||
"react": "^17.0.1", | ||
"react-dom": "^17.0.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^14.14.20", | ||
"@types/react": "^17.0.0", | ||
"typescript": "^4.1.3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import Head from "next/head"; | ||
import { createMuiTheme } from "@material-ui/core"; | ||
import { ThemeProvider } from "@material-ui/core/styles"; | ||
import CssBaseline from "@material-ui/core/CssBaseline"; | ||
import { ApolloProvider } from "@apollo/client"; | ||
import { useApollo } from "../lib/apolloClient"; | ||
|
||
export default function MyApp(props) { | ||
const { Component, pageProps } = props; | ||
const theme = createMuiTheme(); | ||
const apolloClient = useApollo(pageProps.initialApolloState); | ||
|
||
React.useEffect(() => { | ||
// Remove the server-side injected CSS. | ||
const jssStyles = document.querySelector("#jss-server-side"); | ||
if (jssStyles) { | ||
jssStyles.parentElement.removeChild(jssStyles); | ||
} | ||
}, []); | ||
|
||
return ( | ||
<React.Fragment> | ||
<Head> | ||
<title>Ani Search</title> | ||
<meta | ||
name="viewport" | ||
content="minimum-scale=1, initial-scale=1, width=device-width" | ||
/> | ||
</Head> | ||
<ThemeProvider theme={theme}> | ||
<ApolloProvider client={apolloClient}> | ||
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} | ||
<CssBaseline /> | ||
<Component {...pageProps} /> | ||
</ApolloProvider> | ||
</ThemeProvider> | ||
</React.Fragment> | ||
); | ||
} | ||
|
||
MyApp.propTypes = { | ||
Component: PropTypes.elementType.isRequired, | ||
pageProps: PropTypes.object.isRequired, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React from "react"; | ||
import Document, { Html, Head, Main, NextScript } from "next/document"; | ||
import { ServerStyleSheets } from "@material-ui/core/styles"; | ||
|
||
export default class MyDocument extends Document { | ||
render() { | ||
return ( | ||
<Html lang="en"> | ||
<Head> | ||
<meta charSet="utf-8" /> | ||
</Head> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
); | ||
} | ||
} | ||
|
||
MyDocument.getInitialProps = async (ctx) => { | ||
const sheets = new ServerStyleSheets(); | ||
const originalRenderPage = ctx.renderPage; | ||
|
||
ctx.renderPage = () => | ||
originalRenderPage({ | ||
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />), | ||
}); | ||
|
||
const initialProps = await Document.getInitialProps(ctx); | ||
|
||
return { | ||
...initialProps, | ||
// Styles fragment is rendered after the app and page rendering finish. | ||
styles: [ | ||
...React.Children.toArray(initialProps.styles), | ||
sheets.getStyleElement(), | ||
], | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import * as React from "react"; | ||
import { Container } from "@material-ui/core"; | ||
import { makeStyles } from "@material-ui/core/styles"; | ||
|
||
import { gql, useLazyQuery } from "@apollo/client"; | ||
|
||
export const CHARACTER_QUERY = gql` | ||
query queryCharacter($search: String!) { | ||
# TODO | ||
} | ||
`; | ||
|
||
export const STAFF_QUERY = gql` | ||
query queryStaff($search: String!) { | ||
# TODO | ||
} | ||
`; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
// TODO | ||
})); | ||
|
||
function AniSearch() { | ||
const classes = useStyles(); | ||
|
||
// TODO | ||
|
||
return <Container>{/* TODO */}</Container>; | ||
} | ||
|
||
export default AniSearch; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es5", | ||
"lib": [ | ||
"dom", | ||
"dom.iterable", | ||
"esnext" | ||
], | ||
"allowJs": true, | ||
"skipLibCheck": true, | ||
"strict": false, | ||
"forceConsistentCasingInFileNames": true, | ||
"noEmit": true, | ||
"esModuleInterop": true, | ||
"module": "esnext", | ||
"moduleResolution": "node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"jsx": "preserve" | ||
}, | ||
"include": [ | ||
"next-env.d.ts", | ||
"**/*.ts", | ||
"**/*.tsx" | ||
], | ||
"exclude": [ | ||
"node_modules" | ||
] | ||
} |
Oops, something went wrong.