Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions node_modules/.package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"dependencies": {
"@iconify/react": "^6.0.2",
"@tanstack/react-query": "^5.101.0",
"styled-components": "^6.4.2"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion web/.deprecated/app/components/login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
GoogleBtnContainer,
FormWrapper,
} from "./Login.styles";
import Notification from "../otherComponents/helpers/Notification";
import Notification from "../../../../components/helpers/notification/Notification";

const Login = () => {
const router = useRouter();
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion web/.deprecated/app/components/signup/Signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from "./Signup.styles";
import { useState, ChangeEvent } from "react";
import { useRouter } from "next/navigation";
import Notification from "../otherComponents/helpers/Notification";
import Notification from "../../../../components/helpers/notification/Notification";
import axios from "axios";
//import { useAuth } from "@/contexts/signupContext";
//import { signupAPI } from "@/apis/signup";
Expand Down
12 changes: 12 additions & 0 deletions web/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# NextAuth Configuration
NEXTAUTH_SECRET=your-secret-key-here-generate-with-openssl-rand-base64-32
NEXTAUTH_URL=http://localhost:3000

# Google OAuth Configuration
# Get these from https://console.cloud.google.com/
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-google-client-id-here
GOOGLE_CLIENT_SECRET=your-google-client-secret-here

# Backend Configuration
# Points to your Envoy proxy that routes to gRPC backend
NEXT_PUBLIC_ENVOY_BASE_URL=http://localhost:8081
2 changes: 1 addition & 1 deletion web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ yarn-error.log*

# env files (can opt-in for committing if needed)
.env*

todo
# vercel
.vercel

Expand Down
3 changes: 3 additions & 0 deletions web/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { handlers } from "@/auth";

export const { GET, POST } = handlers;
17 changes: 17 additions & 0 deletions web/app/api/dashboard/stats/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

import { NextRequest, NextResponse } from "next/server";
import { StatCardData } from "@/components/types/stats.types";

export async function GET(req: NextRequest) {
const range = req.nextUrl.searchParams.get("range") ?? "today";

const stats: StatCardData[] = [
{ id: "web-views", label: "Web Views", value: 658000, change: 3.05, format: "compact" },
{ id: "unique-visitors", label: "Unique Visitors", value: 246000, change: -8.36, format: "compact" },
{ id: "new-users", label: "New Users", value: 1352, change: 2.65, format: "number" },
{ id: "page-views", label: "Page view", value: 438, change: -0.37, format: "number" },
{ id: "active-users", label: "Active Users", value: 294000, change: 5.12, format: "compact" },
];

return NextResponse.json(stats);
}
21 changes: 21 additions & 0 deletions web/app/api/dashboard/total-users/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { NextRequest, NextResponse } from "next/server";
import { TotalUsersResponse } from "@/components/types/totalUsers.types";

export async function GET(req: NextRequest) {
const range = req.nextUrl.searchParams.get("range") ?? "today";

const labels = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat", "Sun"];

const points = labels.map((label, i) => ({
label,
current: Math.round(1000000 + i * 1800000 + Math.random() * 800000),
previous: Math.round(1500000 + i * 1600000 + Math.random() * 600000),
}));

const response: TotalUsersResponse = {
points,
latest: { label: "Sat", value: points[5].current },
};

return NextResponse.json(response);
}
15 changes: 15 additions & 0 deletions web/app/dashboard/dashboard.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import styled from "styled-components";
import { theme } from "@/components/libs/theme";

export const Container = styled.section`
width: 100%;
display: flex;
flex-wrap: wrap;
background: red;
color: white;
word-break: break-word;
overflow-wrap: anywhere;
padding: 1rem;
overflow-wrap: anywhere;

`
115 changes: 115 additions & 0 deletions web/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"use client";

import { useState } from "react";
import { SessionProvider } from "next-auth/react";
import { ThemeProvider } from "styled-components";
import { AppProvider } from "@/components/contexts/AppContext";
import { QueryProvider } from "@/components/contexts/QueryProvider";
import MenuBar from "@/components/layout/menuBar/MenuBar";
import DashboardHeader from "@/components/layout/header/DashboardHeader";
import { darkTheme } from "@/components/libs/theme2";
import styled from "styled-components";
import { Icon } from "@iconify/react";
import { usePathname } from "next/navigation";
import Link from "next/link";
import { menudata } from "@/components/constants/menuBar.data";

const DashboardLayoutWrapper = styled.div`
display: flex;
width: 100%;
height: 100vh;
overflow: hidden;
background-color: ${(props) => props.theme.colors.surface.main};
transition: ${(props) => props.theme.transitions.themeShift};
position: relative;
`;

const MainContentCanvas = styled.div`
display: flex;
flex-direction: column;
flex-grow: 1;
height: 100%;
width: 0;
overflow: hidden;
`;

const ScrollableDashboardBody = styled.main`
width: 100%;
min-width: 0;
flex-grow: 1;
overflow-y: auto;
overflow-x: hidden;
padding: ${(props) => props.theme.spacing.xl};
padding-bottom: 100px;

@media (max-width: 768px) {
padding: ${(props) => props.theme.spacing.lg};
padding-bottom: 90px;
}
`;

const MobileBottomNavBar = styled.nav`
display: none;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 65px;
background: ${(props) => props.theme.colors.surface.sidebar};
border-top: 1px solid ${(props) => props.theme.colors.border.subtle};
justify-content: space-around;
align-items: center;
z-index: 99;

@media (max-width: 768px) {
display: flex;
}
`;

const BottomNavItem = styled(Link)<{ $active: boolean }>`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: ${({ $active, theme }) => ($active ? theme.colors.brand : theme.colors.text.muted)};
font-size: 24px;
transition: ${(props) => props.theme.transitions.default};
`;

export default function DashboardLayout({ children }: { children: React.ReactNode }) {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState<boolean>(false);
const pathname = usePathname();

return (
<SessionProvider>
<QueryProvider>
<ThemeProvider theme={darkTheme}>
<AppProvider>
<DashboardLayoutWrapper>
<MenuBar isMobileOpen={isMobileMenuOpen} closeMobileMenu={() => setIsMobileMenuOpen(false)} />

<MainContentCanvas>
<DashboardHeader onMenuToggle={() => setIsMobileMenuOpen(!isMobileMenuOpen)} />
<ScrollableDashboardBody>
{children}
</ScrollableDashboardBody>
</MainContentCanvas>

<MobileBottomNavBar>
{menudata.slice(0, 4).map((item) => (
<BottomNavItem
href={item.path}
key={item.id}
$active={pathname === item.path}
>
<Icon icon={item.icon} />
</BottomNavItem>
))}
</MobileBottomNavBar>
</DashboardLayoutWrapper>
</AppProvider>
</ThemeProvider>
</QueryProvider>
</SessionProvider>
);
}
22 changes: 22 additions & 0 deletions web/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use client";

import { useDateRange } from "@/components/hooks/useDateRange";
import DateRangeFilter from "@/components/pages/dashboard/DateRangeFilter";
import StatsOverview from "@/components/pages/dashboard/StatsOverview";
import TotalUsersChart from "@/components/pages/dashboard/TotalUsersChart";
import { ChartsRow } from "@/components/pages/dashboard/ChartsLayout.styles";

export default function Dashboard() {
const dateRange = useDateRange();

return (
<div>
<DateRangeFilter dateRange={dateRange} />
<StatsOverview range={dateRange.selected} />

<ChartsRow>
<TotalUsersChart range={dateRange.selected} />
</ChartsRow>
</div>
);
}
7 changes: 7 additions & 0 deletions web/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,11 @@ svg {
html, body {
overflow-x: hidden;
max-width: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
}

*, *::before, *::after {
box-sizing: border-box;
}
9 changes: 2 additions & 7 deletions web/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Metadata } from "next";
import { Poppins } from "next/font/google";
import "./globals.css";
import StyledComponentsRegistry from "@/components/libs/registry";
import LayoutShell from "@/components/layout/LayoutShell";

const poppins = Poppins({
variable: "--font-poppins",
Expand All @@ -13,19 +12,15 @@ const poppins = Poppins({
export const metadata: Metadata = {
title: "Upstat",
description: "The Upstat Project",
viewport: {
width: "device-width",
initialScale: 1,
maximumScale: 1,
},
};


export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={poppins.variable}>
<body>
<StyledComponentsRegistry>
<LayoutShell>{children}</LayoutShell>
{children}
</StyledComponentsRegistry>
</body>
</html>
Expand Down
3 changes: 3 additions & 0 deletions web/app/login/Login.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import styled from "styled-components";
import { SignupContainer, FormHeading, FormSection, GoogleBtn } from '../signup/Signup.styles'
export { SignupContainer, FormHeading, FormSection, GoogleBtn };
Loading