Merge pull request #4 from mitchell131/refactor-with-scss

refactor scss
This commit is contained in:
Mitchell Magro 2025-07-02 08:39:30 +02:00 committed by GitHub
commit a78fd2e8a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 374 additions and 285 deletions

View File

@ -1,6 +1,4 @@
/* PageLinks.scss */
.link-container {
.page-link__container {
display: flex;
align-items: center;
padding: 12px 1px;
@ -14,10 +12,9 @@
background-color: var(--hover-color);
cursor: pointer;
}
}
.link-text {
.page-link__text {
color: var(--text-tertiary);
margin-left: 12px;
font-weight: 500;
}
}

View File

@ -15,10 +15,10 @@ export default function PageLinks({
icon: Icon,
}: IPageLinksProps) {
return (
<Link href={path} passHref legacyBehavior>
<a className={clsx("link-container")}>
<Link href={path} passHref legacyBehavior className="page-link">
<a className={clsx("page-link__container")}>
{Icon && <Icon />}
<span className="link-text">{title}</span>
<span className="page-link__text">{title}</span>
</a>
</Link>
);

View File

@ -0,0 +1,7 @@
.account-iq {
.account-iq__icon {
font-weight: bold;
color: #4ecdc4;
margin-top: 4px;
}
}

View File

@ -1,17 +1,13 @@
import { styled } from "@mui/material";
import { Box } from "@mui/material";
import { SectionCard } from "../SectionCard/SectionCard";
const AccountIQIcon = styled("div")(() => ({
fontWeight: "bold",
color: "#4ecdc4",
marginTop: "4px",
}));
import "./AccountIQ.scss";
export const AccountIQ = () => {
return (
<Box className="account-iq">
<SectionCard
title="AccountIQ"
icon={<AccountIQIcon>AIQ</AccountIQIcon>}
icon={<div className="account-iq__icon">AIQ</div>}
items={[
{ title: "Automatically reconcile your transactions" },
{ title: "Live wallet balances from providers" },
@ -19,5 +15,6 @@ export const AccountIQ = () => {
{ title: "Learn more" },
]}
/>
</Box>
);
};

View File

@ -0,0 +1,12 @@
.date-range-picker {
.date-range-picker__date-typo {
font-size: 0.875rem;
cursor: pointer;
padding: 8px;
border-radius: 4px;
&:hover {
background-color: rgba(0, 0, 0, 0.04);
}
}
}

View File

@ -6,18 +6,20 @@ import { format } from "date-fns";
import "react-date-range/dist/styles.css";
import "react-date-range/dist/theme/default.css";
import "./DateRangePicker.scss";
export const DateRangePicker = () => {
const [range, setRange] = useState<Range[]>([
{
startDate: new Date(),
endDate: new Date(),
key: "selection"
}
key: "selection",
},
]);
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const handleSelect: DateRangeProps['onChange'] = (ranges) => {
const handleSelect: DateRangeProps["onChange"] = (ranges) => {
if (ranges.selection) {
setRange([ranges.selection]);
if (ranges.selection.endDate !== ranges.selection.startDate) {
@ -35,22 +37,22 @@ export const DateRangePicker = () => {
};
const open = Boolean(anchorEl);
const id = open ? 'date-range-popover' : undefined;
const id = open ? "date-range-popover" : undefined;
return (
<Box>
<Box className="date-range-picker">
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
vertical: "top",
horizontal: "left",
}}
>
<Paper>
@ -66,19 +68,12 @@ export const DateRangePicker = () => {
<Box>
<Typography
onClick={handleClick}
sx={{
fontSize: '0.875rem',
cursor: 'pointer',
p: 1,
borderRadius: 1,
'&:hover': {
backgroundColor: 'action.hover',
}
}}
className="date-range-picker__date-typo"
>
{format(range[0].startDate ?? new Date(), "PPP")} - {format(range[0].endDate ?? new Date(), "PPP")}
{format(range[0].startDate ?? new Date(), "PPP")} -{" "}
{format(range[0].endDate ?? new Date(), "PPP")}
</Typography>
</Box>
</Box>
);
}
};

View File

@ -0,0 +1,5 @@
.documentation {
.documentation__icon {
height: auto;
}
}

View File

@ -1,12 +1,17 @@
import React from "react";
import DescriptionIcon from "@mui/icons-material/Description";
import { SectionCard } from "../SectionCard/SectionCard";
import { Box } from "@mui/material";
import "./Documentation.scss";
export const Documentation = () => {
return (
<Box className="documentation">
<SectionCard
title="Documentation"
icon={<DescriptionIcon fontSize="small" sx={{ height: "auto" }} />}
icon={
<DescriptionIcon className="documentation__icon" fontSize="small" />
}
items={[
{ title: "Provider Integration Overview" },
{ title: "APIs Introduction" },
@ -14,5 +19,6 @@ export const Documentation = () => {
{ title: "How-Tos" },
]}
/>
</Box>
);
};

View File

@ -0,0 +1,6 @@
.fetch-report {
padding: 23px;
margin: 16px;
display: flex;
flex-direction: column;
}

View File

@ -16,6 +16,8 @@ import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import { DateRangePicker } from "../DateRangePicker/DateRangePicker";
import "./FetchReport.scss";
export const FetchReport = () => {
const [state, setState] = useState("");
const [psp, setPsp] = useState("");
@ -29,15 +31,7 @@ export const FetchReport = () => {
const isDownloadEnabled = state && psp && reportType;
return (
<Paper
elevation={3}
sx={{
padding: "23px",
margin: 2,
display: "flex",
flexDirection: "column",
}}
>
<Paper className="fetch-report" elevation={3}>
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 2 }}>
<Typography variant="h6" fontWeight="bold">
Fetch Report

View File

@ -0,0 +1,18 @@
.general-health-card {
.general-health-card__header {
display: flex;
justify-content: space-between;
margin-bottom: 16px;
.general-health-card__right-side {
display: flex;
align-items: center;
}
}
.general-health-card__stat-items {
display: flex;
justify-content: space-around;
margin-top: 16px;
}
}

View File

@ -1,8 +1,10 @@
import { Box, Card, CardContent, Typography, IconButton } from "@mui/material";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import CalendarTodayIcon from "@mui/icons-material/CalendarToday";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import { DateRangePicker } from "../DateRangePicker/DateRangePicker";
import { StatItem } from "./components/StatItem";
import "./GeneralHealthCard.scss";
const stats = [
{ label: "TOTAL", value: 5, change: "-84.85%" },
@ -12,46 +14,15 @@ const stats = [
{ label: "ATV", value: "€0.00", change: "-100%" },
];
const StatItem = ({
label,
value,
change,
}: {
label: string;
value: string | number;
change: string;
}) => (
<Box sx={{ textAlign: "center", px: 2 }}>
<Typography variant="body2" fontWeight="bold" color="text.secondary">
{label}
</Typography>
<Typography variant="h6" fontWeight="bold" mt={0.5}>
{value}
</Typography>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "error.main",
}}
>
<ArrowDropDownIcon fontSize="small" />
{/* <ArrowDropUp fontSize='small' /> */}
<Typography variant="caption">{change}</Typography>
</Box>
</Box>
);
export const GeneralHealthCard = () => {
return (
<Card sx={{ borderRadius: 3, p: 2 }}>
<Card className="general-health-card">
<CardContent>
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 2 }}>
<Box className="general-health-card__header">
<Typography variant="h5" fontWeight="bold">
General Health
</Typography>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Box className="general-health-card__right-side">
<CalendarTodayIcon fontSize="small" />
<Typography variant="body2">
<DateRangePicker />
@ -61,7 +32,7 @@ export const GeneralHealthCard = () => {
</IconButton>
</Box>
</Box>
<Box sx={{ display: "flex", justifyContent: "space-around", mt: 2 }}>
<Box className="general-health-card__stat-items">
{stats.map((item, i) => (
<StatItem key={item.label + i} {...item} />
))}

View File

@ -0,0 +1,12 @@
.static-item {
text-align: center;
padding-left: 16px;
padding-right: 16px;
.static-item__percentage {
display: flex;
align-items: center;
justify-content: center;
color: red;
}
}

View File

@ -0,0 +1,27 @@
import { Box, Typography } from "@mui/material";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import "./StatItem.scss";
export const StatItem = ({
label,
value,
change,
}: {
label: string;
value: string | number;
change: string;
}) => (
<Box className="static-item">
<Typography variant="body2" fontWeight="bold" color="text.secondary">
{label}
</Typography>
<Typography variant="h6" fontWeight="bold" mt={0.5}>
{value}
</Typography>
<Box className="static-item__percentage">
<ArrowDropDownIcon fontSize="small" />
{/* <ArrowDropUp fontSize='small' /> */}
<Typography variant="caption">{change}</Typography>
</Box>
</Box>
);

View File

@ -1,11 +1,11 @@
import { Box } from "@mui/material"
import { GeneralHealthCard } from "../../GeneralHealthCard/GeneralHealthCard"
import { TransactionsOverview } from "../../TransactionsOverview/TransactionsOverview"
import { TransactionsWaitingApproval } from "../../TransactionsWaitingApproval/TransactionsWaitingApproval"
import { FetchReport } from "../../FetchReports/FetchReports"
import { Documentation } from "../../Documentation/Documentation"
import { AccountIQ } from "../../AccountIQ/AccountIQ"
import { WhatsNew } from "../../WhatsNew/WhatsNew"
import { Box } from "@mui/material";
import { GeneralHealthCard } from "../../GeneralHealthCard/GeneralHealthCard";
import { TransactionsOverView } from "../../TransactionsOverView/TransactionsOverView";
import { TransactionsWaitingApproval } from "../../TransactionsWaitingApproval/TransactionsWaitingApproval";
import { FetchReport } from "../../FetchReports/FetchReports";
import { Documentation } from "../../Documentation/Documentation";
import { AccountIQ } from "../../AccountIQ/AccountIQ";
import { WhatsNew } from "../../WhatsNew/WhatsNew";
export const DashboardHomePage = () => {
return (
@ -13,12 +13,12 @@ export const DashboardHomePage = () => {
<Box sx={{ p: 2 }}>
<GeneralHealthCard />
</Box>
<TransactionsOverview />
<TransactionsOverView />
<FetchReport />
<TransactionsWaitingApproval />
<Documentation />
<AccountIQ />
<WhatsNew />
</>
)
}
);
};

View File

@ -0,0 +1,8 @@
.pie-charts {
width: 100%;
height: 300px;
@media (min-width: 960px) {
width: 60%;
}
}

View File

@ -1,12 +1,12 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Box } from "@mui/material";
import { PieChart, Pie, Cell, ResponsiveContainer } from "recharts";
import "./PieCharts.scss";
const data = [
{ name: "Group A", value: 100 },
{ name: "Group B", value: 200 },
{ name: "Group C", value: 400 },
{ name: "Group D", value: 300 }
{ name: "Group D", value: 300 },
];
const COLORS = ["#4caf50", "#ff9800", "#f44336", "#9e9e9e"];
@ -19,7 +19,7 @@ const renderCustomizedLabel = ({
innerRadius,
outerRadius,
percent,
// index
// index
}: any) => {
const radius = innerRadius + (outerRadius - innerRadius) * 0.5;
const x = cx + radius * Math.cos(-midAngle * RADIAN);
@ -39,12 +39,7 @@ const renderCustomizedLabel = ({
};
export const PieCharts = () => {
return (
<Box sx={{
width: {
xs: '100%',
md: '60%'
}, height: '300px'
}}>
<Box className="pie-charts">
<ResponsiveContainer width="100%" height="100%">
<PieChart>
<Pie
@ -58,12 +53,14 @@ export const PieCharts = () => {
dataKey="value"
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
<Cell
key={`cell-${index}`}
fill={COLORS[index % COLORS.length]}
/>
))}
</Pie>
</PieChart>
</ResponsiveContainer>
</Box >
</Box>
);
}
};

View File

@ -0,0 +1,20 @@
.section-card {
padding: 16px;
margin: 16px;
display: flex;
flex-direction: column;
.section-card__header {
display: flex;
justify-content: space-between;
margin-bottom: 16px;
.section-card__title {
display: flex;
gap: 16px;
}
.section-card__icon-wrapper {
display: flex;
align-items: center;
gap: 16px;
}
}
}

View File

@ -13,20 +13,19 @@ import {
import MoreVertIcon from "@mui/icons-material/MoreVert";
import { ISectionCardProps } from "./types";
import "./SectionCard.scss";
export const SectionCard = ({ title, icon, items }: ISectionCardProps) => (
<Paper
elevation={3}
sx={{ padding: 2, margin: 2, display: "flex", flexDirection: "column" }}
>
<Paper className="section-card" elevation={3}>
<CardContent>
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 2 }}>
<Box sx={{ display: "flex", gap: 1 }}>
<Box className="section-card__header">
<Box className="section-card__title">
{icon}
<Typography variant="h6" fontWeight="bold">
{title}
</Typography>
</Box>
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Box className="section-card__icon-wrapper">
<IconButton size="small">
<MoreVertIcon fontSize="small" />
</IconButton>
@ -36,12 +35,7 @@ export const SectionCard = ({ title, icon, items }: ISectionCardProps) => (
<List dense disablePadding>
{items.map((item, index) => (
<ListItem key={item.title + index} disableGutters>
<ListItemText
primary={item.title}
secondary={item.date}
primaryTypographyProps={{ fontSize: 14 }}
secondaryTypographyProps={{ fontSize: 12 }}
/>
<ListItemText primary={item.title} secondary={item.date} />
</ListItem>
))}
</List>

View File

@ -0,0 +1,28 @@
.transaction-overview {
padding: 23px;
margin: 16px;
display: flex;
flex-direction: column;
.transaction-overview__header {
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 8px;
padding-right: 8px;
}
.transaction-overview__chart-table {
padding: 16px;
margin: 16px;
display: flex;
flex-direction: row;
gap: 32px;
flex-wrap: wrap;
@media (min-width: 960px) {
flex-wrap: nowrap;
gap: 0;
}
}
}

View File

@ -0,0 +1,17 @@
.transactions-overview-table {
.transactions-overview-table__state-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
margin-left: auto;
margin-right: auto;
width: 73px;
.transactions-overview-table__state {
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 8px;
}
}
}

View File

@ -10,6 +10,8 @@ import {
Button,
} from "@mui/material";
import "./TransactionsOverViewTable.scss";
const data1 = [
{ state: "Success", count: 120, percentage: "60%", color: "green" },
{ state: "Pending", count: 50, percentage: "25%", color: "orange" },
@ -17,9 +19,9 @@ const data1 = [
{ state: "Other", count: 10, percentage: "5%", color: "gray" },
];
export const TransactionsOverviewTable = () => {
export const TransactionsOverViewTable = () => {
return (
<TableContainer component={Paper}>
<TableContainer className="transactions-overview-table" component={Paper}>
<Table>
<TableHead>
<TableRow>
@ -33,22 +35,11 @@ export const TransactionsOverviewTable = () => {
{data1.map((row, i) => (
<TableRow key={row.state + i}>
<TableCell align="center">
<Box className="transactions-overview-table__state-wrapper">
<Box
className="transactions-overview-table__state"
sx={{
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
mx: "auto", // center the flexbox itself
width: "73px", // consistent width for alignment
}}
>
<Box
sx={{
width: 10,
height: 10,
borderRadius: "50%",
bgcolor: row.color,
mr: 1,
}}
/>
{row.state}

View File

@ -3,29 +3,16 @@ import { Box, Button, IconButton, Paper, Typography } from "@mui/material";
import { PieCharts } from "../PieCharts/PieCharts";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import { TransactionsOverviewTable } from "./TransactionsOverViewTable";
import { TransactionsOverViewTable } from "./components/TransactionsOverViewTable";
export const TransactionsOverview = () => {
import "./TransactionsOverView.scss";
export const TransactionsOverView = () => {
const router = useRouter();
return (
<Paper
elevation={3}
sx={{
padding: "23px",
margin: 2,
display: "flex",
flexDirection: "column",
}}
>
<Paper className="transaction-overview" elevation={3}>
{/* Title and All Transactions Button */}
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
px: 1,
}}
>
<Box className="transaction-overview__header">
<Typography variant="h5" fontWeight="bold">
Transactions Overview (Last 24h)
</Typography>
@ -44,24 +31,9 @@ export const TransactionsOverview = () => {
</Box>
{/* Chart and Table */}
<Box
sx={{
padding: 2,
margin: 2,
display: "flex",
flexDirection: "row",
flexWrap: {
xs: "wrap", // Wrap on small screens
md: "nowrap", // No wrap on medium and up
},
gap: {
xs: 4, // Add spacing on small screens
md: 0, // No spacing on larger screens
},
}}
>
<Box className="transaction-overview__chart-table">
<PieCharts />
<TransactionsOverviewTable />
<TransactionsOverViewTable />
</Box>
</Paper>
);

View File

@ -0,0 +1,6 @@
.transactions-waiting-approval {
padding: 16px;
margin: 16px;
display: flex;
flex-direction: column;
}

View File

@ -16,6 +16,7 @@ import CancelIcon from "@mui/icons-material/Cancel";
import MoreVertIcon from "@mui/icons-material/MoreVert";
import "./TransactionsWaitingApproval.scss";
const transactions = [
{
id: "1049078821",
@ -117,10 +118,7 @@ const transactions = [
export const TransactionsWaitingApproval = () => {
return (
<Paper
elevation={3}
sx={{ padding: 2, margin: 2, display: "flex", flexDirection: "column" }}
>
<Paper elevation={3} className="transactions-waiting-approval">
<Box sx={{ p: 3 }}>
<Box sx={{ display: "flex", justifyContent: "space-between", mb: 2 }}>
<Typography variant="h5" fontWeight="bold">

View File

@ -0,0 +1,5 @@
.whats-new {
.whats-new__wifi-icon {
height: auto;
}
}

View File

@ -1,11 +1,14 @@
import { Box } from "@mui/material";
import { SectionCard } from "../SectionCard/SectionCard";
import WifiIcon from "@mui/icons-material/Wifi";
import "./WhatsNew.scss";
export const WhatsNew = () => {
return (
<Box className="whats-new">
<SectionCard
title="Whats New"
icon={<WifiIcon fontSize="small" sx={{ height: "auto" }} />}
icon={<WifiIcon className="whats-new__wifi-icon" fontSize="small" />}
items={[
{
title: "Sneak Peek Discover the New Rules Hub Feature",
@ -23,5 +26,6 @@ export const WhatsNew = () => {
{ title: "Introducing Our New Status Page", date: "09 Sept 2024" },
]}
/>
</Box>
);
};

View File

@ -1,17 +1,19 @@
.header-toolbar {
.header {
.header__toolbar {
display: flex;
align-items: center;
.left-group {
.header__left-group {
width: 100px;
display: flex;
align-items: center;
gap: 12px; // optional spacing between menu and dropdown
}
.right-group {
.header__right-group {
margin-left: auto; // pushes it to the far right
display: flex;
align-items: center;
}
}
}

View File

@ -1,5 +1,5 @@
import React, { useState } from "react";
import { AppBar, Toolbar, IconButton, Menu, MenuItem } from "@mui/material";
import { AppBar, Toolbar, IconButton } from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import Dropdown from "./dropDown/DropDown";
import AccountMenu from "./accountMenu/AccountMenu";
@ -22,20 +22,21 @@ const Header = () => {
return (
<AppBar
className="header"
position="sticky"
color="transparent"
elevation={0}
sx={{ borderBottom: "1px solid #22242626" }}
>
<Toolbar className="header-toolbar">
<div className="left-group">
<Toolbar className="header__toolbar">
<div className="header__left-group">
<IconButton edge="start" color="inherit" aria-label="menu">
<MenuIcon />
</IconButton>
<Dropdown onChange={handleChange} />
</div>
<div className="right-group">
<div className="header__right-group">
<AccountMenu />
</div>
</Toolbar>

View File

@ -1,7 +1,7 @@
.dropdown-container {
.link-container {
.sidebar-dropdown__container {
.page-link__container {
color: var(--text-secondary);
.link-text {
.page-link__text {
color: var(--text-primary);
}
}

View File

@ -41,7 +41,7 @@ export default function SidebarDropdown({ onChange }: Props) {
>
<em className="em">Select a page</em>
<MenuItem value="" disabled></MenuItem>
<div className="dropdown-container">
<div className="sidebar-dropdown__container">
{PAGE_LINKS.map((link: ISidebarLink) => (
<PageLinks key={link.path} title={link.title} path={link.path} />
))}

View File

@ -1,6 +1,5 @@
"use client";
import React from "react";
import DashboardIcon from "@mui/icons-material/Dashboard";
import { PAGE_LINKS } from "@/app/features/dashboard/sidebar/SidebarLink.constants";
import PageLinks from "../../../components/PageLinks/PageLinks";
@ -8,11 +7,11 @@ import "./sideBar.scss";
const SideBar = () => {
return (
<aside className="sidebar-container">
<div className="sidebar-header">
<aside className="sidebar">
<div className="sidebar__header">
<span>
Betrise cashir{" "}
<DashboardIcon fontSize="small" className="sidebar-icon-spacing" />
<DashboardIcon fontSize="small" className="sidebar__icon-spacing" />
</span>
</div>
{PAGE_LINKS.map((link) => (

View File

@ -1,4 +1,4 @@
.sidebar-container {
.sidebar {
position: fixed;
top: 0;
left: 0;
@ -11,17 +11,17 @@
padding: 16px;
z-index: 1100;
border-right: 1px solid #333;
}
.sidebar-header {
.sidebar__header {
font-size: 20px;
font-weight: 600;
margin-bottom: 24px;
display: flex;
align-items: center;
color: white;
}
.sidebar-icon-spacing {
.sidebar__icon-spacing {
margin-left: 8px;
}
}
}