add delete device

This commit is contained in:
2026-01-26 11:50:42 +07:00
parent 876c4f9d49
commit 2afe4a2e88
4 changed files with 92 additions and 41 deletions

View File

@@ -41,6 +41,7 @@ export default function AddDeviceFeature() {
const deviceToSave: DeviceData = { const deviceToSave: DeviceData = {
...form, ...form,
id: new Date().getTime().toString(),
towerNumber: merchant.tower, towerNumber: merchant.tower,
floorName: merchant.floor, floorName: merchant.floor,
unitNumber: merchant.unit, unitNumber: merchant.unit,

View File

@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useQueries } from "@tanstack/react-query"; import { useQueries } from "@tanstack/react-query";
import { getDeviceStatus } from "../../../repositories/device"; import { getDeviceStatus } from "../../../repositories/device";
import { getDevices, getMerchant } from "../../../utils/storage"; import { getDevices, getMerchant } from "../../../utils/storage";
@@ -22,6 +23,7 @@ export function useDevices() {
"S", "S",
], ],
queryFn: async () => { queryFn: async () => {
try {
const params = { const params = {
merchantName: merchant?.merchantName, merchantName: merchant?.merchantName,
towerNumber: device.towerNumber, towerNumber: device.towerNumber,
@@ -32,23 +34,35 @@ export function useDevices() {
deviceType: device.deviceType, deviceType: device.deviceType,
commandType: "S", commandType: "S",
}; };
const data = await getDeviceStatus(params);
const res = await getDeviceStatus(params);
const payload = res?.data?.payload ?? "";
return { return {
...device, ...device,
code: data.data.code, id: device.id,
deviceName: device.deviceName, data: res.data,
payload: data.data.payload, code: res.data?.code,
status: payload,
data.data.payload?.toLowerCase().includes("on") || status: payload.toLowerCase().includes("on") ||
data.data.payload?.toLowerCase().includes("lock") || payload.toLowerCase().includes("lock") ||
data.data.payload?.toLowerCase().includes("open") payload.toLowerCase().includes("open"),
? true
: false,
} as unknown as Device; } as unknown as Device;
} catch (error) {
// 👇 fallback ke data local
return {
...device,
id: device.id,
data: null,
payload: 'Not Found',
status: false,
} as unknown as Device;
}
}, },
retry: false, // optional: biar ga retry berkali-kali
})), })),
}); });
const devices = queries const devices = queries
.map((q, index) => ({ .map((q, index) => ({
@@ -57,9 +71,7 @@ export function useDevices() {
isError: q.isError, isError: q.isError,
refetch: q.refetch, // 👈 per device refetch: q.refetch, // 👈 per device
key: datas[index].code, key: datas[index].code,
})) }));
.filter((d) => !d?.isError);
console.log(devices);
return { return {
data: devices as unknown as DeviceData[], data: devices as unknown as DeviceData[],

View File

@@ -6,6 +6,7 @@ import {
Lightbulb, Lightbulb,
Minus, Minus,
Plus, Plus,
Trash,
Wind, Wind,
WindArrowDown, WindArrowDown,
} from "lucide-react"; } from "lucide-react";
@@ -13,8 +14,9 @@ import { Switch } from "../../../components/ui/switch";
import { useNavigate } from "@tanstack/react-router"; import { useNavigate } from "@tanstack/react-router";
import Card from "../../../components/ui/card"; import Card from "../../../components/ui/card";
import { useDevices } from "../hooks/queries"; import { useDevices } from "../hooks/queries";
import { getMerchant } from "../../../utils/storage"; import { getDevices, getMerchant, saveDevices } from "../../../utils/storage";
import { useDeviceCommand } from "../hooks/mutations"; import { useDeviceCommand } from "../hooks/mutations";
import { useEffect, useState } from "react";
export default function Devices() { export default function Devices() {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -24,6 +26,8 @@ export default function Devices() {
const { data, isLoading } = useDevices(); const { data, isLoading } = useDevices();
const { isPending, mutate } = useDeviceCommand(); const { isPending, mutate } = useDeviceCommand();
const [error, setError] = useState("");
const onSubmit = (payload: DeviceData, action = "") => { const onSubmit = (payload: DeviceData, action = "") => {
mutate( mutate(
{ {
@@ -38,16 +42,36 @@ export default function Devices() {
unitNumber: payload.unitNumber, unitNumber: payload.unitNumber,
}, },
{ {
onSuccess: () => { onSuccess: (res) => {
if (res.status === "success") {
payload?.refetch?.(); payload?.refetch?.();
} else {
setError(res.message);
}
}, },
onError: () => { onError: (err) => {
payload?.refetch?.(); setError(err.message);
}, },
}, },
); );
}; };
const onDelete = (payload: DeviceData) => {
const devices = getDevices();
const datas = devices?.filter((item) => item.id != payload?.id);
saveDevices(datas);
payload?.refetch?.();
};
useEffect(() => {
if (error) {
setTimeout(() => {
setError("");
}, 3000);
}
}, [error]);
const icons = { const icons = {
L: { icon: <Lightbulb size={24} />, label: "Lampu" }, L: { icon: <Lightbulb size={24} />, label: "Lampu" },
BL: { icon: <Blinds size={24} />, label: "Blind" }, BL: { icon: <Blinds size={24} />, label: "Blind" },
@@ -61,13 +85,19 @@ export default function Devices() {
return ( return (
<> <>
<div className="py-4 px-6"> <div
{ merchant && ( className={`fixed top-4 left-4 right-4 text-center bg-red-500 py-2 px-4 rounded-lg text-white transition-all ease-in duration-300 ${error ? "opacity-100" : "opacity-0"}`}
>
{error}
</div>
<div className="py-4 px-6">
{merchant && (
<h1 className="text-base text-neutral-900 font-bold mb-4"> <h1 className="text-base text-neutral-900 font-bold mb-4">
Devices Located at{' '}{merchant?.tower}/{merchant?.floor}/{merchant?.unit} Devices Located at {merchant?.tower}/{merchant?.floor}/
{merchant?.unit}
</h1> </h1>
) } )}
<div className="flex items-center gap-3 flex-wrap justify-end"> <div className="flex items-center gap-3 flex-wrap justify-end">
<button <button
onClick={() => onClick={() =>
@@ -120,7 +150,7 @@ export default function Devices() {
data?.map((item, index) => ( data?.map((item, index) => (
<Card <Card
key={index} key={index}
className={`${ className={` relative ${
item.deviceName === "AC" && "row-span-2 col-span-1" item.deviceName === "AC" && "row-span-2 col-span-1"
} ${item.status && "bg-orange-100 border-orange-500"}`} } ${item.status && "bg-orange-100 border-orange-500"}`}
> >
@@ -190,6 +220,13 @@ export default function Devices() {
</div> </div>
</> </>
)} )}
<div className="flex justify-end h-8" />
<span
className="cursor-pointer text-red-500 absolute right-2 bottom-2"
onClick={() => onDelete(item)}
>
<Trash />
</span>
</Card> </Card>
))} ))}

View File

@@ -5,6 +5,7 @@ type Device = {
}; };
type DeviceData = { type DeviceData = {
id?: string,
floorName?: string; floorName?: string;
unitNumber?: string; unitNumber?: string;
deviceName?: string; deviceName?: string;