Skip to content
This repository has been archived by the owner on Aug 23, 2024. It is now read-only.

Commit

Permalink
feat: stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
yehezkieldio committed Feb 15, 2024
1 parent ef99866 commit fbe73e1
Show file tree
Hide file tree
Showing 17 changed files with 414 additions and 58 deletions.
4 changes: 3 additions & 1 deletion apps/app/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"react/jsx-pascal-case": "off"
"react/jsx-pascal-case": "off",
"@typescript-eslint/no-unused-vars": "off",
"typescript-eslint/no-explicit-any": "off"
}
},
{
Expand Down
1 change: 0 additions & 1 deletion apps/app/android/.idea/misc.xml

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

2 changes: 1 addition & 1 deletion apps/app/src/components/operator-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const OperatorTabs: React.FC = () => {
<Icons.dashboard strokeWidth={1} className="pt-2 w-[32px] h-[30px]" />
<IonLabel className="pt-2 pb-2">Dashboard</IonLabel>
</IonTabButton>
<IonTabButton tab="trashbinTab" href="/trash-bin/tabs/trash">
<IonTabButton tab="trashbinTab" href="/trash-bin/tabs/trashbin">
<Icons.trash strokeWidth={1} className="pt-2 w-[32px] h-[30px]" />
<IonLabel className="pt-2 pb-2">Trashbin</IonLabel>
</IonTabButton>
Expand Down
20 changes: 14 additions & 6 deletions apps/app/src/components/trashbin-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { Icons } from "@trashtrack/ui";

import OperatorTrashbinDisplay from "../pages/operator/trash-bin/display";
import OperatorSubTrashbinDisplay from "../pages/operator/trash-bin/subtrashbin/subtrash-bin";
import OperatorReportActionDisplay from "../pages/operator/trash-bin/report/report-action";
import OperatorReportActionDisplay, { ReportsPage } from "../pages/operator/trash-bin/report/reports.page";
import OperatorFeedbackDisplay from "../pages/operator/trash-bin/report/feedback/feedback";
import OperatorTrashDisplay from "../pages/operator/trash-bin/subtrashbin/trash/trash";
import { useTranslation } from "react-i18next";
import { DetailedReportPage } from "../pages/operator/trash-bin/report/detailed-report.page";

const TrashbinTabs: React.FC = () => {
const { t } = useTranslation();
Expand All @@ -16,12 +17,19 @@ const TrashbinTabs: React.FC = () => {
<IonTabs>
<IonRouterOutlet animated={false} mode="ios">
<Route path="/trash-bin/tabs/trashbin" render={() => <OperatorTrashbinDisplay />} exact={true} />
<Route path="/trash-bin/tabs/sub-trashbin" render={() => <OperatorSubTrashbinDisplay />} exact={true} />
<Route
path="/trash-bin/tabs/report-action"
render={() => <OperatorReportActionDisplay />}
path="/trash-bin/tabs/sub-trashbin/:trash_bin_id"
render={() => <OperatorSubTrashbinDisplay />}
exact={true}
/>

<Route path="/trash-bin/tabs/report-action" render={() => <ReportsPage />} exact={true} />
<Route
path="/trash-bin/tabs/report-action/detail/:report_id"
render={() => <DetailedReportPage />}
exact={true}
/>

<Route path="/trash-bin/tabs/feedback" render={() => <OperatorFeedbackDisplay />} exact={true} />
<Route path="/trash-bin/tabs/trash" render={() => <OperatorTrashDisplay />} exact={true} />

Expand All @@ -36,10 +44,10 @@ const TrashbinTabs: React.FC = () => {
<Icons.trash strokeWidth={1} className="pt-2 w-[32px] h-[30px]" />
<IonLabel className="pt-2 pb-2">Trashbin</IonLabel>
</IonTabButton>
<IonTabButton tab="subTrashbinTabs" href="/trash-bin/tabs/sub-trashbin">
{/* <IonTabButton tab="subTrashbinTabs" href="/trash-bin/tabs/sub-trashbin">
<Icons.subTrashbin strokeWidth={1} className="pt-2 w-[32px] h-[30px]" />
<IonLabel className="pt-2 pb-2">Sub Trashbin</IonLabel>
</IonTabButton>
</IonTabButton> */}
<IonTabButton tab="reportTabs" href="/trash-bin/tabs/report-action">
<Icons.report strokeWidth={1} className="pt-2 w-[32px] h-[30px]" />
<IonLabel className="pt-2 pb-2">{t("tabs.report")}</IonLabel>
Expand Down
103 changes: 88 additions & 15 deletions apps/app/src/pages/operator/trash-bin/display.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,103 @@
import { IonContent, IonPage } from "@ionic/react";
import { Card, CardContent, Button } from "@trashtrack/ui";
import { Card, CardHeader, CardContent, CardTitle, Input, Label, Separator, Skeleton } from "@trashtrack/ui";
import { useHistory } from "react-router-dom";
import { useState } from "react";
import Fuse from "fuse.js";

import { useTranslation } from "react-i18next";
import { useTrashBinQuery } from "../../../queries/get-trash-bin-query";

export interface SubTrashBin {
id: number;
trashBinId: number;
name: string;
maxCapacity: number;
currentCapacity: number;
}

interface TrashBin {
id: number;
name: string;
latitude: number;
longitude: number;
description: string;
openCount: number;
}

export function OperatorTrashbinDisplay() {
const { data, isLoading } = useTrashBinQuery();
const history = useHistory();
const [searchTerm, setSearchTerm] = useState("");
const { t } = useTranslation();

const fuseOptions = {
keys: ["name"],
threshold: 0.4,
};

const fuse = new Fuse(!isLoading ? (data.data as TrashBin[]) : [], fuseOptions);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const filteredData: any[] =
!isLoading && searchTerm === "" ? data.data : fuse.search(searchTerm).map((result) => result.item);

return (
<IonPage>
<IonContent className="operator-trashbin-display ion-padding" fullscreen>
<IonContent className="complain-form-tempat-sampah ion-padding" fullscreen>
<div className="pt-12">
<h1 className="font-bold text-left text-xl">TrashTrack</h1>
<p className="text-xs text-left text-slate-600">Trashbin Management</p>
<p className="text-xs text-left text-slate-600">Trashbin</p>
</div>
<div className="flex flex-col pt-8 gap-4">
<Card className="flex flex-col mt-8">
<CardContent className="pt-6">
<p className="text-center text-xs">Trashbin</p>
</CardContent>
</Card>
<Card className="flex flex-col mt-8">
<CardContent className="pt-6">
<Button className="font-bold text-xs w-full" onClick={() => history.replace("/tabs/home")}>
Kembali
</Button>
</CardContent>
</Card>
<div className="flex flex-col">
<Label className="mb-2" htmlFor="search">
{t("complain.form.tempat-sampah.search")}
</Label>
<Input
id="search"
type="text"
placeholder={t("complain.form.tempat-sampah.search-input")}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
<Separator className="my-4" />
{isLoading ? (
<Card className="flex flex-col">
<CardHeader>
<Skeleton className="h-4 w-20" />
</CardHeader>
<CardContent>
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-40" />
</CardContent>
</Card>
) : filteredData.length === 0 && searchTerm !== "" ? (
<Card className="flex flex-col">
<CardHeader className="text-left">
<CardTitle className="text-lg">{t("complain.form.tempat-sampah.no-results")}</CardTitle>
</CardHeader>
</Card>
) : (
filteredData.map((trashBin: TrashBin) => (
<Card
className="flex flex-col"
key={trashBin.id}
onClick={() => history.push(`/trash-bin/tabs/sub-trashbin/${trashBin.id}`)}
>
<CardHeader className="text-left">
<CardTitle className="text-lg">{trashBin.name}</CardTitle>
</CardHeader>
<CardContent className="pt-2">
<p className="text-sm">
Latitude: {trashBin.latitude} | Longitude: {trashBin.longitude} <br />
{trashBin.description}
</p>
</CardContent>
</Card>
))
)}
</div>
</IonContent>
</IonPage>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { IonContent, IonPage } from "@ionic/react";
import { useGetReportById } from "./get-report.query";
import { useHistory, useParams } from "react-router-dom";
import { Button, Card, CardContent, CardHeader, Skeleton } from "@trashtrack/ui";
import { InterfaceReport } from "./reports.page";
import { useEffect, useState } from "react";

export function DetailedReportPage() {
const history = useHistory();
const { report_id } = useParams<{ report_id: string }>();
const { data: reportData, isError, error, isLoading } = useGetReportById(Number(report_id));
const [imageUrl, setImageUrl] = useState<string>("");

useEffect(() => {
if (!isLoading && reportData) {
const uint8Array = new Uint8Array(reportData.data.imageData);
const blob = new Blob([uint8Array], { type: "image/jpeg" });
setImageUrl(URL.createObjectURL(blob));
}
}, [isLoading, reportData]);

return (
<IonPage>
<IonContent className="ion-padding" fullscreen>
<div className="pt-12">
<h1 className="font-bold text-left text-xl">TrashTrack</h1>
<p className="text-xs text-left text-slate-600">Detailed Report for TrashBin ID: {report_id}</p>
</div>
<div className="flex flex-col pt-8 gap-2">
{isError && (
<Card className="flex flex-col mt-4">
<CardContent className="pt-4">
<p className="text-center text-xs">{JSON.stringify(error)}</p>
</CardContent>
</Card>
)}
{isLoading ? (
<Card className="flex flex-col mt-4">
<CardContent className="pt-4">
<CardHeader>
<Skeleton className="h-4 w-20" />
</CardHeader>
<CardContent className="flex flex-col gap-2">
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-40" />
<Skeleton className="h-4 w-40" />
</CardContent>
</CardContent>
</Card>
) : (
<Card className="flex flex-col mt-4">
<CardContent className="pt-4">
<div className="flex flex-col gap-2">
<p className="text-xs text-left">{reportData.data.name}</p>
<img
src={imageUrl ? imageUrl : "https://via.placeholder.com/150"}
className="w-full h-object-cover"
alt=""
/>
</div>
</CardContent>
</Card>
)}
<Card className="flex flex-col mt-4">
<CardContent className="pt-4">
<Button variant="secondary" onClick={() => history.goBack()}>
Back
</Button>
</CardContent>
</Card>
</div>
</IonContent>
</IonPage>
);
}
14 changes: 14 additions & 0 deletions apps/app/src/pages/operator/trash-bin/report/get-report.query.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useQuery } from "@tanstack/react-query";
import { API_URL } from "@trashtrack/utils";
import { CapacitorHttp } from "@capacitor/core";

export const useGetReportById = (reportId: number) => {
return useQuery({
queryKey: ["getReportById", reportId],
queryFn: () =>
CapacitorHttp.request({
url: API_URL + `/report/id/${reportId}`,
method: "GET",
}).then((res) => res.data),
});
};
14 changes: 14 additions & 0 deletions apps/app/src/pages/operator/trash-bin/report/get-reports.query.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { useQuery } from "@tanstack/react-query";
import { API_URL } from "@trashtrack/utils";
import { CapacitorHttp } from "@capacitor/core";

export const useGetReports = () => {
return useQuery({
queryKey: ["getReports"],
queryFn: () =>
CapacitorHttp.request({
url: API_URL + `/report`,
method: "GET",
}).then((res) => res.data),
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useQuery } from "@tanstack/react-query";
import { API_URL } from "@trashtrack/utils";
import { CapacitorHttp } from "@capacitor/core";

export const useGetTrashBinById = (trashBinId: number, userId: number) => {
return useQuery({
queryKey: ["getTrashBinById", trashBinId, userId],
queryFn: () =>
CapacitorHttp.request({
url: API_URL + `/trash-bin/id/${trashBinId}`,
method: "GET",
}).then((res) => res.data),
enabled: !!userId,
});
};
24 changes: 0 additions & 24 deletions apps/app/src/pages/operator/trash-bin/report/report-action.tsx

This file was deleted.

Loading

0 comments on commit fbe73e1

Please sign in to comment.