diff --git a/README.md b/README.md index 64e343e..195e5c4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,33 @@ -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). +# React App + Firebase Auth & Realtime Database + +This project built with [Create React App](https://github.com/facebook/create-react-app) allows you to add / modify / delete character sheets for novels. This application uses Firebase for authentication and database. + +## :fire: Prerequisite (Environment variables) + +To use this app, you need to create an `.env` file at the root of the project in which you add the app's Firebase configuration (Realtime Database). Here is an example below: + +:warning: **These are dummy data, do not copy them as they are in your project.** + +```#!/bin/bash +# .env + +REACT_APP_FIREBASE_API_KEY=ffa6eeb0-3ba7-4091-bd0b-98011315365a +REACT_APP_FIREBASE_AUTH_DOMAIN=auth-domain.firebaseapp.com +REACT_APP_FIREBASE_DATABASE_URL=https://database-url.firebaseio.com +REACT_APP_FIREBASE_PROJECT_ID=project-id-name +REACT_APP_FIREBASE_STORAGE_BUCKET=storage-bucket.appspot.com +REACT_APP_FIREBASE_MESSAGING_SENDER_ID=497108424 +REACT_APP_FIREBASE_APP_ID=9:497108424:web:96ba329da5b0 +``` + +## Resources: Frameworks & libraries + +* React +* Typescript +* Material UI +* Firebase Realtime Database +* React Router +* React i18next (translations) ## Available Scripts @@ -36,9 +65,3 @@ If you aren’t satisfied with the build tool and configuration choices, you can Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). diff --git a/package.json b/package.json index b27a46c..7001ee1 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "dependencies": { "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.56", "@react-firebase/auth": "^0.2.10", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", diff --git a/src/App.tsx b/src/App.tsx index 13193ac..487fd7e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import { firebaseConfig } from './config/config'; import SignIn from './components/login/SignIn'; import Dashboard from './components/Dashboard'; +import WithSplashScreen from './components/splash-screen/WithSplashScreen'; const App = () => { const signInWithGoogle = React.useCallback(async () => { @@ -44,4 +45,4 @@ const App = () => { ); }; -export default App; +export default WithSplashScreen(App); diff --git a/src/components/Dashboard.tsx b/src/components/Dashboard.tsx index 7153049..4aaebaa 100644 --- a/src/components/Dashboard.tsx +++ b/src/components/Dashboard.tsx @@ -136,8 +136,7 @@ const Dashboard = ({ signOut }: DashboardProps) => { }; const handleDrawerClose = () => { setOpen(false); - }; - // const fixedHeightPaper = clsx(classes.paper, classes.fixedHeight); + };; const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); diff --git a/src/components/characters-list/CharactersList.tsx b/src/components/characters-list/CharactersList.tsx index 69cc28e..c062be2 100644 --- a/src/components/characters-list/CharactersList.tsx +++ b/src/components/characters-list/CharactersList.tsx @@ -14,13 +14,13 @@ interface CharactersListProps { const CharactersList = ({ classes }: CharactersListProps) => { return ( - <> - - - - - - + <> + + + + + + ); } diff --git a/src/components/characters-list/CharactersTable.tsx b/src/components/characters-list/CharactersTable.tsx index dcddea4..c0eb440 100644 --- a/src/components/characters-list/CharactersTable.tsx +++ b/src/components/characters-list/CharactersTable.tsx @@ -1,6 +1,7 @@ import React from 'react'; import * as firebase from 'firebase'; import { useList } from 'react-firebase-hooks/database'; +import { useTranslation } from "react-i18next"; import Link from '@material-ui/core/Link'; import { makeStyles } from '@material-ui/core/styles'; import CircularProgress from '@material-ui/core/CircularProgress'; @@ -9,31 +10,9 @@ import TableBody from '@material-ui/core/TableBody'; import TableCell from '@material-ui/core/TableCell'; import TableHead from '@material-ui/core/TableHead'; import TableRow from '@material-ui/core/TableRow'; - -import { firebaseConfig } from '../../config/config'; - import Title from '../shared/Title'; -// Generate Order Data -interface CreateDataProps { - id: string, - date: string, - name: string, - shipTo: string, - paymentMethod: string, - amount: number, -} -function createData(id: number, date: string, name: string, age: number, occupation: string, role: string) { - return { id, date, name, age, occupation, role }; -} - -const rows = [ - createData(0, '16 Mar, 2019', 'Matt Suderland', 45, 'Hero', 'Master'), - createData(1, '16 Mar, 2019', 'Phil Rigor', 32, 'Singer', 'Major'), - createData(2, '16 Mar, 2019', 'Ellen Mitchell', 27, 'Journalist', 'Minor'), - createData(3, '16 Mar, 2019', 'Paula Cloud', 89, 'Driver', 'Master'), - createData(4, '15 Mar, 2019', 'Edgard Lazd', 21, 'Soldier', 'Major'), -]; +import Alert from '@material-ui/lab/Alert'; function preventDefault(event: any) { event.preventDefault(); @@ -50,8 +29,10 @@ const useStyles = makeStyles((theme) => ({ }, })); -export default function Orders() { +const CharactersTable = () => { const classes = useStyles(); + const { t } = useTranslation(); + const [initializeApp, setInitializeApp] = React.useState(false); const [characters, setCharacters] = React.useState({}); @@ -78,42 +59,51 @@ export default function Orders() { const [snapshots, loading, error] = useList(charactersRef); return ( - - Recent Characters + <> + {t('characters.title')} + {error && + + Error: {error} + + } {loading &&
} {!loading && snapshots && - - - - Date - Name - Age - Occupation - Role - - - - {snapshots.map((row) => ( - - {row.val().createdAt} - {row.val().name} - {row.val().age} - {row.val().occupation} - {row.val().role} + <> +
+ + + {t('characters.tablehead.date')} + {t('characters.tablehead.name')} + {t('characters.tablehead.age')} + {t('characters.tablehead.occupation')} + {t('characters.tablehead.role')} - ))} - -
+ + + {snapshots.map((row) => ( + + {row.val().createdAt} + {row.val().name} + {row.val().age} + {row.val().occupation} + {row.val().role} + + ))} + + +
+ + {t('characters.button.seemore')} + +
+ } -
- - See more orders - -
-
+ ); } + +export default CharactersTable; diff --git a/src/components/login/SignIn.tsx b/src/components/login/SignIn.tsx index 97ebf04..4724744 100644 --- a/src/components/login/SignIn.tsx +++ b/src/components/login/SignIn.tsx @@ -15,7 +15,6 @@ import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; import Container from '@material-ui/core/Container'; -import Launch from '../layout/Launch'; import Copyright from '../layout/Copyright'; import GoogleLogo from '../../styles/images/google_logo.svg'; @@ -57,9 +56,6 @@ const SignIn = ({ signInWithGoogle, signInAnonymously }: SignInProps) => { return ( <> - {isSignedIn && - - } {!isSignedIn && diff --git a/src/components/splash-screen/WithSplashScreen.tsx b/src/components/splash-screen/WithSplashScreen.tsx new file mode 100644 index 0000000..67e4229 --- /dev/null +++ b/src/components/splash-screen/WithSplashScreen.tsx @@ -0,0 +1,40 @@ +import React, { Component } from 'react'; +import Launch from '../layout/Launch'; + +const WithSplashScreen =

( + WrappedComponent: React.ComponentType

+ ) => { + return class extends Component { + constructor(props: Readonly

) { + super(props); + this.state = { + loading: true, + }; + } + + componentDidMount() { + try { + setTimeout(() => { + this.setState({ + loading: false, + }); + }, 4000) + } catch (err) { + console.log(err); + this.setState({ + loading: false, + }); + } + } + + render() { + // while checking user session, show "loading" message + if (this.state.loading) return ; + + // otherwise, show the desired route + return ; + } + }; +} + +export default WithSplashScreen; diff --git a/src/db/characters.json b/src/db/characters.json index b9f0ec6..7b6b028 100644 --- a/src/db/characters.json +++ b/src/db/characters.json @@ -4,6 +4,6 @@ { "id": 2, "createdAt": "16 Mar, 2019", "name": "Phil Rigor", "age": 32, "occupation": "Singer", "role": "Major" }, { "id": 3, "createdAt": "16 Mar, 2019", "name": "Ellen Mitchell", "age": 27, "occupation": "Journalist", "role": "Minor" }, { "id": 4, "createdAt": "16 Mar, 2019", "name": "Paula Cloud", "age": 58, "occupation": "Driver", "role": "Master" }, - { "id": 5, "createdAt": "16 Mar, 2019", "name": "Edgard Lazd", "age": 21, "occupation": "Solder", "role": "Major" } + { "id": 5, "createdAt": "16 Mar, 2019", "name": "Edgard Lazd", "age": 21, "occupation": "Soldier", "role": "Major" } ] } \ No newline at end of file diff --git a/src/translations/en.json b/src/translations/en.json index c666c34..993ecb0 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -17,5 +17,18 @@ "signinwithgoogle": "Sign In with Google", "signinanon": "Sign In Anonymously" } + }, + "characters": { + "title": "Recent characters", + "tablehead": { + "date": "Date", + "name": "Name", + "age": "Age", + "occupation": "Occupation", + "role": "Role" + }, + "button": { + "seemore": "See more characters" + } } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 8df4250..416195a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1941,6 +1941,17 @@ dependencies: "@babel/runtime" "^7.4.4" +"@material-ui/lab@^4.0.0-alpha.56": + version "4.0.0-alpha.56" + resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz#ff63080949b55b40625e056bbda05e130d216d34" + integrity sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw== + dependencies: + "@babel/runtime" "^7.4.4" + "@material-ui/utils" "^4.10.2" + clsx "^1.0.4" + prop-types "^15.7.2" + react-is "^16.8.0" + "@material-ui/styles@^4.10.0": version "4.10.0" resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071"