Skip to content

Commit bba95f5

Browse files
authored
Merge pull request #4 from ckhawks/jan24-again
ENCHANGED PAGE ROUTING AND COMPONENT LOADING (WITH ANIMATIONS/RIZZ) A…
2 parents 03e6654 + cbbfe7d commit bba95f5

File tree

19 files changed

+387
-172
lines changed

19 files changed

+387
-172
lines changed

backend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"name": "backend",
33
"version": "1.0.0",
44
"description": "",
5-
"main": "index.js",
5+
"main": "src/index.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1",
8-
"start": "nodemon --exec babel-node index.js"
8+
"start": "nodemon --exec babel-node src/index.js"
99
},
1010
"author": "",
1111
"license": "ISC",

backend/index.js renamed to backend/src/index.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,38 @@
1+
const { createServer } = require('http');
12
const express = require('express');
23
const cors = require('cors');
34
const app = express();
45
const port = 5500;
56

7+
8+
9+
const server = createServer(app);
10+
611
app.use(express.urlencoded({ extended: true }));
712
app.use(express.json());
813

914
app.use(cors());
1015

16+
// const corsOptions = {
17+
// origin: (origin, callback) => {
18+
// if (
19+
// process.env.DEPLOYMENT_ENV === 'development' ||
20+
// process.env.NODE_ENV === 'test' ||
21+
// knownDomains.indexOf(origin) !== -1
22+
// ) {
23+
// callback(null, true);
24+
// } else {
25+
// console.error('Request submitted from unknown origin', origin);
26+
// callback(new Error('Not allowed'));
27+
// }
28+
// }
29+
// };
30+
// // enable CORS - Cross Origin Resource Sharing
31+
// app.use('*', cors(corsOptions));
32+
33+
const routes = require('./routes/');
34+
app.use('/v1', routes);
35+
1136
// https://dev.to/richienabuk/setting-up-express-js-rest-api-postgres-and-sequelize-orm-with-es6-4m08
1237

1338
app.get('/', (req, res) => {
@@ -52,6 +77,8 @@ app.get('/people', (req, res) => {
5277
res.json(data);
5378
});
5479

55-
app.listen(port, () => {
80+
server.listen(port, () => {
5681
console.log(`Example app listening on port ${port}`);
57-
});
82+
});
83+
84+
module.exports = server;

backend/src/routes/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// import { BaseRoute } from 'av-common';
2+
import express, { Request, Response } from 'express';
3+
4+
const userRoutes = require('./user.route');
5+
6+
const router = express.Router();
7+
8+
router
9+
.route('/status')
10+
// .get(useAuth, (req: Request, res: Response) =>
11+
.get((req, res) =>
12+
res.json({ message: 'Success!' })
13+
);
14+
15+
router.use('/users', userRoutes);
16+
17+
module.exports = router;

backend/src/routes/user.route.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
const express = require('express');
2+
// const { GetCompanyCategoriesRoute } = require('av-common');
3+
4+
// const controller = require('../../controllers/companyCategory.controller');
5+
6+
// const { checkAuth0Token } = require('../../middlewares/auth');
7+
8+
const router = express.Router();
9+
10+
// router.use(checkAuth0Token);
11+
12+
// const { CompanyCategory } = require('../models');
13+
// const {
14+
// getCompanyCategories
15+
// } = require('../services/companyHierarchy/companyCategory/getCompanyCategories');
16+
// const { captureError } = require('../utils/logs');
17+
// const { buildErrorMsg } = require('../utils/methods');
18+
19+
router
20+
.route('/users')
21+
.get(async (req, res) => {
22+
try {
23+
const response = await getCompanyCategories();
24+
25+
res.json(response);
26+
} catch (error) {
27+
captureError(error);
28+
console.error('getCompanyCategories', error);
29+
res.status(500).send({
30+
message: buildErrorMsg('getting company categories'),
31+
errorType: error.message
32+
});
33+
}
34+
});
35+
36+
router
37+
.route('/users')
38+
.post(async (req, res) => {
39+
try {
40+
const { name } = req.body;
41+
42+
const [companyCategory, created] = await CompanyCategory.findOrCreate({
43+
where: { name: name.toUpperCase().trim() },
44+
attributes: ['id', 'name']
45+
});
46+
47+
if (!created) {
48+
res.status(500).send({
49+
message: `${req.query.name} already exists`,
50+
created
51+
});
52+
}
53+
54+
res.json({ companyCategory, created });
55+
} catch (error) {
56+
captureError(error);
57+
console.error('createAssignee', error);
58+
res.status(500).send({
59+
message: buildErrorMsg('creating a company category')
60+
});
61+
}
62+
});
63+
64+
module.exports = router;

frontend/src/App.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
padding: 0px 20px;
4848
display: flex;
4949
flex-direction: column;
50+
transition: max-width 0.15s ease-in-out;
5051
}
5152

5253
.container-wide {
@@ -55,6 +56,7 @@
5556
padding: 0px 20px;
5657
display: flex;
5758
flex-direction: column;
59+
transition: max-width 0.15s ease-in-out;
5860
}
5961

6062
.vertical-center {

frontend/src/App.js

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,34 @@ import GeistTestPage from './pages/GeistTest/GeistTestPage';
2020
import LoginPage from './pages/Authentication/LoginPage';
2121
import RegisterPage from "./pages/Authentication/RegisterPage";
2222
import GalleryPage from "./pages/Gallery/GalleryPage";
23+
import OrganizePage from "./pages/Organize/OrganizePage";
2324

25+
import BaseLayout from "./pages/BaseLayout";
2426

2527
function App() {
2628
return (
2729

2830
<div className="App">
2931
<BrowserRouter>
3032
<Routes>
31-
<Route path="*" element={<NotFoundPage/>} />
32-
<Route path="/" element={<HomePage/>} />
33-
<Route path="/geist-test" element={<GeistTestPage />} />
34-
<Route path="/login" element={<LoginPage/>} />
35-
<Route path="register" element={<RegisterPage />}/>
36-
<Route path="/gallery" element={<GalleryPage/>}/>
3733

34+
35+
{/* could refactor this to use contexts to inform the layout https://reactjs.org/docs/context.html */}
36+
<Route element={<BaseLayout/>}>
37+
<Route path="*" element={<NotFoundPage/>} />
38+
<Route path="/" element={<HomePage/>} />
39+
<Route path="geist-test" element={<GeistTestPage />} />
40+
</Route>
41+
<Route element={<BaseLayout centered/>}>
42+
<Route path="login" element={<LoginPage/>} />
43+
<Route path="register" element={<RegisterPage />}/>
44+
</Route>
45+
<Route element={<BaseLayout wide/>}>
46+
<Route path="gallery" element={<GalleryPage/>}/>
47+
<Route path="organize" element={<OrganizePage/>}/>
48+
</Route>
49+
50+
{/* Legacy routes */}
3851
<Route path="old" element={<Layout />}>
3952
<Route index element={<Home />} />
4053
<Route path="about" element={<About />} />
@@ -47,12 +60,7 @@ function App() {
4760
<Route path="test" element={<Testing />} />
4861
<Route path="*" element={<NotFound />} />
4962
</Route>
50-
{/* <Route path="/" element={<Layout />}>
51-
52-
</Route>
53-
<Route path="geist-test" element={<GeistTestContainer />} />
54-
<Route path="register" element={<RegisterPage />}/>
55-
<Route path="gallery" element={<GalleryPage/>}/> */}
63+
5664
</Routes>
5765
</BrowserRouter>
5866
</div>

frontend/src/components/NavbarMenu/NavbarMenu.css

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,14 @@
6767
display: flex;
6868
align-items: center;
6969
justify-content: flex-start;
70-
7170
}
7271

73-
.navbar-logo:hover {
74-
transform: translate3d(0px,-1px,0px);
72+
.navbar-logo>.tabs {
73+
max-height: 46px;
74+
}
75+
76+
.navbar-logo>a>.image:hover {
77+
transform: translate3d(0px,-2px,0px);
7578
}
7679

7780
.navbar-middle {

frontend/src/components/NavbarMenu/NavbarMenu.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ const NavbarMenu = (props) => {
3535
<div className="navbar-center">
3636
<div className={"navbar " + (props.wide ? "container-wide" : "container-regular")}>
3737
<div className="navbar-logo">
38-
<a href="/">
38+
<Link to="/">
3939
<Image height="32px" mr={.5} src={StellectionLogo} draggable={false} title="Logo" alt="Stellection"/>
40-
</a>
40+
</Link>
41+
<Tabs initialValue={url} hideDivider hideBorder onChange={navTabsChangeHandler} value={url}>
42+
<Tabs.Item label="Geist Test" value="geist-test" />
43+
</Tabs>
4144

4245
</div>
4346
<div className="navbar-middle">
4447
<Tabs initialValue={url} hideDivider hideBorder onChange={navTabsChangeHandler} value={url}>
45-
<Tabs.Item label="Collect" value="geist-test" />
48+
<Tabs.Item label="Collect" value="collect" />
4649
<Tabs.Item label="Organize" value="organize" />
4750
<Tabs.Item label="Browse" value="gallery" />
4851
</Tabs>

frontend/src/hooks/useApi.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const swrApi = async (payload) => {
1212
body,
1313
contentType: contentTypeSent,
1414
header,
15-
token,
15+
// token,
1616
params,
1717
formData,
18-
showError = true
18+
// showError = true
1919
} = payload;
2020
let url = `${BASE_URL}/${path}`;
2121
if (params) {

frontend/src/hooks/useApi.ts.disabled

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// import { useSelector } from 'react-redux';
2+
// import { toast } from 'react-toastify';
3+
import useSWR, { SWRResponse, useSWRConfig } from 'swr';
4+
import ScopedMutator from 'swr';
5+
// import { TOAST_OPTIONS } from '../constants/toast';
6+
// import { getTokenSelector } from '../selectors/auth';
7+
// import { getCompanyTemp } from '../utils/company';
8+
// import { logoutRedirect } from '../utils/general';
9+
10+
// const BASE_URL = process.env.BACKEND_API_URL;
11+
const BASE_URL = "http://127.0.0.1:5500/v1";
12+
13+
const defaultContentType = 'application/json';
14+
15+
interface ApiParams<U> {
16+
path: string;
17+
method: string;
18+
body?: U;
19+
contentType?: string;
20+
header?: Record<string, string>;
21+
params?: Record<string, string>;
22+
formData?: FormData;
23+
showError?: boolean;
24+
}
25+
26+
type ApiFunctionParams<U> = ApiParams<U> & {
27+
token?: string;
28+
};
29+
30+
const swrApi = async <T, U>(payload: ApiFunctionParams<U>): Promise<T> => {
31+
const {
32+
path,
33+
method,
34+
body,
35+
contentType: contentTypeSent,
36+
header,
37+
token,
38+
params,
39+
formData,
40+
showError = true
41+
} = payload;
42+
let url = `${BASE_URL}/v1/${path}`;
43+
if (params) {
44+
const query = Object.keys(params)
45+
.map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`)
46+
.join('&');
47+
url = `${url}?${query}`;
48+
}
49+
const contentType = contentTypeSent || defaultContentType;
50+
51+
const headers: {
52+
'Content-Type'?: string;
53+
Authorization: string;
54+
// CompanyId: string;
55+
} = {
56+
...header,
57+
'Content-Type': `${contentType}`,
58+
Authorization: token ? `Bearer ${token}` : '',
59+
// CompanyId: getCompanyTemp()
60+
};
61+
62+
// TODO: we shoul figure out how to do this better.
63+
if (formData) delete headers['Content-Type'];
64+
65+
try {
66+
const response = await fetch(url, {
67+
method,
68+
headers,
69+
body: body ? JSON.stringify(body) : formData ?? undefined
70+
});
71+
const responseBody = await response.json();
72+
responseBody.ok = true;
73+
74+
if (response.status !== 200 && response.status !== 201) {
75+
const { message } = await responseBody;
76+
// Token has expired errors
77+
if (
78+
message === 'jwt expired' ||
79+
message === 'No authorization token was found'
80+
) {
81+
// logoutRedirect();
82+
responseBody.ok = true;
83+
} else {
84+
// if (showError) toast.error(message, TOAST_OPTIONS);
85+
responseBody.ok = false;
86+
}
87+
}
88+
return responseBody;
89+
} catch (error) {
90+
throw Error(error as string);
91+
}
92+
};
93+
94+
/**
95+
* Hook for making server calls.
96+
* First generic is for the response type, second is for the body type.
97+
* @param params
98+
* @returns
99+
*/
100+
export function useApi<T, U>(params: ApiParams<U>): SWRResponse<T> {
101+
// const token = useSelector(getTokenSelector);
102+
103+
const response = useSWR(
104+
{
105+
// token,
106+
...params
107+
},
108+
(...args) => swrApi<T, U>(...args)
109+
);
110+
111+
return response;
112+
}
113+
114+
// export function useApiRefetch(): typeof ScopedMutator {
115+
// const { mutate } = useSWRConfig();
116+
// return mutate;
117+
// }

0 commit comments

Comments
 (0)