WIp

Seto Elkahfi committed Aug 3, 2023 at 11:35 UTC 24bc90a0acf7fa01e92bb4160db4158b77d0788a
9 files changed +104 -66
README.md
+3
@@ -7,6 +7,9 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
7 3. Run `npm run build` to build the project.
8 4. RUn `firebase deploy` to deploy the new build.
9
10 +## SSR
11 +
12 +https://ui.dev/react-router-server-rendering
13
14 ## Available Scripts
15
public/index.html
+1
@@ -14,6 +14,7 @@ Just like me, you know nothing :)
14 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
15 <script src="https://cdn.jsdelivr.net/jquery.supersized/3.2.7/core/js/supersized.core.3.2.1.min.js"></script>
16 <script type="text/javascript">$(function(e){e.supersized({start_slide:0,new_window:1,image_protect:1,min_width:0,min_height:0,vertical_center:1,horizontal_center:1,fit_always:0,fit_portrait:1,fit_landscape:0,slides:[{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/kazvan-1.jpg",title:"Image Credit: Maria Kazvan"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/kazvan-3.jpg",title:"Image Credit: Maria Kazvan"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/wojno-1.jpg",title:"Image Credit: Colin Wojno"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/wojno-2.jpg",title:"Image Credit: Colin Wojno"},{image:"https://buildinternet.s3.amazonaws.com/projects/supersized/3.2/slides/wojno-3.jpg",title:"Image Credit: Colin Wojno"}]})});</script>
17 + <script id="initial-data"></script>
18 </head>
19 <body>
20 <noscript>You need to enable JavaScript to run this app.</noscript>
server/server.tsx
+43 -17
@@ -5,7 +5,7 @@ import App from '../src/components/App'
5 import path from 'path';
6 import fs from 'fs';
7 import { StaticRouter, matchPath } from 'react-router-dom';
8 -import routes from '../shared/routes';
8 +import routes from '../src/shared/routes';
9 import Firebase from '../src/components/Firebase';
10 import firebaseInstance from '../src/components/Firebase/config';
11
@@ -19,28 +19,54 @@ server.get('*', (req, res, next) => {
19
20 const activeRoute = routes.find((route) =>
21 matchPath(route.path, req.url)
22 - ) || {}
22 + )
23
24 const firebase = new Firebase('en', firebaseInstance.database());
25
26 - const app = ReactDOMServer.renderToString(
27 - <StaticRouter location={req.url}>
28 - <App firebase={firebase} />
29 - </StaticRouter>
30 - );
26 + if (!activeRoute) {
27 + return next();
28 + }
29
32 - const indexFile = path.resolve('./build/index.html');
30 + const promise = activeRoute.fetchInitialData
31 + ? activeRoute.fetchInitialData(req.path)
32 + : Promise.resolve();
33
34 - fs.readFile(indexFile, 'utf8', (err, data) => {
35 - if (err) {
36 - console.error('Something went wrong:', err);
37 - return res.status(500).send('Oops, better luck next time!');
38 - }
34 + promise
35 + .then((data) => {
36
40 - return res.send(
41 - data.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
42 - );
43 - });
37 + const app = ReactDOMServer.renderToString(
38 + <StaticRouter location={req.url}>
39 + <App firebase={firebase} />
40 + </StaticRouter>
41 + );
42 +
43 + const indexFile = path.resolve('./build/index.html');
44 + const initialData = JSON.stringify(data);
45 +
46 + console.log('data', initialData);
47 + console.log('req.path', req.path);
48 +
49 + fs.readFile(indexFile, 'utf8', (err, data) => {
50 + if (err) {
51 + console.error('Something went wrong:', err);
52 + return res.status(500).send('Oops, better luck next time!');
53 + }
54 + return res.send(
55 + data
56 + .replace(
57 + '<div id="root"></div>',
58 + `<div id="root">${app}</div>`
59 + )
60 + .replace(
61 + '<script id="initial-data"></script>',
62 + `<script id="initial-data" type="application/json">
63 + window.__DATA__=${initialData}
64 + </script>`
65 + )
66 + );
67 + });
68 + })
69 + .catch(next);
70 });
71
72 server.listen(3002, () => {
shared/routes.tsx deleted
-16
@@ -1,16 +0,0 @@
1 -import Home from '../src/components/Home';
2 -import About from '../src/components/About';
3 -
4 -// Desc: Routes for the application
5 -const routes = [
6 - {
7 - path: '/',
8 - component: Home,
9 - },
10 - {
11 - path: '/about',
12 - component: About,
13 - }
14 -];
15 -
16 -export default routes;
\ No newline at end of file
src/components/App.tsx
+2 -4
@@ -47,8 +47,6 @@ type AppState = {
47
48 class App extends Component<AppProps, AppState> {
49
50 - firebase: Firebase | null = null;
51 -
50 onChangeLanguage(language: string) {
51 switch (language) {
52 case 'se': i18nConfig.messages = messages_sv; break;
@@ -63,8 +61,8 @@ class App extends Component<AppProps, AppState> {
61 }
62 i18nConfig.language = language;
63 this.setState({ language: language })
66 - if (this.firebase) {
67 - this.firebase.setLanguage(language)
64 + if (this.props.firebase) {
65 + this.props.firebase.setLanguage(language)
66 }
67 }
68
src/components/Firebase/firebase.ts
+4 -3
@@ -7,15 +7,16 @@ class Firebase {
7 language!: string;
8
9 public onLanguageChangedCallback: (() => void) | null = null
10 - private static instace: Firebase
10 + private static instance: Firebase
11
12 constructor(language: string, db: app.database.Database) {
13
14 - if (Firebase.instace)
15 - return Firebase.instace
14 + if (Firebase.instance)
15 + return Firebase.instance
16
17 this.db = db;
18 this.language = language;
19 + Firebase.instance = this;
20 }
21
22 setLanguage(language: string) {
src/components/Main.tsx
+8 -26
@@ -1,11 +1,7 @@
1 import React from 'react';
2 import { Switch, Route } from 'react-router-dom';
3 -import Home from './Home';
4 -import About from './About';
5 -import Cv from './Cv';
6 -import Contact from './Contact';
3 import { FirebaseContext } from './Firebase';
8 -import AudioPlayer from './AudioPlayer';
4 +import routes from '../shared/routes';
5
6 const mainStyle = {
7 marginTop: 20,
@@ -27,27 +23,13 @@ const Main = () => (
23 <div className="row py-lg-5">
24 <div className="col-lg-6 col-md-8 mx-auto" style={contentStyle}>
25 <Switch>
30 - <Route exact path='/'>
31 - <FirebaseContext.Consumer>
32 - {firebase => <Home firebase={firebase} />}
33 - </FirebaseContext.Consumer>
34 - </Route>
35 - <Route path='/about'>
36 - <FirebaseContext.Consumer>
37 - {firebase => <About firebase={firebase} />}
38 - </FirebaseContext.Consumer>
39 - </Route>
40 - <Route path='/cv'>
41 - <FirebaseContext.Consumer>
42 - {firebase => <Cv firebase={firebase} />}
43 - </FirebaseContext.Consumer>
44 - </Route>
45 -
46 - <Route path='/contact'>
47 - <FirebaseContext.Consumer>
48 - {firebase => <Contact firebase={firebase} />}
49 - </FirebaseContext.Consumer>
50 - </Route>
26 + {
27 + routes.map((route, index) => (
28 + <Route key={index} path={route.path}>
29 + <route.component />
30 + </Route>
31 + ))
32 + }
33 </Switch>
34 </div>
35 </div>
src/shared/api.ts new
+12
@@ -0,0 +1,12 @@
1 +import axios from "axios";
2 +
3 +axios.defaults.baseURL = 'https://api.musik88.com/api/v1/';
4 +
5 +export const getCaraousel = () => {
6 + return axios.get(`/carousel`)
7 + .then(res => {
8 + console.log(res);
9 + const files = res.data.audio_files;
10 + return files;
11 + })
12 +}
src/shared/routes.tsx new
+31
@@ -0,0 +1,31 @@
1 +import Home from '../components/Home';
2 +import About from '../components/About';
3 +import React from 'react';
4 +import { getCaraousel } from './api';
5 +
6 +export interface Route {
7 + path: string;
8 + component: React.ComponentType<any>;
9 + fetchInitialData?: (path?: string) => Promise<any>;
10 +}
11 +
12 +// Desc: Routes for the application
13 +const routes: Route[] = [
14 + {
15 + path: '/',
16 + component: Home,
17 + fetchInitialData: (path = '') => getCaraousel()
18 + },
19 + {
20 + path: '/about',
21 + component: About,
22 + fetchInitialData: (path = '') => Promise.resolve()
23 + },
24 + {
25 + path: '/cv',
26 + component: About,
27 + fetchInitialData: (path = '') => Promise.resolve()
28 + }
29 +];
30 +
31 +export default routes;
\ No newline at end of file