Skip to content

Commit

Permalink
refactoring and antd design implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ex-Machin committed Jan 15, 2025
1 parent 7baaa79 commit 095cf97
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 115 deletions.
168 changes: 106 additions & 62 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,127 @@
import React, { Component, ComponentType, Suspense } from "react";
import { connect } from "react-redux";
import { Route, Routes } from "react-router-dom";
import { compose } from "redux";
import { LaptopOutlined, NotificationOutlined, UserOutlined } from '@ant-design/icons';
import type { MenuProps } from 'antd';
import { Breadcrumb, Layout, Menu } from 'antd';
import 'antd/dist/antd.css';
import React, { Suspense, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Link, Route, Routes } from "react-router-dom";
import { AnyAction } from "redux";
import { ThunkDispatch } from 'redux-thunk';
import "./App.css";
import HeaderContainer from "./components/Header/HeaderContainer";

import Music from "./components/Music/Music";
import NavBarContainer from "./components/NavBar/NavBarContainer";
import News from "./components/News/News";
import Preloader from "./components/Preloader/Preloader";
import Settings from "./components/Settings/Settings";
import { withRouter } from "./hoc/withRouter";
import { initialize } from "./redux/app-reducer";
import { AppStateType } from "./redux/redux-store";
import 'antd/dist/antd.css';
import Header from './components/Header/Header';
import { Footer } from 'antd/lib/layout/layout';

const { Content, Sider } = Layout;

const DialogsContainer = React.lazy(() =>
import("./components/Dialogs/DialogsContainer")
const items = [
{
icon: UserOutlined,
label: <Link to="/profile">Profile</Link>
},
{
icon: LaptopOutlined,
label: <Link to="/dialogs">Dialogs</Link>
},
{
icon: NotificationOutlined,
label: <Link to="/news">News</Link>
},
{
icon: UserOutlined,
label: <Link to="/users">Users</Link>
},
{
icon: UserOutlined,
label: <Link to="/music">Music</Link>
},
{
icon: UserOutlined,
label: <Link to="/settings">Settings</Link>
}
]

const items2: MenuProps['items'] = items.map((item, index) => {
return {
key: index,
icon: React.createElement(item.icon),
label: item.label,
};
},
);

const DialogsContainer = React.lazy(() => import("./components/Dialogs/DialogsContainer"));
const ProfilePage = React.lazy(() => import("./components/Profile/ProfilePage"));
const LoginPage = React.lazy(() => import("./components/Login/Login"));
const UsersPage = React.lazy(() => import("./components/Users/UsersPage"));

type MapPropsType = ReturnType<typeof mapStateToProps>
type DispatchPropsType = {
initialize: () => void
}
export const App: React.FC = () => {

class App extends Component<MapPropsType & DispatchPropsType> {

catchAllUnhandledErrors = () => {
const catchAllUnhandledErrors = () => {
alert("Some error occured")
}
const dispatch: ThunkDispatch<AppStateType, unknown, AnyAction> = useDispatch()

componentDidMount() {
this.props.initialize();
window.addEventListener("unhandledrejection", this.catchAllUnhandledErrors);
}
componentWillUnmount() {
window.removeEventListener(
"unhandledrejection",
this.catchAllUnhandledErrors
);
}
useEffect(() => {
dispatch(initialize())
window.addEventListener("unhandledrejection", catchAllUnhandledErrors);
}, [dispatch])

render() {
if (!this.props.init) {
return <Preloader />;
} else
return (
<div className="app-wrapper">
<HeaderContainer />
<NavBarContainer />
<div className="app-wrapper-content">
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<ProfilePage />} />
<Route path="/dialogs" element={<DialogsContainer />} />
<Route path="/profile/:id" element={<ProfilePage />} />
<Route path="/profile" element={<ProfilePage />} />
<Route path="/news" element={<News />} />
<Route path="/music" element={<Music />} />
<Route path="/settings" element={<Settings />} />
<Route path="/users" element={<UsersPage pageTitle="Каничива" />}/>
<Route path="/login" element={<LoginPage />} />
<Route path="*" element={<Button>Not Found</Button>} />
</Routes>
</Suspense>
</div>
</div>
);
}
}
useEffect(() => () => {
window.removeEventListener("unhandledrejection", catchAllUnhandledErrors);
}, [])

const isInitialized = useSelector((state: AppStateType) => state.app.initialized)

const mapStateToProps = (state: AppStateType) => ({
init: state.app.initialized,
});

export default compose<ComponentType>(
withRouter,
connect(mapStateToProps, { initialize })
)(App);
return isInitialized ? (
<Layout>
<Header />
<Layout>
<Sider width={200} className="site-layout-background">
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%', borderRight: 0 }}
items={items2}
/>
</Sider>
<Layout style={{ padding: '0 24px 24px' }}>
<Content
className="site-layout-background"
style={{
padding: 24,
margin: 0,
minHeight: 280,
}}
>
<div className="app-wrapper-content">
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<ProfilePage />} />
<Route path="/dialogs" element={<DialogsContainer />} />
<Route path="/profile/:id" element={<ProfilePage />} />
<Route path="/profile" element={<ProfilePage />} />
<Route path="/news" element={<News />} />
<Route path="/music" element={<Music />} />
<Route path="/settings" element={<Settings />} />
<Route path="/users" element={<UsersPage pageTitle="Каничива" />} />
<Route path="/login" element={<LoginPage />} />
<Route path="*" element={<div>Not Found</div>} />
</Routes>
</Suspense>
</div>
</Content>
</Layout>
</Layout>
<Footer style={{ textAlign: 'center' }}>Social Network @ 2025 Created by Ex-Machin</Footer>
</Layout>
) : <Preloader />
}
Binary file added src/assets/images/bird_2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 15 additions & 6 deletions src/components/Header/Header.module.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
.header {
grid-area: header;
background-color: green;
position: sticky;
top: 0;
z-index: 1;
width: 100%;
}
.header img {
width: 20px;
.header.logo {
float: left;
width: 40px;
height: 40px;
}
.loginBlock {
float: right;
color: aquamarine;
}
/* width: 25%; */
height: 100%;
color: whitesmoke;
display: flex;
justify-content: space-between;
align-items: center;
}
65 changes: 37 additions & 28 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,43 @@
import React from "react";
import { Link } from "react-router-dom";
import React from 'react';
import s from "./Header.module.css";
import { logout } from '../../redux/auth-reducer';
import { UserOutlined } from '@ant-design/icons';
import { AppStateType } from '../../redux/redux-store';
import { useDispatch, useSelector } from 'react-redux';
import { Layout, Button } from 'antd';
import { Avatar } from 'antd';
import { ThunkDispatch } from 'redux-thunk';
import { AnyAction } from 'redux';
import { Link } from 'react-router-dom';
import logo from "../../assets/images/bird_2.jpg";

export type MapHeaderPropsType = {
isAuth: boolean | null
login: string | null
}
const Header: React.FC = () => {
const { Header } = Layout;

export type DispatchHeaderPropsType = {
logout: () => void
}
const isAuth = useSelector((state: AppStateType) => state.auth.isAuth)
const login = useSelector((state: AppStateType) => state.auth.login)

const Header: React.FC<MapHeaderPropsType & DispatchHeaderPropsType> = (props) => {
return (
<header className={s.header}>
<img
src="https://upload.wikimedia.org/wikipedia/commons/1/1e/RPC-JP_Logo.png"
alt=""
/>
{props.isAuth ? (
<div>
{props.login} <button onClick={props.logout}>Logout</button>
</div>
) : (
<Link to={"/login"} className={s.loginBlock}>
Login
</Link>
)}
</header>
);
const dispatch: ThunkDispatch<AppStateType, unknown, AnyAction> = useDispatch()

return (
<Header className={s.header}>
<img className='logo' src={logo} alt="" height='40px' width='40px' />
<div className={s.loginBlock}>
{isAuth ? (
<>
<div title={login || ''}>
<Avatar style={{ marginRight: "20px"}} shape="square" size="small" icon={<UserOutlined />} />
</div>
<Button type="primary" onClick={() => dispatch(logout())}>Logout</Button>
</>
) : (
<Button type='primary'>
<Link to={"/login"}>Login </Link>
</Button>
)}
</div>
</Header>
);
};

export default Header;
export default Header;
18 changes: 0 additions & 18 deletions src/components/Header/HeaderContainer.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import { App } from "./App";
import "./index.css";
import store from "./redux/redux-store";

Expand Down

0 comments on commit 095cf97

Please sign in to comment.