Skip to content

Commit

Permalink
Add sharecodes report
Browse files Browse the repository at this point in the history
  • Loading branch information
tructn committed Dec 13, 2024
1 parent 157d55f commit db21a77
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 54 deletions.
10 changes: 4 additions & 6 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ const HealthScreen = lazy(() => import("./screens/health"));
const SportCentersScreen = lazy(() => import("./screens/sportcenter"));
const SettingsScreen = lazy(() => import("./screens/settings"));
const PageNotFoundScreen = lazy(() => import("./screens/page-not-found"));
const AttendantRequestScreen = lazy(
() => import("./components/attendant-requests"),
);
const Requests = lazy(() => import("./components/requests"));
const AdminRequestScreen = lazy(() => import("./screens/admin-requests"));
const Reportings = lazy(() => import("./screens/reporting"));
const ReportingScreen = lazy(() => import("./screens/reporting"));
const PublicOutstandingReport = lazy(
() => import("./screens/public/outstanding-report"),
);
Expand All @@ -33,14 +31,14 @@ function App() {
<Route path="players" element={<PlayerScreen />} />
<Route path="matches" element={<MatchesScreen />} />
<Route path="sportcenters" element={<SportCentersScreen />} />
<Route path="reports" element={<Reportings />} />
<Route path="reports" element={<ReportingScreen />} />
<Route path="health" element={<HealthScreen />} />
<Route path="settings" element={<SettingsScreen />} />
<Route path="*" element={<PageNotFoundScreen />} />
</Route>
) : (
<Route element={<PublicLayout />}>
<Route index element={<AttendantRequestScreen />} />
<Route index element={<Requests />} />
</Route>
)}
<Route path="/login" element={<Landing />} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { FC } from "react";
import Loading from "../loading";
import SectionLoading from "../section-loading";

interface Props {
text?: string;
}

const FullScreenLoading: FC<Props> = ({ text }) => {
const AppLoading: FC<Props> = ({ text }) => {
return (
<div className="flex h-screen w-screen flex-col items-center justify-center">
<Loading text={text} />
<SectionLoading text={text} />
</div>
);
};

export default FullScreenLoading;
export default AppLoading;
4 changes: 2 additions & 2 deletions frontend/src/components/profile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import Loading from "../loading";
import SectionLoading from "../section-loading";
import { useAuth0 } from "@auth0/auth0-react";
import { Navigate } from "react-router-dom";

Expand All @@ -11,7 +11,7 @@ const UserProfile: React.FC<UserProfileProp> = ({ showLabel }) => {
const { user, isAuthenticated, isLoading } = useAuth0();

if (isLoading) {
return <Loading />;
return <SectionLoading />;
}

if (!isAuthenticated) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { MatchSummaryModel } from "../../models";
import { useApi } from "../../hooks/useApi";

export default function AttendantRequests() {
export default function Requests() {
const api = useApi();
const { user } = useAuth0();
const { data: attendantRequests, refetch: refetchAttendants } =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface Props {
text?: string;
}

const Loading: FC<Props> = ({ text }) => {
const SectionLoading: FC<Props> = ({ text }) => {
return (
<div className="flex h-full w-full items-center justify-center">
<div className="flex items-center space-x-2">
Expand All @@ -16,4 +16,4 @@ const Loading: FC<Props> = ({ text }) => {
);
};

export default Loading;
export default SectionLoading;
4 changes: 2 additions & 2 deletions frontend/src/screens/admin-requests/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import AttendantRequests from "../../components/attendant-requests";
import Page from "../../components/page";
import Requests from "../../components/requests";

export default function AdminRequests() {
return (
<Page title="Attendant Requests">
<div className="flex items-center justify-center">
<AttendantRequests />
<Requests />
</div>
</Page>
);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/screens/dashboard/match-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import dayjs from "dayjs";
import React, { Suspense } from "react";
import { FiMapPin } from "react-icons/fi";
import formatter from "../../common/formatter";
import Loading from "../../components/loading";
import SectionLoading from "../../components/section-loading";
import { MatchSummaryModel } from "../../models";
import MatchListContent from "./match-list-content";

Expand Down Expand Up @@ -47,7 +47,7 @@ const MatchList: React.FC<Prop> = ({ matches, expandFirstItem }) => {
</div>
</Accordion.Control>
<Accordion.Panel>
<Suspense fallback={<Loading />}>
<Suspense fallback={<SectionLoading />}>
<MatchListContent match={m} />
</Suspense>
</Accordion.Panel>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/screens/layouts/admin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { Tooltip } from "@mantine/core";
import cx from "clsx";
import { FC, ReactNode, Suspense, useState } from "react";
import { Navigate, NavLink, Outlet } from "react-router-dom";
import FullScreenLoading from "../../components/fullscreen-loading";
import Loading from "../../components/loading";
import AppLoading from "../../components/app-loading";
import SectionLoading from "../../components/section-loading";
import LogoutButton from "../../components/logout-button";
import UserProfile from "../../components/profile";

Expand Down Expand Up @@ -56,7 +56,7 @@ function AdminLayout() {
}

if (isLoading) {
return <FullScreenLoading text="Log you in..." />;
return <AppLoading text="Log you in..." />;
}

if (!isAuthenticated || !user) {
Expand Down Expand Up @@ -141,7 +141,7 @@ function AdminLayout() {
</div>
</div>
<div className="flex w-full flex-1 bg-slate-300">
<Suspense fallback={<Loading />}>
<Suspense fallback={<SectionLoading />}>
<Outlet />
</Suspense>
</div>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/screens/layouts/public.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { Menu, rem } from "@mantine/core";
import { IconLogout } from "@tabler/icons-react";
import { Suspense } from "react";
import { Navigate, Outlet, useNavigate } from "react-router-dom";
import FullScreenLoading from "../../components/fullscreen-loading";
import Loading from "../../components/loading";
import AppLoading from "../../components/app-loading";
import SectionLoading from "../../components/section-loading";

function PublicLayout() {
const { user, isAuthenticated, isLoading, logout } = useAuth0();
const navigate = useNavigate();

if (isLoading) {
return <FullScreenLoading />;
return <AppLoading />;
}

if (!isAuthenticated && !user) {
Expand Down Expand Up @@ -53,7 +53,7 @@ function PublicLayout() {
</Menu.Dropdown>
</Menu>

<Suspense fallback={<Loading />}>
<Suspense fallback={<SectionLoading />}>
<Outlet />
</Suspense>
</div>
Expand Down
29 changes: 19 additions & 10 deletions frontend/src/screens/reporting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@ import { rem, Tabs } from "@mantine/core";
import { IconMoneybag, IconTimeline } from "@tabler/icons-react";
import { lazy, Suspense, useState } from "react";
import Page from "../../components/page";
import Loading from "../../components/loading";
import SectionLoading from "../../components/section-loading";

type TabType = "outstanding-payment" | "activity-log";
type TabType = "unpaid" | "activity-log" | "share-codes";

const OutstandingPayments = lazy(() => import("./outstanding-payments"));
const Unpaid = lazy(() => import("./unpaid"));
const ActivityLogs = lazy(() => import("./activity-log"));
const ShareCodes = lazy(() => import("./sharecodes"));

export default function Reporting() {
const iconStyle = { width: rem(16), height: rem(16) };
const [tab, setTab] = useState<TabType>("outstanding-payment");
const [tab, setTab] = useState<TabType>("unpaid");

return (
<Page title="Reports">
<Tabs defaultValue="outstanding-payment">
<Tabs defaultValue="unpaid">
<Tabs.List>
<Tabs.Tab
value="outstanding-payment"
value="unpaid"
leftSection={<IconMoneybag style={iconStyle} />}
onClick={() => setTab("outstanding-payment")}
onClick={() => setTab("unpaid")}
>
Outstanding Payments
Unpaid
</Tabs.Tab>
<Tabs.Tab
value="activity-log"
Expand All @@ -31,12 +32,20 @@ export default function Reporting() {
>
Activities
</Tabs.Tab>
<Tabs.Tab
value="share-codes"
leftSection={<IconTimeline style={iconStyle} />}
onClick={() => setTab("share-codes")}
>
Share Codes
</Tabs.Tab>
</Tabs.List>

<Tabs.Panel value={tab}>
<Suspense fallback={<Loading />}>
{tab === "outstanding-payment" && <OutstandingPayments />}
<Suspense fallback={<SectionLoading />}>
{tab === "unpaid" && <Unpaid />}
{tab === "activity-log" && <ActivityLogs />}
{tab === "share-codes" && <ShareCodes />}
</Suspense>
</Tabs.Panel>
</Tabs>
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/screens/reporting/models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ShareUrlModel {
id: string;
fullUrl: string;
}
58 changes: 58 additions & 0 deletions frontend/src/screens/reporting/sharecodes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Button, Table } from "@mantine/core";
import { useMutation, useQuery } from "@tanstack/react-query";

import { FiTrash } from "react-icons/fi";
import { useApi } from "../../hooks/useApi";
import { ShareUrlModel } from "./models";
import DataTableSkeleton from "../../components/skeleton/data-table-skeleton";

export default function ShareCodes() {
const { get, del } = useApi();

const { data, refetch, isPending } = useQuery({
queryKey: ["getShareUrls"],
queryFn: () => get<ShareUrlModel[]>("api/v1/share-codes/urls"),
});

const deleteMut = useMutation({
mutationFn: (id: string) => del(`api/v1/share-codes/urls/${id}`),
});

return (
<Table striped highlightOnHover withRowBorders={false}>
<Table.Thead>
<Table.Tr>
<Table.Th>ID</Table.Th>
<Table.Th>URL</Table.Th>
<Table.Th></Table.Th>
</Table.Tr>
</Table.Thead>
<Table.Tbody>
{isPending ? (
<DataTableSkeleton row={3} col={3} />
) : (
data?.map((item) => {
return (
<Table.Tr key={item.id}>
<Table.Td>{item.id}</Table.Td>
<Table.Td>{item.fullUrl}</Table.Td>
<Table.Td>
<Button
leftSection={<FiTrash size={18} />}
color="red"
onClick={async () => {
await deleteMut.mutateAsync(item.id);
await refetch();
}}
>
Delete
</Button>
</Table.Td>
</Table.Tr>
);
})
)}
</Table.Tbody>
</Table>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,28 @@ import {
} from "@mantine/core";
import { useQuery } from "@tanstack/react-query";

import { useDisclosure } from "@mantine/hooks";
import { modals } from "@mantine/modals";
import { notifications } from "@mantine/notifications";
import clsx from "clsx";
import { useMemo, useState } from "react";
import { FiCheckCircle, FiShare } from "react-icons/fi";
import httpService from "../../common/httpservice";
import Currency from "../../components/currency";
import DataTableSkeleton from "../../components/skeleton/data-table-skeleton";
import { useApi } from "../../hooks/useApi";
import { UnpaidModel } from "../../models/reports/unpaid";
import { FiCheckCircle, FiShare } from "react-icons/fi";
import { modals } from "@mantine/modals";
import { IoWarning } from "react-icons/io5";
import { notifications } from "@mantine/notifications";
import { useDisclosure } from "@mantine/hooks";

export default function OutstandingPayments() {
export default function UnpaidReport() {
const { get } = useApi();

const [opened, { open: openShareCodeResult, close: closeShareCodeResult }] =
useDisclosure(false);
const [shareCodeUrl, setShareCodeUrl] = useState("");

const { isPending, data, refetch } = useQuery({
queryKey: ["getUnpaidReport"],
queryFn: () => httpService.get<UnpaidModel[]>("api/v1/reports/unpaid"),
queryFn: () => get<UnpaidModel[]>("api/v1/reports/unpaid"),
});

const totalUnpaid = useMemo(() => {
Expand Down Expand Up @@ -96,14 +98,14 @@ export default function OutstandingPayments() {
<Tooltip label="Anyone with this link can access to this report">
<Button
leftSection={<FiShare />}
variant="outline"
color="red"
variant="light"
onClick={shareToEveryOne}
>
Publish
</Button>
</Tooltip>
</div>

<Table striped highlightOnHover withRowBorders={false}>
<Table.Thead>
<Table.Tr>
Expand Down Expand Up @@ -134,7 +136,6 @@ export default function OutstandingPayments() {
<Table.Td>{item.registrationSummary}</Table.Td>
<Table.Td className="flex-end flex justify-end space-x-2 text-right">
<Button
size="xs"
leftSection={<FiCheckCircle size={18} />}
color="green"
onClick={() => markPaid(item)}
Expand Down
21 changes: 14 additions & 7 deletions internal/dto/sharecode.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package dto

type CreateShareUrlDto struct {
Url string `json:"url"`
}
type (
CreateShareUrlDto struct {
Url string `json:"url"`
}

type ValidateShareUrlDto struct {
Url string `json:"url"`
Code string `json:"code"`
}
ValidateShareUrlDto struct {
Url string `json:"url"`
Code string `json:"code"`
}

ShareCodeDto struct {
Id uint `json:"id"`
FullUrl string `json:"fullUrl"`
}
)
Loading

0 comments on commit db21a77

Please sign in to comment.