diff --git a/App.css b/App.css new file mode 100644 index 0000000..f90339d --- /dev/null +++ b/App.css @@ -0,0 +1,184 @@ +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/App.jsx b/App.jsx new file mode 100644 index 0000000..5170ed1 --- /dev/null +++ b/App.jsx @@ -0,0 +1,67 @@ +import { useState, useContext, useEffect } from "react" + +import Sidebar from "./components/Sidebar" + +import Dashboard from "./Pages/Dashboard" +import LoginPage from "./Pages/LoginPage" +import AdminDashboard from "./Pages/AdminDashboard" +import HistoryPembelian from "./Pages/HistoryPembelian" + +import { AuthContext } from "./context/AuthContext" + +export default function App() { + + const { user } = useContext(AuthContext) + + const [page, setPage] = useState("dashboard") + + // 🔥 AUTO SET PAGE BERDASARKAN ROLE + useEffect(() => { + + if (!user) return + + const role = user?.role?.toLowerCase() + + if (role === "admin") { + setPage("admin") + } else { + setPage("dashboard") + } + + }, [user]) + + // 🔥 BELUM LOGIN + if (!user) { + return + } + + return ( +
+ + {/* SIDEBAR */} + + + {/* CONTENT */} +
+ + {/* USER DASHBOARD */} + {page === "dashboard" && } + + {/* HISTORY PEMBELIAN */} + {page === "history" && } + + {/* ADMIN DASHBOARD */} + {page === "admin" && } + +
+ +
+ ) +} \ No newline at end of file diff --git a/index.css b/index.css new file mode 100644 index 0000000..7111d4c --- /dev/null +++ b/index.css @@ -0,0 +1,92 @@ +:root { + font-family: + Inter, + system-ui, + sans-serif; + + color: #f8fafc; + + background: + linear-gradient( + 135deg, + #020617, + #0f172a, + #111827 + ); + + font-synthesis: none; + + text-rendering: + optimizeLegibility; + + -webkit-font-smoothing: + antialiased; + + -moz-osx-font-smoothing: + grayscale; +} + +* { + box-sizing: border-box; +} + +html, +body, +#root { + margin: 0; + padding: 0; + + width: 100%; + min-height: 100vh; +} + +body { + background: + radial-gradient( + circle at top left, + rgba(245,158,11,0.18), + transparent 20% + ), + + radial-gradient( + circle at bottom right, + rgba(239,68,68,0.12), + transparent 25% + ), + + linear-gradient( + 135deg, + #020617, + #0f172a, + #111827 + ); + + color: #f8fafc; +} + +button { + font-family: inherit; +} + +a { + color: inherit; + text-decoration: none; +} + +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: #0f172a; +} + +::-webkit-scrollbar-thumb { + background: + linear-gradient( + #f59e0b, + #ea580c + ); + + border-radius: 999px; +} \ No newline at end of file diff --git a/main.jsx b/main.jsx new file mode 100644 index 0000000..a6dd5ff --- /dev/null +++ b/main.jsx @@ -0,0 +1,17 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' + +import './index.css' +import App from './App.jsx' + +import { AuthProvider } from './context/AuthContext.jsx' + +createRoot(document.getElementById('root')).render( + + + + + + + , +) \ No newline at end of file