diff --git a/package.json b/package.json index 44f14fa6..8b9c6f06 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "@heroicons/react": "2.0.18", "@material-tailwind/react": "2.1.4", "apexcharts": "3.44.0", + "axios": "^1.12.2", + "jwt-decode": "^4.0.0", "prop-types": "15.8.1", "react": "18.2.0", "react-apexcharts": "1.4.1", @@ -27,6 +29,6 @@ "prettier": "3.0.3", "prettier-plugin-tailwindcss": "0.5.6", "tailwindcss": "3.3.4", - "vite": "4.5.0" + "vite": "^4.5.14" } -} \ No newline at end of file +} diff --git a/public/img/background.jpg b/public/img/background.jpg new file mode 100644 index 00000000..fb14759e Binary files /dev/null and b/public/img/background.jpg differ diff --git a/public/img/pattern.png b/public/img/pattern.png deleted file mode 100644 index 2b34e46f..00000000 Binary files a/public/img/pattern.png and /dev/null differ diff --git a/src/App.jsx b/src/App.jsx index 87826600..4995a483 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,12 +1,25 @@ import { Routes, Route, Navigate } from "react-router-dom"; import { Dashboard, Auth } from "@/layouts"; +import PrivateRoute from "../src/component/PrivateRoute"; function App() { return ( - } /> + {/* Dashboard'u sadece giriş yapmış kullanıcı görecek */} + + + + } + /> + + {/* Auth sayfaları (giriş, kayıt) herkes görebilir */} } /> - } /> + + {/* Varsayılan yönlendirme */} + } /> ); } diff --git a/src/api/axiosConfig.js b/src/api/axiosConfig.js new file mode 100644 index 00000000..8fabae67 --- /dev/null +++ b/src/api/axiosConfig.js @@ -0,0 +1,29 @@ +import axios from "axios"; + + + +const apiClient = axios.create({ + baseURL: "https://localhost:7093/api", +}); + + +apiClient.interceptors.request.use( + (config) => { + + const token = localStorage.getItem("authToken"); + + + if (token) { + + config.headers.Authorization = `Bearer ${token}`; + } + + return config; + }, + (error) => { + + return Promise.reject(error); + } +); + +export default apiClient; \ No newline at end of file diff --git a/src/component/PrivateRoute.jsx b/src/component/PrivateRoute.jsx new file mode 100644 index 00000000..63f8e93b --- /dev/null +++ b/src/component/PrivateRoute.jsx @@ -0,0 +1,15 @@ +import React from "react"; +import { Navigate } from "react-router-dom"; + +const PrivateRoute = ({ children }) => { + const token = localStorage.getItem("authToken"); + + if (!token) { + // Token yoksa login sayfasına yönlendir + return ; + } + + return children; +}; + +export default PrivateRoute; diff --git a/src/context/index.jsx b/src/context/index.jsx index 653a362d..232589ba 100644 --- a/src/context/index.jsx +++ b/src/context/index.jsx @@ -23,6 +23,10 @@ export function reducer(state, action) { } case "OPEN_CONFIGURATOR": { return { ...state, openConfigurator: action.value }; + } + // YENİ: Kullanıcı rolünü ayarlamak için yeni case eklendi. + case "SET_USER_ROLE": { + return { ...state, userRole: action.value }; } default: { throw new Error(`Unhandled action type: ${action.type}`); @@ -38,18 +42,20 @@ export function MaterialTailwindControllerProvider({ children }) { transparentNavbar: true, fixedNavbar: false, openConfigurator: false, + // YENİ: userRole state'i eklendi. Sayfa yenilendiğinde rolün kaybolmaması için localStorage'dan okunuyor. + userRole: localStorage.getItem("userRole") || null, }; const [controller, dispatch] = React.useReducer(reducer, initialState); const value = React.useMemo( - () => [controller, dispatch], - [controller, dispatch] + () => [controller, dispatch], + [controller, dispatch] ); return ( - - {children} - + + {children} + ); } @@ -58,7 +64,7 @@ export function useMaterialTailwindController() { if (!context) { throw new Error( - "useMaterialTailwindController should be used inside the MaterialTailwindControllerProvider." + "useMaterialTailwindController should be used inside the MaterialTailwindControllerProvider." ); } @@ -72,14 +78,18 @@ MaterialTailwindControllerProvider.propTypes = { }; export const setOpenSidenav = (dispatch, value) => - dispatch({ type: "OPEN_SIDENAV", value }); + dispatch({ type: "OPEN_SIDENAV", value }); export const setSidenavType = (dispatch, value) => - dispatch({ type: "SIDENAV_TYPE", value }); + dispatch({ type: "SIDENAV_TYPE", value }); export const setSidenavColor = (dispatch, value) => - dispatch({ type: "SIDENAV_COLOR", value }); + dispatch({ type: "SIDENAV_COLOR", value }); export const setTransparentNavbar = (dispatch, value) => - dispatch({ type: "TRANSPARENT_NAVBAR", value }); + dispatch({ type: "TRANSPARENT_NAVBAR", value }); export const setFixedNavbar = (dispatch, value) => - dispatch({ type: "FIXED_NAVBAR", value }); + dispatch({ type: "FIXED_NAVBAR", value }); export const setOpenConfigurator = (dispatch, value) => - dispatch({ type: "OPEN_CONFIGURATOR", value }); + dispatch({ type: "OPEN_CONFIGURATOR", value }); + + +export const setUserRole = (dispatch, value) => + dispatch({ type: "SET_USER_ROLE", value }); \ No newline at end of file diff --git a/src/layouts/dashboard.jsx b/src/layouts/dashboard.jsx index 888a627a..3041b4a5 100644 --- a/src/layouts/dashboard.jsx +++ b/src/layouts/dashboard.jsx @@ -2,53 +2,53 @@ import { Routes, Route } from "react-router-dom"; import { Cog6ToothIcon } from "@heroicons/react/24/solid"; import { IconButton } from "@material-tailwind/react"; import { - Sidenav, - DashboardNavbar, - Configurator, - Footer, +  Sidenav, +  DashboardNavbar, +  Configurator, +  Footer, } from "@/widgets/layout"; import routes from "@/routes"; import { useMaterialTailwindController, setOpenConfigurator } from "@/context"; export function Dashboard() { - const [controller, dispatch] = useMaterialTailwindController(); - const { sidenavType } = controller; +  const [controller, dispatch] = useMaterialTailwindController(); +  const { sidenavType } = controller; - return ( -
- -
- - - setOpenConfigurator(dispatch, true)} - > - - - - {routes.map( - ({ layout, pages }) => - layout === "dashboard" && - pages.map(({ path, element }) => ( - - )) - )} - -
-
-
-
-
- ); +  return ( +   
+      +     
+        +        +        setOpenConfigurator(dispatch, true)} +        > +          +        +        +          {routes.map( +            ({ layout, pages }) => +              layout === "dashboard" && +              pages.map(({ path, element }) => ( +                +              )) +          )} +        +       
+         
+       
+     
+   
+  ); } Dashboard.displayName = "/src/layout/dashboard.jsx"; diff --git a/src/pages/auth/index.js b/src/pages/auth/index.js index ca1bbcb6..425a5351 100644 --- a/src/pages/auth/index.js +++ b/src/pages/auth/index.js @@ -1,2 +1,2 @@ export * from "@/pages/auth/sign-in"; -export * from "@/pages/auth/sign-up"; + diff --git a/src/pages/auth/sign-in.jsx b/src/pages/auth/sign-in.jsx index 3b3da41a..65555782 100644 --- a/src/pages/auth/sign-in.jsx +++ b/src/pages/auth/sign-in.jsx @@ -1,126 +1,129 @@ +import React, { useState } from "react"; +import { Card, Input, Button, Typography } from "@material-tailwind/react"; +import { Link, useNavigate } from "react-router-dom"; +import { jwtDecode } from "jwt-decode"; import { - Card, - Input, - Checkbox, - Button, - Typography, -} from "@material-tailwind/react"; -import { Link } from "react-router-dom"; - + useMaterialTailwindController, + setUserRole, +} from "@/context"; export function SignIn() { + + + const [, dispatch] = useMaterialTailwindController(); + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + const navigate = useNavigate(); + + + const handleSignIn = async () => { + const loginData = { + username: username, + password: password, + }; + + try { + const response = await fetch("https://localhost:7093/api/Auth/Login", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(loginData), + }); + + if (response.ok) { + const token = await response.text(); + + + localStorage.setItem("authToken", token); + console.log("Giriş Başarılı!"); + const decodedToken = jwtDecode(token); + const userRoleClaim = decodedToken.role || decodedToken["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"]; + const userRole = userRoleClaim ? userRoleClaim.toLowerCase() : null; + console.log(userRole); + + if (userRole) { + setUserRole(dispatch, userRole); + localStorage.setItem("userRole", userRole); + } + + + navigate("/dashboard/home"); + } else { + alert("Kullanıcı adı veya şifre hatalı!"); + } + } catch (error) { + console.error("Sunucuya bağlanırken bir hata oluştu:", error); + alert("Sunucuya bağlanılamadı."); + } + }; + + + return ( -
-
-
- Sign In - Enter your email and password to Sign In. -
-
-
- - Your email - - - - Password +
+ +
+ + LOGO -
- +
- I agree the  - - Terms and Conditions - + Kullanıcı Adı - } - containerProps={{ className: "-ml-2.5" }} - /> - - -
- setUsername(e.target.value)} + /> +
+ +
+ - Subscribe me to newsletter - - } - containerProps={{ className: "-ml-2.5" }} - /> - - - Forgot Password - - -
-
- -
+ + +
- - Not registered? - Create account - - - -
-
- -
- -
+ + ); } -export default SignIn; +export default SignIn; \ No newline at end of file diff --git a/src/pages/dashboard/home.jsx b/src/pages/dashboard/home.jsx index 2c700669..5cc98917 100644 --- a/src/pages/dashboard/home.jsx +++ b/src/pages/dashboard/home.jsx @@ -1,258 +1,21 @@ import React from "react"; -import { - Typography, - Card, - CardHeader, - CardBody, - IconButton, - Menu, - MenuHandler, - MenuList, - MenuItem, - Avatar, - Tooltip, - Progress, -} from "@material-tailwind/react"; -import { - EllipsisVerticalIcon, - ArrowUpIcon, -} from "@heroicons/react/24/outline"; -import { StatisticsCard } from "@/widgets/cards"; -import { StatisticsChart } from "@/widgets/charts"; -import { - statisticsCardsData, - statisticsChartsData, - projectsTableData, - ordersOverviewData, -} from "@/data"; -import { CheckCircleIcon, ClockIcon } from "@heroicons/react/24/solid"; + + export function Home() { - return ( -
-
- {statisticsCardsData.map(({ icon, title, footer, ...rest }) => ( - - {footer.value} -  {footer.label} - - } - /> - ))} -
-
- {statisticsChartsData.map((props) => ( - - -  {props.footer} - - } - /> - ))} -
-
- - -
- - Projects - - - - 30 done this month - -
- - - - - - - - Action - Another Action - Something else here - - -
- - - - - {["companies", "members", "budget", "completion"].map( - (el) => ( - - ) - )} - - - - {projectsTableData.map( - ({ img, name, members, budget, completion }, key) => { - const className = `py-3 px-5 ${ - key === projectsTableData.length - 1 - ? "" - : "border-b border-blue-gray-50" - }`; - return ( - - - - - - - ); - } - )} - -
- - {el} - -
-
- - - {name} - -
-
- {members.map(({ img, name }, key) => ( - - - - ))} - - - {budget} - - -
- - {completion}% - - -
-
-
-
- - - - Orders Overview - - - - 24% this month - - - - {ordersOverviewData.map( - ({ icon, color, title, description }, key) => ( -
-
- {React.createElement(icon, { - className: `!w-5 !h-5 ${color}`, - })} -
-
- - {title} - - - {description} - -
-
- ) - )} -
-
-
-
- ); +  return ( + +   
+ +      {/* Boş bırakıldı */} + +   
+ +  ); + } -export default Home; + + +export default Home; \ No newline at end of file diff --git a/src/pages/dashboard/notifications.jsx b/src/pages/dashboard/notifications.jsx index f4be88b0..8cf792e9 100644 --- a/src/pages/dashboard/notifications.jsx +++ b/src/pages/dashboard/notifications.jsx @@ -1,84 +1,100 @@ import React from "react"; import { Typography, - Alert, Card, CardHeader, CardBody, + Button, } from "@material-tailwind/react"; -import { InformationCircleIcon } from "@heroicons/react/24/outline"; -export function Notifications() { - const [showAlerts, setShowAlerts] = React.useState({ - blue: true, - green: true, - orange: true, - red: true, - }); - const [showAlertsWithIcon, setShowAlertsWithIcon] = React.useState({ - blue: true, - green: true, - orange: true, - red: true, - }); - const alerts = ["gray", "green", "orange", "red"]; +// Örnek güzergah verisi +const routesData = [ + { route: "İstanbul - Ankara" }, + { route: "İzmir - Antalya" }, + { route: "Bursa - Eskişehir" }, +]; +export function Notifications() { return (
+ {/* Güzergahlar başlığı ve ekleme butonu */} - - Alerts + + Güzergahlar + - - {alerts.map((color) => ( - setShowAlerts((current) => ({ ...current, [color]: false }))} - > - A simple {color} alert with an example link. Give - it a click if you like. - - ))} - - - - - - Alerts with Icon - - - - {alerts.map((color) => ( - - } - onClose={() => setShowAlertsWithIcon((current) => ({ - ...current, - [color]: false, - }))} - > - A simple {color} alert with an example link. Give - it a click if you like. - - ))} + + + + + + {["Güzergah", "İşlem"].map((el) => ( + + ))} + + + + + {routesData.map(({ route }, key) => { + const className = `py-3 px-5 ${ + key === routesData.length - 1 ? "" : "border-b border-blue-gray-50" + }`; + + return ( + + {/* Güzergah */} + + + {/* İşlem butonları */} + + + ); + })} + +
+ + {el} + +
+ + {route} + + +
+ + +
+
diff --git a/src/pages/dashboard/profile.jsx b/src/pages/dashboard/profile.jsx index 0d9f0115..1441185f 100644 --- a/src/pages/dashboard/profile.jsx +++ b/src/pages/dashboard/profile.jsx @@ -1,221 +1,167 @@ +import React, { useState, useEffect } from "react"; import { Card, - CardBody, CardHeader, - CardFooter, - Avatar, + CardBody, Typography, - Tabs, - TabsHeader, - Tab, - Switch, - Tooltip, Button, } from "@material-tailwind/react"; -import { - HomeIcon, - ChatBubbleLeftEllipsisIcon, - Cog6ToothIcon, - PencilIcon, -} from "@heroicons/react/24/solid"; -import { Link } from "react-router-dom"; -import { ProfileInfoCard, MessageCard } from "@/widgets/cards"; -import { platformSettingsData, conversationsData, projectsData } from "@/data"; + +import apiClient from "@/api/axiosConfig"; export function Profile() { + // Verileri, yüklenme durumunu ve hata durumunu tutmak için state'ler + const [users, setUsers] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Bu effect, bileşen ilk yüklendiğinde çalışır ve verileri çeker + useEffect(() => { + const fetchUsers = async () => { + try { + setLoading(true); + // Backend'de oluşturduğumuz endpoint'e istek atıyoruz + const response = await apiClient.get("/users"); + setUsers(response.data); // Gelen veriyi state'e kaydediyoruz + } catch (err) { + setError("Kullanıcı verileri yüklenirken bir hata oluştu."); + console.error(err); + } finally { + setLoading(false); // Yükleme tamamlandı + } + }; + + fetchUsers(); + }, []); // [] dependency array'i sayesinde sadece bir kez çalışır + + // YENİ: Kullanıcı silme fonksiyonu eklendi + const handleDelete = async (userId, userName) => { + // Kazara silmeyi önlemek için kullanıcıdan onay al + if (window.confirm(`'${userName}' adlı kullanıcıyı silmek istediğinizden emin misiniz?`)) { + try { + // Backend'deki DELETE endpoint'ine istek gönder + await apiClient.delete(`/users/${userId}`); + + // Arayüzü anında güncellemek için silinen kullanıcıyı listeden çıkar + setUsers(currentUsers => currentUsers.filter(user => user.id !== userId)); + + // Kullanıcıya başarı mesajı göster (isteğe bağlı) + // alert("Kullanıcı başarıyla silindi."); + } catch (err) { + alert("Kullanıcı silinirken bir hata oluştu."); + console.error(err); + } + } + }; + + + // Yüklenme sırasında gösterilecek içerik + if (loading) { + return ( +
+ Kullanıcılar Yükleniyor... +
+ ); + } + + // Hata durumunda gösterilecek içerik + if (error) { + return ( +
+ {error} +
+ ); + } + return ( - <> -
-
-
- - -
-
- -
- - Richard Davis - - - CEO / Co-Founder - -
-
-
- - - - - App - - - - Message - - - - Settings - - - -
-
-
-
- - Platform Settings - -
- {platformSettingsData.map(({ title, options }) => ( -
- - {title} - -
- {options.map(({ checked, label }) => ( - - ))} -
-
- ))} -
-
- - - - -
- ), - }} - action={ - - - - } - /> -
- - Platform Settings - -
    - {conversationsData.map((props) => ( - - reply - - } - /> - ))} -
-
-
-
- - Projects +
+ + + + Kullanıcılar - - Architects design houses - -
- {projectsData.map( - ({ img, title, description, tag, route, members }) => ( - - + Kullanıcı Ekle + + + + + + + {["Ad Soyad", "Araç Plakası", "Telefon", "İşlem"].map((el) => ( + + + + {/* Statik veri yerine backend'den gelen 'users' state'ini map'liyoruz */} + {users.map((user, key) => { + const isLast = key === users.length - 1; + const className = `py-3 px-5 ${ + isLast ? "" : "border-b border-blue-gray-50" + }`; + + return ( + // React'te listeler için 'key' prop'u benzersiz olmalıdır, ID kullanmak en iyisidir. + + + + + + + ); + })} + +
- {title} - - - {tag} + {el} - - {title} - - - {description} - - - - - - -
- {members.map(({ img, name }, key) => ( - - + ))} +
+ + {user.fullName} + + + + {user.licensePlate} + + + + {user.phoneNumber} + + +
+ + {/* YENİ: Sil butonuna onClick olayı eklendi */} +
- - - ) - )} - - - - - + variant="gradient" + color="red" + className="normal-case text-[10px] py-1 px-2" + onClick={() => handleDelete(user.id, user.fullName)} + > + Sil + + +
+
+
+
); } -export default Profile; +export default Profile; \ No newline at end of file diff --git a/src/pages/dashboard/tables.jsx b/src/pages/dashboard/tables.jsx index 3d453ed7..531a557b 100644 --- a/src/pages/dashboard/tables.jsx +++ b/src/pages/dashboard/tables.jsx @@ -3,31 +3,37 @@ import { CardHeader, CardBody, Typography, - Avatar, - Chip, - Tooltip, - Progress, + Button, } from "@material-tailwind/react"; -import { EllipsisVerticalIcon } from "@heroicons/react/24/outline"; -import { authorsTableData, projectsTableData } from "@/data"; +import { authorsTableData } from "@/data"; export function Tables() { return (
- + - Authors Table + Araçlar + + - +
- {["author", "function", "status", "employed", ""].map((el) => ( + {["Araçlar", "Şoför", "İşlem"].map((el) => ( + - {authorsTableData.map( - ({ img, name, email, job, online, date }, key) => { - const className = `py-3 px-5 ${ - key === authorsTableData.length - 1 - ? "" - : "border-b border-blue-gray-50" - }`; + {authorsTableData.map(({ plaka, driver }, key) => { + const className = `py-3 px-5 ${ + key === authorsTableData.length - 1 ? "" : "border-b border-blue-gray-50" + }`; - return ( - - - - - - - - ); - } - )} - -
-
- -
- - {name} - - - {email} - -
-
-
- - {job[0]} - - - {job[1]} - - - - - - {date} - - - - Edit - -
-
-
- - - - Projects Table - - - - - - - {["companies", "members", "budget", "completion", ""].map( - (el) => ( - + {/* Araç Plaka */} + - - - {projectsTableData.map( - ({ img, name, members, budget, completion }, key) => { - const className = `py-3 px-5 ${ - key === projectsTableData.length - 1 - ? "" - : "border-b border-blue-gray-50" - }`; + + + {/* Şoför */} + - return ( - - - - - - - - ); - } - )} + Sil + + + + + ); + })}
- - {el} + return ( +
+ + {plaka} - - ) - )} -
+ + {driver} + +
-
- - - {name} - -
-
- {members.map(({ img, name }, key) => ( - - - - ))} - - +
+
-
- - {completion}% - - -
-
- +
diff --git a/src/routes.jsx b/src/routes.jsx index 3a5a8da0..c2c7cfbe 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -1,66 +1,139 @@ import { - HomeIcon, - UserCircleIcon, - TableCellsIcon, - InformationCircleIcon, - ServerStackIcon, - RectangleStackIcon, + +  HomeIcon, + +  UserCircleIcon, + +  TableCellsIcon, + +  InformationCircleIcon, + +  ServerStackIcon, + +  RectangleStackIcon, + +  TruckIcon, + +  MapIcon, + +  Squares2X2Icon, + } from "@heroicons/react/24/solid"; + import { Home, Profile, Tables, Notifications } from "@/pages/dashboard"; -import { SignIn, SignUp } from "@/pages/auth"; + +import { SignIn } from "@/pages/auth"; + + + + + + const icon = { - className: "w-5 h-5 text-inherit", + +  className: "w-5 h-5 text-inherit", + }; + + export const routes = [ - { - layout: "dashboard", - pages: [ - { - icon: , - name: "dashboard", - path: "/home", - element: , - }, - { - icon: , - name: "profile", - path: "/profile", - element: , - }, - { - icon: , - name: "tables", - path: "/tables", - element: , - }, - { - icon: , - name: "notifications", - path: "/notifications", - element: , - }, - ], - }, - { - title: "auth pages", - layout: "auth", - pages: [ - { - icon: , - name: "sign in", - path: "/sign-in", - element: , - }, - { - icon: , - name: "sign up", - path: "/sign-up", - element: , - }, - ], - }, + +  { + +    layout: "dashboard", + +    pages: [ + +      { + +        icon: , + +        name: "Araç Sıraları", + +        path: "/home", + +        element: , + +        // roles eklenmediği için giriş yapan herkes görebilir. + +        // İsterseniz roles: ['admin', 'user'] de ekleyebilirsiniz. + +      }, + +      { + +        icon: , + +        name: "Kullanıcılar", + +        path: "/profile", + +        element: , + +        roles: ['admin'], + +      }, + +      { + +        icon: , + +        name: "Araçlar", + +        path: "/tables", + +        element: , + +        roles: ['admin'], // YENİ: Sadece adminler görebilir. + +      }, + +      { + +        icon: , + +        name: "Güzergahlar", + +        path: "/notifications", + +        element: , + +        roles: ['admin'], // YENİ: Sadece adminler görebilir. + +      }, + +    ], + +  }, + +  { + +    title: "auth pages", + +    layout: "auth", + +    pages: [ + +      { + +        icon: , + +        name: "sign in", + +        path: "/sign-in", + +        element: , + +      }, + +    ], + +  }, + ]; -export default routes; + + +export default routes; \ No newline at end of file diff --git a/src/widgets/layout/dashboard-navbar.jsx b/src/widgets/layout/dashboard-navbar.jsx index d91e23f7..00eaa89b 100644 --- a/src/widgets/layout/dashboard-navbar.jsx +++ b/src/widgets/layout/dashboard-navbar.jsx @@ -1,36 +1,23 @@ -import { useLocation, Link } from "react-router-dom"; -import { - Navbar, - Typography, - Button, - IconButton, - Breadcrumbs, - Input, - Menu, - MenuHandler, - MenuList, - MenuItem, - Avatar, -} from "@material-tailwind/react"; -import { - UserCircleIcon, - Cog6ToothIcon, - BellIcon, - ClockIcon, - CreditCardIcon, - Bars3Icon, -} from "@heroicons/react/24/solid"; -import { - useMaterialTailwindController, - setOpenConfigurator, - setOpenSidenav, -} from "@/context"; +import { ArrowRightOnRectangleIcon, Bars3Icon } from "@heroicons/react/24/solid"; +import { IconButton, Input, Navbar, Typography, Breadcrumbs } from "@material-tailwind/react"; +import { useMaterialTailwindController, setOpenSidenav } from "@/context"; +import { useLocation, Link, useNavigate } from "react-router-dom"; // 🔹 useNavigate eklendi export function DashboardNavbar() { const [controller, dispatch] = useMaterialTailwindController(); const { fixedNavbar, openSidenav } = controller; const { pathname } = useLocation(); const [layout, page] = pathname.split("/").filter((el) => el !== ""); + + + const navigate = useNavigate(); + +const handleLogout = () => { + localStorage.removeItem("authToken"); // Token sil + localStorage.removeItem("userRole"); // varsa rol bilgisini de sil + navigate("/auth/sign-in"); // Login ekranına yönlendir +}; + return ( -
+
+ {/* Breadcrumbs ve sayfa başlığı */}
- {layout} + {layout || "Home"} - - {page} + + {page || "Dashboard"} - - {page} + + {page || "Dashboard"}
-
+ + {/* Arama ve ikonlar */} +
- +
+ + {/* Sidenav toggle */} - - - - - - - - - - - - - - - -
- - New message from Laur - - - 13 minutes ago - -
-
- - -
- - New album by Travis Scott - - - 1 day ago - -
-
- -
- -
-
- - Payment successfully completed - - - 2 days ago - -
-
-
-
+ + {/* Çıkış butonu */} setOpenConfigurator(dispatch, true)} + color="red" + onClick={handleLogout} // 🔹 logout çağrıldı + className="rounded-full hover:bg-red-100 transition-colors" > - +
); } - -DashboardNavbar.displayName = "/src/widgets/layout/dashboard-navbar.jsx"; - -export default DashboardNavbar; diff --git a/src/widgets/layout/footer.jsx b/src/widgets/layout/footer.jsx index 1ea98e53..f2c59643 100644 --- a/src/widgets/layout/footer.jsx +++ b/src/widgets/layout/footer.jsx @@ -8,33 +8,7 @@ export function Footer({ brandName, brandLink, routes }) { return (
- - © {year}, made with{" "} - by{" "} - - {brandName} - {" "} - for a better web. - -
    - {routes.map(({ name, path }) => ( -
  • - - {name} - -
  • - ))} -
+
); diff --git a/src/widgets/layout/sidenav.jsx b/src/widgets/layout/sidenav.jsx index cc7e6ffe..091be2b8 100644 --- a/src/widgets/layout/sidenav.jsx +++ b/src/widgets/layout/sidenav.jsx @@ -11,22 +11,24 @@ import { useMaterialTailwindController, setOpenSidenav } from "@/context"; export function Sidenav({ brandImg, brandName, routes }) { const [controller, dispatch] = useMaterialTailwindController(); - const { sidenavColor, sidenavType, openSidenav } = controller; + + const { sidenavColor, sidenavType, openSidenav, userRole } = controller; const sidenavTypes = { dark: "bg-gradient-to-br from-gray-800 to-gray-900", white: "bg-white shadow-sm", transparent: "bg-transparent", }; + // Debug: Rolün doğru gelip gelmediğini kontrol etmek için + console.log("SIDEBAR'DAKİ ROL:", userRole); + return ( ); @@ -106,6 +112,6 @@ Sidenav.propTypes = { routes: PropTypes.arrayOf(PropTypes.object).isRequired, }; -Sidenav.displayName = "/src/widgets/layout/sidnave.jsx"; +Sidenav.displayName = "/src/widgets/layout/sidenav.jsx"; export default Sidenav;