Skip to content

Commit

Permalink
feat: a lot has changed
Browse files Browse the repository at this point in the history
1. Adding notifications dialog. 2. Updating packages. 3. Changes in styles for card, header, dialog.
Adding new components. Updating home page
  • Loading branch information
NoHop3 committed Nov 13, 2023
1 parent 5afa0a2 commit 6b68569
Show file tree
Hide file tree
Showing 97 changed files with 4,144 additions and 2,410 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [releases/**, main]
branches: [releases/**]
tags:
- '*'
paths:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
.env.development
.env.development.local
.env.test.local
.env.production
.env.production.local

npm-debug.log*
Expand Down
33 changes: 15 additions & 18 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import React, { useMemo } from "react";
import {
ThemeProvider as ScThemeProvider,
} from "styled-components";
import { ThemeProvider, StyledEngineProvider } from "@mui/material";
import { lightTheme, darkTheme } from "../src/shared/utils/theme/themes";
import React, { useMemo } from 'react';
import { ThemeProvider as ScThemeProvider } from 'styled-components';
import { ThemeProvider, StyledEngineProvider } from '@mui/material';
import { lightTheme, darkTheme } from '../src/shared';

export const globalTypes = {
theme: {
name: "Theme",
title: "Theme",
description: "Theme for your components",
defaultValue: "light",
name: 'Theme',
title: 'Theme',
description: 'Theme for your components',
defaultValue: 'light',
toolbar: {
icon: "paintbrush",
icon: 'paintbrush',
dynamicTitle: true,
items: [
{ value: "light", left: "☀️", title: "Light mode" },
{ value: "dark", left: "🌙", title: "Dark mode" },
{ value: 'light', left: '☀️', title: 'Light mode' },
{ value: 'dark', left: '🌙', title: 'Dark mode' },
],
},
},
Expand All @@ -31,7 +29,8 @@ export const withProviders = (Story, context) => {
const { theme: themeKey } = context.globals;

// only recompute the theme if the themeKey changes
const theme = useMemo(() => THEMES[themeKey] || THEMES["light"], [themeKey]);
const theme = useMemo(() => THEMES[themeKey] || THEMES['light'], [themeKey]);

return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
Expand All @@ -43,12 +42,10 @@ export const withProviders = (Story, context) => {
);
};

export const decorators = [
withProviders,
];
export const decorators = [withProviders];

export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
expanded: true, // Adds the description and default columns
matchers: {
Expand Down
97 changes: 49 additions & 48 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,77 +47,78 @@
"@fortawesome/free-regular-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/react-fontawesome": "0.2.0",
"@mui/base": "5.0.0-beta.19",
"@mui/icons-material": "5.14.13",
"@mui/material": "5.14.13",
"@mui/styled-engine-sc": "6.0.0-alpha.1",
"@mui/system": "5.14.13",
"@mui/types": "7.2.6",
"@mui/base": "5.0.0-beta.23",
"@mui/icons-material": "5.14.16",
"@mui/material": "5.14.17",
"@mui/styled-engine-sc": "6.0.0-alpha.5",
"@mui/system": "5.14.17",
"@mui/types": "7.2.8",
"@reduxjs/toolkit": "1.9.7",
"@types/babel__core": "7.20.2",
"@types/estree": "1.0.2",
"@types/node": "20.8.4",
"@types/react": "18.2.28",
"@types/react-color": "3.0.7",
"@types/react-dom": "18.2.13",
"@types/react-redux": "7.1.27",
"@types/styled-components": "5.1.28",
"@types/uuid": "9.0.5",
"@types/babel__core": "7.20.4",
"@types/estree": "1.0.5",
"@types/node": "20.9.0",
"@types/react": "18.2.37",
"@types/react-color": "3.0.10",
"@types/react-dom": "18.2.15",
"@types/react-redux": "7.1.30",
"@types/styled-components": "5.1.30",
"@types/uuid": "9.0.7",
"jwt-decode": "3.1.2",
"axios": "1.5.1",
"axios": "1.6.1",
"connected-react-router": "6.9.3",
"history": "5.3.0",
"jest-esm-transformer": "1.0.0",
"react": "18.2.0",
"react-color": "2.19.3",
"react-dom": "18.2.0",
"react-redux": "8.1.3",
"react-router-dom": "6.16.0",
"react-router-dom": "6.18.0",
"react-scripts": "5.0.1",
"redux-thunk": "2.4.2",
"styled-components": "6.0.8",
"styled-components": "6.1.1",
"ts-jest": "29.1.1",
"ts-node": "10.9.1",
"uuid": "9.0.1",
"web-vitals": "3.5.0"
},
"devDependencies": {
"@babel/core": "7.23.0",
"@babel/plugin-proposal-private-property-in-object": "7.21.11",
"@babel/preset-env": "7.22.20",
"@babel/preset-react": "7.22.15",
"@babel/preset-typescript": "7.23.0",
"@babel/runtime": "7.23.1",
"@babel/core": "7.23.3",
"@babel/plugin-transform-private-property-in-object": "7.23.3",
"@babel/preset-env": "7.23.3",
"@babel/preset-react": "7.23.3",
"@babel/preset-typescript": "7.23.3",
"@babel/runtime": "7.23.2",
"@semantic-release/changelog": "6.0.3",
"@semantic-release/commit-analyzer": "11.0.0",
"@semantic-release/commit-analyzer": "11.1.0",
"@semantic-release/git": "10.0.1",
"@semantic-release/github": "9.2.1",
"@semantic-release/release-notes-generator": "12.0.0",
"@storybook/addon-essentials": "7.4.6",
"@storybook/addon-interactions": "7.4.6",
"@storybook/addon-links": "7.4.6",
"@semantic-release/github": "9.2.3",
"@semantic-release/release-notes-generator": "12.1.0",
"@storybook/addon-essentials": "7.5.3",
"@storybook/addon-interactions": "7.5.3",
"@storybook/addon-links": "7.5.3",
"@storybook/addon-styling": "1.3.7",
"@storybook/blocks": "7.4.6",
"@storybook/preset-create-react-app": "7.4.6",
"@storybook/react": "7.4.6",
"@storybook/react-webpack5": "7.4.6",
"@storybook/blocks": "7.5.3",
"@storybook/preset-create-react-app": "7.5.3",
"@storybook/react": "7.5.3",
"@storybook/react-webpack5": "7.5.3",
"@storybook/testing-library": "0.2.2",
"@svgr/plugin-svgo": "8.1.0",
"@svgr/webpack": "8.1.0",
"@testing-library/jest-dom": "6.1.3",
"@testing-library/react": "14.0.0",
"@testing-library/jest-dom": "6.1.4",
"@testing-library/react": "14.1.0",
"@testing-library/user-event": "14.5.1",
"@typescript-eslint/eslint-plugin": "6.7.5",
"@typescript-eslint/parser": "6.7.5",
"@typescript-eslint/eslint-plugin": "6.10.0",
"@typescript-eslint/parser": "6.10.0",
"storybook": "7.5.3",
"babel-jest": "29.7.0",
"commitizen": "4.3.0",
"css-select": "5.1.0",
"eslint": "8.51.0",
"eslint": "8.53.0",
"eslint-config-prettier": "9.0.0",
"eslint-config-standard-with-typescript": "39.1.1",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-jest": "27.4.2",
"eslint-plugin-n": "16.1.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-jest": "27.6.0",
"eslint-plugin-n": "16.3.1",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-react": "7.33.2",
Expand All @@ -127,11 +128,10 @@
"jest-environment-jsdom": "29.7.0",
"jest-esm-transformer": "1.0.0",
"nth-check": "2.1.1",
"prettier": "3.0.3",
"prettier": "3.1.0",
"prop-types": "15.8.1",
"semantic-release": "22.0.5",
"storybook": "7.4.6",
"svgo": "3.0.2",
"semantic-release": "22.0.7",
"svgo": "3.0.3",
"typescript": "5.2.2"
},
"scripts": {
Expand All @@ -145,8 +145,9 @@
"test:watch": "jest --passWithNoTests --watch",
"tsc": "tsc",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"husky-init": "npx husky install && npx husky add .husky/pre-commit \"npx prettier --write \"\"src/*.ts\"\" \"\"src/**/*.ts*\"\"\" & npx husky add .husky/pre-push \"npx tsc && yarn run lint\" & npx husky add .husky/prepare-commit-msg \"exec < /dev/tty && npx cz --hook || true\""
"build:storybook": "storybook build",
"husky:init": "npx husky install && npx husky add .husky/pre-commit \"npx prettier --write \"\"src/*.ts\"\" \"\"src/**/*.ts*\"\"\" & npx husky add .husky/pre-push \"npx tsc && yarn run lint\" & npx husky add .husky/prepare-commit-msg \"exec < /dev/tty && npx cz --hook || true\"",
"push": "git add . && git commit && git push"
},
"eslintConfig": {
"extends": [
Expand Down
104 changes: 79 additions & 25 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
import { useEffect } from 'react';
import jwtDecode from 'jwt-decode';
import { connect } from 'react-redux';
import { Routes, Route, BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from '@mui/material/styles';
import { ThemeProvider as ScThemeProvider } from 'styled-components';
import {
useCustomTheme,
useGetDeviceType,
DeviceTypes,
useAppDispatch,
useAppSelector,
setNotificationVisibility,
setSnackbarVisibility,
Snackbar,
AuthenticatedUser,
setUser,
AppDispatch,
ApplicationState,
TSnackbar,
setSnackbar,
} from './shared';
import { Home, Error, Login, Register } from './pages';
import { Header, BottomNavigation } from './components';
import jwtDecode from 'jwt-decode';
import { useEffect } from 'react';

function App() {
const notification = useAppSelector((state) => state.notifications.notification);
const theme = useCustomTheme();
const dispatch = useAppDispatch();
interface IAppProps {
snackbar: TSnackbar;

onInit: () => void;
setSnackbarVisibility: (visibility: boolean) => void;
}

const App = (props: IAppProps) => {
const token = localStorage.getItem('token');

// Set background color for the root element
const root = document.getElementById('root') as HTMLElement;
const theme = useCustomTheme();
root.style.backgroundColor = theme.palette.background.default;

// Check if the user is authenticated and set the user in the store or remove token if expired
const { snackbar, setSnackbarVisibility, onInit } = props;

useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
const decoded = jwtDecode(token) as AuthenticatedUser;
if (decoded && decoded.exp >= Date.now() / 1000) {
// Dispatch setUser if a valid token exists
dispatch(setUser(decoded));
}
}
}, []);
onInit();
}, [token]);

return (
<ThemeProvider theme={theme}>
Expand All @@ -55,10 +58,12 @@ function App() {
<Route path="*" element={<Error />} />
</Routes>
<Snackbar
open={notification.open}
message={notification.message}
type={notification.type}
onClose={() => dispatch(setNotificationVisibility(false))}
open={snackbar.open}
message={snackbar.message}
type={snackbar.type}
onClose={() => {
setSnackbarVisibility(false);
}}
autoHideDuration={4000}
/>
{useGetDeviceType() !== DeviceTypes.DESKTOP && <BottomNavigation />}
Expand All @@ -67,6 +72,55 @@ function App() {
</ScThemeProvider>
</ThemeProvider>
);
}
};

const mapStateToProps = (state: ApplicationState) => ({
snackbar: state.notifications.snackbar,
user: state.user.user,
token: state.user.token,
});

const mapDispatchToProps = (dispatch: AppDispatch) => {
return {
onInit: () => {
const token = localStorage.getItem('token');
if (token) {
const decoded = jwtDecode(token) as AuthenticatedUser;
if (decoded && decoded.exp >= Date.now() / 1000) {
// Dispatch setUser if a valid token exists
dispatch(setUser(decoded));
dispatch(
setSnackbar({
open: true,
message: `Welcome back! ${decoded.username} 👋`,
type: 'success',
}),
);
} else {
// Remove invalid token
localStorage.removeItem('token');
dispatch(setUser(undefined));
dispatch(
setSnackbar({
open: true,
message: 'Your session has expired. Please login again. 😅',
type: 'error',
}),
);
}
} else {
dispatch(setUser(undefined));
dispatch(
setSnackbar({
open: true,
message: 'Hey 👋! Welcome to this create-react-app custom template! 😎',
type: 'info',
}),
);
}
},
setSnackbarVisibility: (visibility: boolean) => dispatch(setSnackbarVisibility(visibility)),
};
};

export default App;
export const AppContainer = connect(mapStateToProps, mapDispatchToProps)(App);
21 changes: 21 additions & 0 deletions src/components/bottom-navigation/bottom-navigation.container.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { connect } from 'react-redux';

import { type ApplicationState, type AppDispatch, markANotificationAsRead, removeANotification } from '../../shared';
import { BottomNav } from './bottom-navigation';

const mapStateToProps = (state: ApplicationState) => ({
notifications: state.notifications.notifications,
});

const mapDispatchToProps = (dispatch: AppDispatch) => {
return {
onMarkNotificationAsRead: (id: string) => {
dispatch(markANotificationAsRead(id));
},
onDeleteNotification: (id: string) => {
dispatch(removeANotification(id));
},
};
};

export const BottomNavigationContainer = connect(mapStateToProps, mapDispatchToProps)(BottomNav);
7 changes: 7 additions & 0 deletions src/components/bottom-navigation/bottom-navigation.props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { TNotification } from '../../shared';

export interface IBottomNavigationProps {
notifications: TNotification[];
onDeleteNotification: (id: string) => void;
onMarkNotificationAsRead: (id: string) => void;
}
Loading

0 comments on commit 6b68569

Please sign in to comment.