Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add features #15

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
0df9a0c
Create axios.
hichem-bouzourine Apr 23, 2023
978f14b
Fix(dependencies) - Add axios + styled components.
hichem-bouzourine Apr 23, 2023
ba5d3df
Create Users and Categories UI.
hichem-bouzourine Apr 23, 2023
19652cb
Creatin de categorie.
hichem-bouzourine Apr 23, 2023
7e2cb39
Fix(Catégorie) - img clickable, fix typo.
hichem-bouzourine Apr 24, 2023
feb58d6
Feat(Component) - Create Copyright.
hichem-bouzourine Apr 25, 2023
a36c848
Feat(app) - add authentication functionality
hichem-bouzourine Apr 26, 2023
7ee9d75
Feat(Sidebar) - dynamically render the user.
hichem-bouzourine Apr 27, 2023
a9bf929
Feat(axios) - configure Authorization header
hichem-bouzourine Apr 29, 2023
7a1b751
Feat(users) - delete user.
hichem-bouzourine Apr 29, 2023
3c86b24
Feat(user) - Create user.
hichem-bouzourine May 1, 2023
9c9481a
Feat(Categorie) - Delete categorie.
hichem-bouzourine May 1, 2023
6d154e8
Fix(Categorie) - Show appropriate message.
hichem-bouzourine May 1, 2023
2dee945
Feat(platform) - handle logout.
hichem-bouzourine May 1, 2023
9d98a4c
Feat(signalement) - Create Signalement Profiles.
hichem-bouzourine May 1, 2023
90ba396
Feat(user) - render specialite.
hichem-bouzourine May 1, 2023
f1dbcb2
Feat(categorie) - styling buttons.
hichem-bouzourine May 1, 2023
1ee8500
Fix(user) - Validate date.
hichem-bouzourine May 1, 2023
9094ed1
Fix(user) - typo in button.
hichem-bouzourine May 1, 2023
b7d8c15
Feat(signales) - handle resultat signalement.
hichem-bouzourine May 1, 2023
67cbec5
Feat(signalement) - display selected User.
hichem-bouzourine May 2, 2023
6a8d787
Feat(user) - Handle Statut Compte.
hichem-bouzourine May 3, 2023
b5e441b
Feat(categorie) - Add Refresh button.
hichem-bouzourine May 3, 2023
4542730
Fix(user) - disabled button error.
hichem-bouzourine May 7, 2023
7df22fb
Feat(oeuvre) - Display oeuvres.
hichem-bouzourine May 7, 2023
1fa8c60
Feat(user) - Change modify visibility.
hichem-bouzourine May 14, 2023
038a849
Feat(stats) - Bar chart.
hichem-bouzourine May 14, 2023
5a64bbf
Feat(signalement - oeuvre).
hichem-bouzourine May 28, 2023
9f0f022
Fix(global) - color and responsiveness.
hichem-bouzourine May 31, 2023
dd4e7f2
Feat(Signalement) - SIgnalement Avis.
hichem-bouzourine May 31, 2023
7088a1b
Feat(Technique/Categorie) - Modify.
hichem-bouzourine Jun 1, 2023
e5add7c
Feat(Materiaux) - CRUD.
hichem-bouzourine Jun 1, 2023
e47b85d
Feat(line chart) - Add line chart + styling.
hichem-bouzourine Jun 2, 2023
4942e82
Feat(signalement) - Add Date reponse admin.
hichem-bouzourine Jun 2, 2023
f7c5df1
Feat(admin) - Modify admin data.
hichem-bouzourine Jun 2, 2023
60afdab
Feat(users) - Accept or Decline users documents.
hichem-bouzourine Jun 3, 2023
6a86d57
Feat(user) - Admin create only admins
hichem-bouzourine Jun 5, 2023
6b73b72
Fix(user) - bug in Statut compte.
hichem-bouzourine Jun 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
/.pnp
.pnp.js

*.env

# testing
/coverage

Expand Down
17,343 changes: 11,582 additions & 5,761 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"@fullcalendar/timegrid": "^5.11.3",
"@mui/icons-material": "^5.10.3",
"@mui/material": "^5.10.5",
"@mui/styles": "^5.12.3",
"@mui/x-data-grid": "^5.17.2",
"@mui/x-date-pickers": "^6.3.0",
"@nivo/bar": "^0.80.0",
"@nivo/core": "^0.79.0",
"@nivo/geo": "^0.80.0",
Expand All @@ -23,15 +25,19 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.5",
"chart.js": "^3.9.1",
"dayjs": "^1.11.7",
"formik": "^2.2.9",
"react": "^18.2.0",
"react-chartjs-2": "^4.3.1",
"react-dom": "^18.2.0",
"react-material-ui-carousel": "^3.4.2",
"react-pro-sidebar": "^0.7.1",
"react-redux": "^8.0.2",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"styled-components": "^5.3.9",
"web-vitals": "^2.1.4",
"yup": "^0.32.11"
},
Expand Down
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Tableau de bord</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
102 changes: 78 additions & 24 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,101 @@
import { useState } from "react";
import { Routes, Route } from "react-router-dom";
import { useEffect, useState } from "react";
import { Routes, Route, Navigate } from "react-router-dom";
import Topbar from "./scenes/global/Topbar";
import Sidebar from "./scenes/global/Sidebar";
import Dashboard from "./scenes/dashboard";
import Team from "./scenes/team";
import Invoices from "./scenes/invoices";
import Contacts from "./scenes/contacts";
import Users from "./scenes/users";
import Categories from "./scenes/categories";
import Bar from "./scenes/bar";
import Form from "./scenes/form";
import Line from "./scenes/line";
import Pie from "./scenes/pie";
import FAQ from "./scenes/faq";
import Geography from "./scenes/geography";
import { CssBaseline, ThemeProvider } from "@mui/material";
import { ColorModeContext, useMode } from "./theme";
import Calendar from "./scenes/calendar/calendar";
import CreateCategorie from "./components/CreateCategorie";
import Login from "./scenes/login/Login";
import CreateUser from "./components/CreateUser";
import SignalementProfile from "./scenes/signalementProfile/index";
import Oeuvres from "./scenes/oeuvres";
import SignalementOeuvre from "./scenes/signalementOeuvre";
import SignalementAvis from "./scenes/signalementAvis";
import Techniques from "./scenes/technique";
import CreateTechnique from "./components/CreateTechnique";
import Materiaux from "./scenes/materiaux";
import CreateMateriau from "./components/CreateMateriau";
import Settings from "./scenes/settings/index";

function AuthenticatedRoutes() {
const [isSidebar, setIsSidebar] = useState(true);
return (
<>
<Sidebar isSidebar={isSidebar} />
<main className="content">
<Topbar setIsSidebar={setIsSidebar} />
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/users">
<Route index element={<Users />} />
<Route path="create" element={<CreateUser />} />
</Route>
<Route path="/categories">
<Route index element={<Categories />} />
<Route path="create" element={<CreateCategorie />} />
<Route path=":id" element={<CreateCategorie />} />
</Route>
<Route path="/oeuvres" element={<Oeuvres />} />
<Route path="/signalement-profile" element={<SignalementProfile />} />
<Route path="/signalement-oeuvre" element={<SignalementOeuvre />} />
<Route path="/signalement-avis" element={<SignalementAvis />} />
<Route path="/techniques">
<Route index element={<Techniques />} />
<Route path="create" element={<CreateTechnique />} />
<Route path=":id" element={<CreateTechnique />} />
</Route>
<Route path="/materiaux">
<Route index element={<Materiaux />} />
<Route path="create" element={<CreateMateriau />} />
<Route path=":id" element={<CreateMateriau />} />
</Route>
<Route path="/bar" element={<Bar />} />
<Route path="/pie" element={<Pie />} />
<Route path="/line" element={<Line />} />
<Route path="/faq" element={<FAQ />} />
<Route path="/calendar" element={<Calendar />} />
<Route path="/geography" element={<Geography />} />
<Route path="/settings" element={<Settings />} />
<Route path="/*" element={<Navigate to="/" replace />} />
</Routes>
</main>
</>
);
}

function App() {
const [theme, colorMode] = useMode();
const [isSidebar, setIsSidebar] = useState(true);
const [isAuthenticated, setIsAuthenticated] = useState(false);

useEffect(() => {
const token = localStorage.getItem("token");
setIsAuthenticated(token ? true : false);
}, []);

return (
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<div className="app">
<Sidebar isSidebar={isSidebar} />
<main className="content">
<Topbar setIsSidebar={setIsSidebar} />
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/team" element={<Team />} />
<Route path="/contacts" element={<Contacts />} />
<Route path="/invoices" element={<Invoices />} />
<Route path="/form" element={<Form />} />
<Route path="/bar" element={<Bar />} />
<Route path="/pie" element={<Pie />} />
<Route path="/line" element={<Line />} />
<Route path="/faq" element={<FAQ />} />
<Route path="/calendar" element={<Calendar />} />
<Route path="/geography" element={<Geography />} />
</Routes>
</main>
<Routes>
{isAuthenticated ? (
<Route path="/*" element={<AuthenticatedRoutes />} />
) : (
<>
<Route path="/login" element={<Login />} />
<Route path="*" element={<Navigate to="/login" replace />} />
</>
)}
</Routes>
</div>
</ThemeProvider>
</ColorModeContext.Provider>
Expand Down
14 changes: 14 additions & 0 deletions src/axios/axios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from "axios";

const instance = axios.create({
baseURL: process.env.REACT_APP_API_URL,
});

instance.interceptors.request.use((config) => {
const token = localStorage.getItem("token");
if (token) config.headers.Authorization = `Bearer ${token}`;

return config;
});

export default instance;
12 changes: 12 additions & 0 deletions src/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const isValidEmail = (email) => {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
};

export const isValidPassword = (password) => {
return password?.length < 4 ? false : true;
};

export const isValidDate = (date) => {
return date < new Date();
};
113 changes: 113 additions & 0 deletions src/components/AvisCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import {
Box,
Button,
Card,
CardContent,
CardHeader,
CircularProgress,
Grid,
IconButton,
Typography,
useTheme,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
import axios from "../axios/axios";
import { tokens } from "../theme";
import { useEffect, useState } from "react";

const AvisCard = ({ avis, onClose }) => {
const theme = useTheme();
const colors = tokens(theme.palette.mode);

const [user, setUser] = useState(null);
const { id_avis, id_utilisateur, id_oeuvre, contenu, date_avis } = avis;

const deleteAvis = async (id_avis) => {
await axios.delete(`/avis/${id_avis}`).catch((err) => {
console.log(err);
});
};

const deleteUser = async (id) => {
await axios.delete(`/admin/users/${id}`).catch((err) => {
console.log(err);
});
};

const getSelectedUser = async (id) => {
await axios.get(`admin/userById/${id}`).then((res) => {
setUser(res.data);
});
};

useEffect(() => {
getSelectedUser(id_utilisateur);
}, []);

return (
<Card>
<CardHeader
title={
user ? ` Signalement de l'avis de ${user.nom} ${user.prenom}` : ""
}
action={
<IconButton onClick={onClose}>
<CloseIcon />
</IconButton>
}
/>
<CardContent>
{!user?.photo && <CircularProgress color="success" />}
{user?.photo && (
<img
src={user?.photo}
alt={`${user?.nom} ${user?.prenom}`}
style={{ maxWidth: "100%", marginBottom: "16px" }}
/>
)}
<Typography variant="subtitle1" gutterBottom>
<strong>Type:</strong> {user?.type}
</Typography>
<Typography variant="body1" gutterBottom>
<strong>Email:</strong> {user?.email}
</Typography>
<Typography variant="body1" gutterBottom>
<strong>Téléphone:</strong> {user?.telephone}
</Typography>
<Typography variant="body1" gutterBottom>
<strong>Date de naissance:</strong>{" "}
{new Date(user?.date_de_naissance)?.toLocaleDateString("fr-FR")}
</Typography>
<Typography variant="body1" gutterBottom>
<strong>Sexe:</strong> {user?.sexe}
</Typography>
<Typography variant="body1" gutterBottom>
<strong>Date écriture avis:</strong>{" "}
{new Date(date_avis)?.toLocaleDateString("fr-FR")}
</Typography>
<Typography variant="body1" gutterBottom>
<strong>L'avis:</strong>
</Typography>{" "}
<h1>{contenu}</h1>
<Box display={"flex"} flexDirection={"column"} width="30%">
<Button
variant="contained"
sx={{ mt: 5, color: colors.redAccent[500] }}
onClick={() => deleteAvis(id_avis)}
>
Supprimer l'avis
</Button>
<Button
variant="contained"
sx={{ mt: 5, color: colors.redAccent[500] }}
onClick={() => deleteUser(user?.id_utilisateur)}
>
Sanctionner Utilisateur
</Button>
</Box>
</CardContent>
</Card>
);
};

export default AvisCard;
22 changes: 15 additions & 7 deletions src/components/BarChart.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { useTheme } from "@mui/material";
import { ResponsiveBar } from "@nivo/bar";
import { tokens } from "../theme";
import { mockBarData as data } from "../data/mockData";

const BarChart = ({ isDashboard = false }) => {
const BarChart = ({
isDashboard = false,
data,
keys,
indexBy,
axisBottomLegend,
axisLeftLegend,
}) => {
const theme = useTheme();
const colors = tokens(theme.palette.mode);

Expand Down Expand Up @@ -39,8 +45,8 @@ const BarChart = ({ isDashboard = false }) => {
},
},
}}
keys={["hot dog", "burger", "sandwich", "kebab", "fries", "donut"]}
indexBy="country"
keys={keys}
indexBy={indexBy}
margin={{ top: 50, right: 130, bottom: 50, left: 60 }}
padding={0.3}
valueScale={{ type: "linear" }}
Expand Down Expand Up @@ -76,17 +82,19 @@ const BarChart = ({ isDashboard = false }) => {
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: isDashboard ? undefined : "country", // changed
legend: isDashboard ? undefined : axisBottomLegend, // changed
legendPosition: "middle",
legendOffset: 32,
}}
axisLeft={{
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: isDashboard ? undefined : "food", // changed
legend: isDashboard ? undefined : axisLeftLegend, // changed
legendPosition: "middle",
legendOffset: -40,
// tickValues: data.reduce((set, { y }) => set.add(y), new Set()).size,
format: (e) => Math.floor(e) === e && e,
}}
enableLabel={false}
labelSkipWidth={12}
Expand Down Expand Up @@ -121,7 +129,7 @@ const BarChart = ({ isDashboard = false }) => {
]}
role="application"
barAriaLabel={function (e) {
return e.id + ": " + e.formattedValue + " in country: " + e.indexValue;
return e.id + ": " + e.formattedValue + " par type: " + e.indexValue;
}}
/>
);
Expand Down
23 changes: 23 additions & 0 deletions src/components/Copyright.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Typography } from "@mui/material";
import React from "react";
import { Link } from "react-router-dom";

const Copyright = (props) => {
return (
<Typography
variant="body2"
color="text.secondary"
align="center"
{...props}
>
{"Copyright © "}
<Link style={{ color: "inherit" }} to="/">
Artisanat
</Link>{" "}
{new Date().getFullYear()}
{"."}
</Typography>
);
};

export default Copyright;
Loading