Fix about and home ssr

Seto Elkahfi committed Aug 7, 2023 at 23:34 UTC 48228a84d8fd5ec4b8cacab6fb0ed1c10daeffeb
8 files changed +86 -37
server/server.tsx
+6 -10
@@ -27,23 +27,19 @@ server.get('*', (req, res, next) => {
27 return next();
28 }
29
30 - const promise = activeRoute.fetchInitialData
31 - ? activeRoute.fetchInitialData(req.path)
32 - : Promise.resolve();
30 + activeRoute
31 + .fetchInitialData(req.path, firebase)
32 + .then((initialData) => {
33
34 - promise
35 - .then((data) => {
34 + console.log('data', initialData);
35
36 const app = ReactDOMServer.renderToString(
37 <StaticRouter location={req.url}>
39 - <App firebase={firebase} />
38 + <App initialData={initialData} />
39 </StaticRouter>
40 );
41
42 const indexFile = path.resolve('./build/index.html');
44 - const initialData = JSON.stringify(data);
45 -
46 - console.log('data', initialData);
43 console.log('req.path', req.path);
44
45 fs.readFile(indexFile, 'utf8', (err, data) => {
@@ -56,7 +52,7 @@ server.get('*', (req, res, next) => {
52 .replace(
53 '<div id="root"></div>',
54 `<div id="root">${app}</div>`
59 - )
55 + )
56 .replace(
57 '<script id="initial-data"></script>',
58 `<script id="initial-data" type="application/json">
src/components/About.tsx
+19 -4
@@ -2,9 +2,11 @@ import React, { Component } from 'react';
2 import { FormattedMessage } from 'react-intl';
3 import Firebase from './Firebase';
4 import app from 'firebase/app';
5 +import { InitialData } from '../shared/routes';
6
7 type AboutProps = {
8 firebase: Firebase | null
9 + initialData?: InitialData
10 }
11
12 type AboutState = {
@@ -20,13 +22,26 @@ class About extends Component<AboutProps, AboutState> {
22 constructor(props: AboutProps) {
23 super(props);
24 this.aboutRef = this.props.firebase?.aboutRef();
23 - this.state = {
24 - contentMain: "Loading ...",
25 - contentSkills: "Loading ...",
26 - updatedAt: "Loading ..."
25 + if (this.props.initialData) {
26 + console.log(this.props.initialData);
27 + this.state = {
28 + contentMain: this.props.initialData['data']['contentMain'],
29 + contentSkills: this.props.initialData['data']['contentSkills'],
30 + updatedAt: this.props.initialData['data']['updatedAt']
31 + }
32 + } else {
33 + this.state = {
34 + contentMain: "Loading ...",
35 + contentSkills: "Loading ...",
36 + updatedAt: "Loading ..."
37 + }
38 }
39 }
40 +
41 componentDidMount() {
42 + if (this.props.initialData)
43 + return;
44 +
45 this.aboutRef?.on('value', (snapshot) => {
46 let items = snapshot?.val();
47 this.setState({
src/components/App.tsx
+8 -3
@@ -20,6 +20,7 @@ import messagesFr from "../translations/fr.json";
20 import messagesZh from "../translations/zh.json";
21 import messagesEs from "../translations/es.json";
22 import messagesJa from "../translations/ja.json";
23 +import { InitialData } from '../shared/routes';
24
25 addLocaleData([
26 ...localeEn,
@@ -37,8 +38,9 @@ let i18nConfig = {
38 messages: messages_en
39 };
40
40 -type AppProps = {
41 - firebase: Firebase
41 +export type AppProps = {
42 + firebase?: Firebase
43 + initialData?: InitialData
44 }
45
46 type AppState = {
@@ -71,7 +73,10 @@ class App extends Component<AppProps, AppState> {
73 <IntlProvider locale={i18nConfig.language} messages={i18nConfig.messages}>
74 <FirebaseContext.Provider value={this.props.firebase}>
75 <Header onChangeLanguage={this.onChangeLanguage.bind(this)} />
74 - <Main />
76 + <Main
77 + firebase={this.props.firebase}
78 + initialData={this.props.initialData}
79 + />
80 <FooterLinks />
81 </FirebaseContext.Provider>
82 </IntlProvider >
src/components/Firebase/context.ts
+1 -1
@@ -1,6 +1,6 @@
1 import React from 'react';
2 import Firebase from './firebase';
3
4 -const FirebaseContext = React.createContext<Firebase | null>(null);
4 +const FirebaseContext = React.createContext<Firebase | undefined>(undefined);
5
6 export default FirebaseContext;
\ No newline at end of file
src/components/FooterLinks.tsx
-5
@@ -41,11 +41,6 @@ const FooterLinks = () => (
41 defaultMessage="About"
42 description="About link" />
43 </Link>
44 - <Link to='/cv' style={linkStyle}>
45 - <FormattedMessage id="header.cv"
46 - defaultMessage="CV"
47 - description="CV link" />
48 - </Link>
44 </p>
45 </div>
46 </footer>
src/components/Main.tsx
+11 -3
@@ -1,6 +1,7 @@
1 import React from 'react';
2 import { Switch, Route } from 'react-router-dom';
3 import routes from '../shared/routes';
4 +import { AppProps } from './App';
5
6 const mainStyle = {
7 marginTop: 20,
@@ -16,7 +17,11 @@ const contentStyle = {
17 backgroundColor: 'rgba(52, 52, 52, 0.6)'
18 }
19
19 -const Main = () => (
20 +const Main = (props: AppProps) => {
21 +
22 + console.log('MAIN', props.initialData);
23 +
24 + return (
25 <main style={mainStyle}>
26 <section className="py-5 text-center container">
27 <div className="row py-lg-5">
@@ -25,7 +30,10 @@ const Main = () => (
30 {
31 routes.map((route, index) => (
32 <Route key={index} exact={route.exact} path={route.path} >
28 - <route.component />
33 + <route.component
34 + firebase={props.firebase}
35 + initialData={props.initialData}
36 + />
37 </Route>
38 ))
39 }
@@ -34,6 +42,6 @@ const Main = () => (
42 </div>
43 </section>
44 </main>
37 -);
45 +)};
46
47 export default Main;
\ No newline at end of file
src/shared/api.ts
+30 -1
@@ -1,4 +1,5 @@
1 import axios from "axios";
2 +import Firebase from "../components/Firebase";
3
4 axios.defaults.baseURL = 'https://api.musik88.com/api/v1/';
5
@@ -7,6 +8,34 @@ export const getCaraousel = () => {
8 .then(res => {
9 console.log(res);
10 const files = res.data.audio_files;
10 - return files;
11 + const obj = {
12 + path: '/',
13 + data: files
14 + };
15 + return obj;
16 })
17 }
18 +
19 +export const getAbout = (path: string, firebase: Firebase) => {
20 + return firebase
21 + .aboutRef()
22 + .once('value')
23 + .then((snapshot) => {
24 + return {
25 + path: path,
26 + data: snapshot.val()
27 + }
28 + });
29 +}
30 +
31 +export const getContact = (path: string, firebase: Firebase) => {
32 + return firebase
33 + .contactRef()
34 + .once('value')
35 + .then((snapshot) => {
36 + return {
37 + path: path,
38 + data: snapshot.val()
39 + }
40 + });
41 +}
\ No newline at end of file
src/shared/routes.tsx
+11 -10
@@ -1,15 +1,21 @@
1 import Home from '../components/Home';
2 import About from '../components/About';
3 import React from 'react';
4 -import { getCaraousel } from './api';
4 +import { getAbout, getCaraousel, getContact } from './api';
5 import Contact from '../components/Contact';
6 import Cv from '../components/Cv';
7 +import Firebase from '../components/Firebase';
8
9 export interface Route {
10 path: string;
11 component: React.ComponentType<any>;
12 exact?: boolean;
12 - fetchInitialData?: (path?: string) => Promise<any>;
13 + fetchInitialData: (path: string, firebase: Firebase) => Promise<InitialData>;
14 +}
15 +
16 +export type InitialData = {
17 + data: any;
18 + path: string;
19 }
20
21 // Desc: Routes for the application
@@ -18,22 +24,17 @@ const routes: Route[] = [
24 path: '/',
25 component: Home,
26 exact: true,
21 - fetchInitialData: () => getCaraousel()
27 + fetchInitialData: (path, firebase) => getCaraousel()
28 },
29 {
30 path: '/about',
31 component: About,
26 - fetchInitialData: () => Promise.resolve()
27 - },
28 - {
29 - path: '/cv',
30 - component: Cv,
31 - fetchInitialData: () => Promise.resolve()
32 + fetchInitialData: getAbout
33 },
34 {
35 path: '/contact',
36 component: Contact,
36 - fetchInitialData: () => Promise.resolve()
37 + fetchInitialData: getContact
38 }
39 ];
40