From 420989dc9fa9f4845ec6a7d04b525a080ea98a96 Mon Sep 17 00:00:00 2001 From: Ismail Ali Date: Thu, 10 Jul 2025 19:11:38 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20DetailModal=20um=20Min/Max/Durchschnitt?= =?UTF-8?q?=20erg=C3=A4nzt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Chart zeigt jetzt zusätzlich zu Messwert auch Minimal-, Maximal- und Durchschnittswerte an - Datenstruktur an Redux angepasst (i, a, g) - Darstellung entspricht jetzt LoopMeasurementChart --- .env.development | 2 +- .env.production | 2 +- CHANGELOG.md | 10 + components/main/system/DetailModal.tsx | 41 +++- mocks/api/SERVICE/SystemMockData.json | 17 -- mocks/api/SERVICE/digitalOutputsMockData.json | 14 -- .../SERVICE/kabelueberwachungMockData.json | 200 ------------------ mocks/api/SERVICE/last20MessagesMockData.json | 142 ------------- package-lock.json | 4 +- package.json | 2 +- pages/api/cpl/getAnalogInputsHandler.ts | 28 +-- pages/api/cpl/getDigitalOutputsHandler.ts | 30 +-- .../cpl/updateAnalogInputsSettingsHandler.ts | 55 ++--- 13 files changed, 77 insertions(+), 470 deletions(-) delete mode 100644 mocks/api/SERVICE/SystemMockData.json delete mode 100644 mocks/api/SERVICE/digitalOutputsMockData.json delete mode 100644 mocks/api/SERVICE/kabelueberwachungMockData.json delete mode 100644 mocks/api/SERVICE/last20MessagesMockData.json diff --git a/.env.development b/.env.development index 972a9f6..e611154 100644 --- a/.env.development +++ b/.env.development @@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false NEXT_PUBLIC_EXPORT_STATIC=false NEXT_PUBLIC_USE_CGI=false # App-Versionsnummer -NEXT_PUBLIC_APP_VERSION=1.6.581 +NEXT_PUBLIC_APP_VERSION=1.6.583 NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter) diff --git a/.env.production b/.env.production index ed2d240..f0cf527 100644 --- a/.env.production +++ b/.env.production @@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL NEXT_PUBLIC_EXPORT_STATIC=true NEXT_PUBLIC_USE_CGI=true # App-Versionsnummer -NEXT_PUBLIC_APP_VERSION=1.6.581 +NEXT_PUBLIC_APP_VERSION=1.6.583 NEXT_PUBLIC_CPL_MODE=production \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index abb08ff..0994668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [1.6.583] – 2025-07-10 + +- eslintrc.json : "@typescript-eslint/no-unused-vars": "warn" + +--- +## [1.6.582] – 2025-07-10 + +- eslintrc.json : "@typescript-eslint/no-unused-vars": "warn" + +--- ## [1.6.581] – 2025-07-10 - fix: Bei System: Detailansicht: Zeitraum von bis fehlt. Ganzseitenansicht fehlt noch. gelöst mit zoom und pan diff --git a/components/main/system/DetailModal.tsx b/components/main/system/DetailModal.tsx index 722c517..57a0399 100644 --- a/components/main/system/DetailModal.tsx +++ b/components/main/system/DetailModal.tsx @@ -38,14 +38,31 @@ ChartJS.register( const initialChartData = { datasets: [ { - label: "Messdaten", + label: "Minimum", data: [], - borderColor: "rgba(61, 176, 242, 1)", + borderColor: "lightgrey", + backgroundColor: "rgba(211,211,211,0.3)", + borderWidth: 2, + pointRadius: 0, + tension: 0.1, + }, + { + label: "Maximum", + data: [], + borderColor: "lightgrey", + backgroundColor: "rgba(211,211,211,0.3)", + borderWidth: 2, + pointRadius: 0, + tension: 0.1, + }, + { + label: "Durchschnitt", + data: [], + borderColor: "rgba(59,130,246,1)", backgroundColor: "rgba(59,130,246,0.3)", borderWidth: 2, pointRadius: 0, tension: 0.1, - fill: false, }, ], }; @@ -182,10 +199,20 @@ export const DetailModal = ({ useEffect(() => { if (chartRef.current) { const chart = chartRef.current; - chart.data.datasets[0].data = [...reduxData] - .reverse() - .map((p) => ({ x: new Date(p.t), y: p.i })); - chart.update("none"); + const sortedData = [...reduxData].reverse(); + + chart.data.datasets[0].data = sortedData.map((p) => ({ + x: new Date(p.t), + y: p.i, + })); + chart.data.datasets[1].data = sortedData.map((p) => ({ + x: new Date(p.t), + y: p.a, + })); + chart.data.datasets[2].data = sortedData.map((p) => ({ + x: new Date(p.t), + y: p.g, + })); } }, [reduxData]); diff --git a/mocks/api/SERVICE/SystemMockData.json b/mocks/api/SERVICE/SystemMockData.json deleted file mode 100644 index 8a193b1..0000000 --- a/mocks/api/SERVICE/SystemMockData.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "win_appVersion": "0.02", - "win_deviceName": "CPLV4 Ismail Rastede", - "win_mac1": "0 48 86 81 46 143", - "win_ip": "10.10.0.243", - "win_subnet": "255.255.255.0", - "win_gateway": "10.10.0.1", - "win_cplInternalTimestamp": "23.10.24 15:10:28 Uhr", - "win_opcState": "1", - "win_opcSessions": "0", - "win_opcName": "CPL V4 OPC UA Application Deutsche Bahne", - "win_ntp1": "192.53.103.108", - "win_ntp2": "0.0.0.0", - "win_ntp3": "0.0.0.0", - "win_ntpTimezone": "2", - "win_ntpActive": "1" -} diff --git a/mocks/api/SERVICE/digitalOutputsMockData.json b/mocks/api/SERVICE/digitalOutputsMockData.json deleted file mode 100644 index 5bc4b7a..0000000 --- a/mocks/api/SERVICE/digitalOutputsMockData.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "win_da_state": [ - 0, - 0, - 1, - 1 - ], - "win_da_bezeichnung": [ - "DA1", - "Ausgang2", - "Ausgang3", - "Ausgang4" - ] -} \ No newline at end of file diff --git a/mocks/api/SERVICE/kabelueberwachungMockData.json b/mocks/api/SERVICE/kabelueberwachungMockData.json deleted file mode 100644 index 23e67e6..0000000 --- a/mocks/api/SERVICE/kabelueberwachungMockData.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "win_kueOnline": [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 - ], - "win_kuePSTmMinus96V": [ - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_kueCableBreak": [ - 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 1, 1, 1 - ], - "win_kueGroundFault": [ - 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_kueAlarm1": [ - 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, - 1, 0, 0, 0, 0, 0, 0 - ], - "win_kueAlarm2": [ - 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_kueOverflow": [ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_kueIso": [ - 10, 10, 10, 10.5, 10, 10, 10, 10, 10.5, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10.5, 10, 10, 10, 10, 10, 10.5, 10, 200, 200, 200, 200 - ], - "win_kueLimit1": [ - 3, 9.9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 - ], - "win_kueDelay1": [ - 3, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420 - ], - "win_kueResidence": [ - 0, 0.612, 0, 0.645, 0.822, 0.97, 0, 0, 1.452, 0, 0.734, 0.37, 0.566, 0, - 0.738, 0.684, 1.166, 0.595, 0, 1.651, 1.18, 1.387, 1.214, 0, 1.475, 0.615, - 0.494, 1.217, 65, 65, 65, 65 - ], - "win_kueLimit2Low": [ - 3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, - 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, - 0.1, 0.1 - ], - "win_kueLimit2High": [ - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 - ], - "win_kueLoopInterval": [ - 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6 - ], - "win_kueVersion": [ - 420, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, - 419, 419 - ], - "win_kueID": [ - "Test3", - "B23", - "Kabel 3", - "Kabel 4", - "Kabel 5", - "Kabel 6", - "FTZ4562", - "Kabel 8", - "12344", - "Kabel 10", - "Kabel 11", - "Kabel 12", - "Kabel 13", - "Kabel 14", - "Kabel 15", - "H56-77", - "Kabel 17", - "Kabel 18", - "Kabel 19", - "Kabel 20", - "Kabel 21", - "Kabel 22", - "Kabel 23", - "Kabel 24", - "Kabel 25", - "Kabel 26", - "Kabel 27", - "Kabel 28", - "Kabel 29", - "Kabel 30", - "Kabel 31", - "Kabel 32" - ], - "win_kueName": [ - "Linie 2", - "Edewecht 3", - "", - "Linie 4", - "Linie 5", - "", - "", - "Kabel_8", - "Kabel_9", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", - "Kabel 32" - ], - "win_tdrActive": [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 - ], - "win_tdrAtten": [ - 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2 - ], - "win_tdrSpeed": [ - 112, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100 - ], - "win_tdrTrigger": [ - 102, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80 - ], - "win_tdrPulse": [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_tdrAmp": [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_tdrLocation": [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 - ], - "win_tdrLast": [ - "2024-10-17 07:51:54:000", - "2024-09-30 08:38:50:000", - "?", - "?", - "?", - "?", - "?", - "?", - "2024-09-30 08:36:43:000", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?", - "?" - ], - "win_memoryInterval": [ - 5, 0, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0 - ] -} diff --git a/mocks/api/SERVICE/last20MessagesMockData.json b/mocks/api/SERVICE/last20MessagesMockData.json deleted file mode 100644 index af9c477..0000000 --- a/mocks/api/SERVICE/last20MessagesMockData.json +++ /dev/null @@ -1,142 +0,0 @@ -[ - { - "id": 25068, - "code": "02101", - "timestamp": "2025-04-22 04:56:28", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25067, - "code": "02101", - "timestamp": "2025-04-22 04:55:43", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25066, - "code": "02101", - "timestamp": "2025-04-22 04:48:39", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25065, - "code": "02101", - "timestamp": "2025-04-22 04:46:02", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25064, - "code": "02101", - "timestamp": "2025-04-22 04:38:58", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25063, - "code": "02101", - "timestamp": "2025-04-22 04:36:44", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25062, - "code": "02401", - "timestamp": "2025-04-22 04:35:38", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25061, - "code": "02401", - "timestamp": "2025-04-22 04:28:33", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25060, - "code": "02101", - "timestamp": "2025-04-22 02:56:28", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25059, - "code": "02101", - "timestamp": "2025-04-22 02:56:06", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25058, - "code": "02101", - "timestamp": "2025-04-22 02:40:27", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25057, - "code": "02101", - "timestamp": "2025-04-22 02:40:05", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25056, - "code": "02101", - "timestamp": "2025-04-22 02:26:40", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25055, - "code": "02101", - "timestamp": "2025-04-22 02:26:17", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25054, - "code": "02101", - "timestamp": "2025-04-22 02:16:56", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25053, - "code": "02101", - "timestamp": "2025-04-22 02:16:34", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25052, - "code": "02101", - "timestamp": "2025-04-22 02:09:30", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25051, - "code": "02101", - "timestamp": "2025-04-22 02:01:18", - "message": "Isofehler kommend", - "status": 1 - }, - { - "id": 25050, - "code": "02101", - "timestamp": "2025-04-22 01:54:35", - "message": "Isofehler gehend", - "status": 0 - }, - { - "id": 25049, - "code": "02101", - "timestamp": "2025-04-22 01:54:13", - "message": "Isofehler kommend", - "status": 1 - } -] diff --git a/package-lock.json b/package-lock.json index ba138c8..ab952e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cpl-v4", - "version": "1.6.581", + "version": "1.6.583", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cpl-v4", - "version": "1.6.581", + "version": "1.6.583", "dependencies": { "@fontsource/roboto": "^5.1.0", "@headlessui/react": "^2.2.4", diff --git a/package.json b/package.json index 3adeba0..f2d7692 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cpl-v4", - "version": "1.6.581", + "version": "1.6.583", "private": true, "scripts": { "dev": "next dev", diff --git a/pages/api/cpl/getAnalogInputsHandler.ts b/pages/api/cpl/getAnalogInputsHandler.ts index 0caed18..76a364b 100644 --- a/pages/api/cpl/getAnalogInputsHandler.ts +++ b/pages/api/cpl/getAnalogInputsHandler.ts @@ -8,26 +8,14 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) { const mode = process.env.NEXT_PUBLIC_CPL_MODE; try { - /* if (mode === "json") { - const filePath = path.join( - process.cwd(), - "mocks/api/SERVICE/analogInputsMockData.json" - ); - const content = fs.readFileSync(filePath, "utf-8"); - const data = JSON.parse(content); - return res.status(200).json(data); - } */ - - if (mode === "json") { - const filePath = path.join( - process.cwd(), - "mocks/device-cgi-simulator/SERVICE/analogInputsMockData.json" - ); - const jsonContent = fs.readFileSync(filePath, "utf-8"); - const data = JSON.parse(jsonContent); - res.status(200).json(data); - return; - } + const filePath = path.join( + process.cwd(), + "mocks/device-cgi-simulator/SERVICE/analogInputsMockData.json" + ); + const jsonContent = fs.readFileSync(filePath, "utf-8"); + const data = JSON.parse(jsonContent); + res.status(200).json(data); + return; } catch (error) { console.error(error); res.status(500).json({ error: "Internal Server Error" }); diff --git a/pages/api/cpl/getDigitalOutputsHandler.ts b/pages/api/cpl/getDigitalOutputsHandler.ts index 0f980a6..469d025 100644 --- a/pages/api/cpl/getDigitalOutputsHandler.ts +++ b/pages/api/cpl/getDigitalOutputsHandler.ts @@ -3,7 +3,6 @@ import { NextApiRequest, NextApiResponse } from "next"; import path from "path"; import fs from "fs/promises"; -import { readFileSync } from "fs"; export default async function handler( req: NextApiRequest, @@ -11,25 +10,12 @@ export default async function handler( ) { const mode = process.env.NEXT_PUBLIC_CPL_MODE ?? "json"; - if (mode === "json") { - // Lese JSON-Datei z.B. digitalOutputsMockData.json - const filePath = path.join( - process.cwd(), - "mocks/api/SERVICE/digitalOutputsMockData.json" - ); - const content = await fs.readFile(filePath, "utf-8"); - const data = JSON.parse(content); - return res.status(200).json(data); - } - - if (mode === "jsSimulatedProd") { - const digitalOutputsScript = readFileSync( - "mocks/device-cgi-simulator/SERVICE/digitalOutputsMockData.js" - ); - res.setHeader("Content-Type", "application/javascript"); - res.status(200).send(digitalOutputsScript); - return; - } - - return res.status(400).json({ error: "Unsupported mode" }); + // Lese JSON-Datei z.B. digitalOutputsMockData.json + const filePath = path.join( + process.cwd(), + "mocks/device-cgi-simulator/SERVICE/digitalOutputsMockData.json" + ); + const content = await fs.readFile(filePath, "utf-8"); + const data = JSON.parse(content); + return res.status(200).json(data); } diff --git a/pages/api/cpl/updateAnalogInputsSettingsHandler.ts b/pages/api/cpl/updateAnalogInputsSettingsHandler.ts index 7a5493a..1d6586a 100644 --- a/pages/api/cpl/updateAnalogInputsSettingsHandler.ts +++ b/pages/api/cpl/updateAnalogInputsSettingsHandler.ts @@ -15,51 +15,20 @@ export default function handler(req: NextApiRequest, res: NextApiResponse) { return res.status(400).json({ error: "Missing or invalid updates array" }); } - if (mode === "json") { - const filePath = path.join( - process.cwd(), - "mocks/api/SERVICE/analogInputsMockData.json" - ); - const content = fs.readFileSync(filePath, "utf-8"); - const data = JSON.parse(content); + const filePath = path.join( + process.cwd(), + "mocks/device-cgi-simulator/SERVICE/analogInputsMockData.json" + ); + const content = fs.readFileSync(filePath, "utf-8"); + const data = JSON.parse(content); - for (const update of updates) { - const { key, index, value } = update; - if (Array.isArray(data[key]) && index < data[key].length) { - data[key][index] = value; - } + for (const update of updates) { + const { key, index, value } = update; + if (Array.isArray(data[key]) && index < data[key].length) { + data[key][index] = value; } - - fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8"); - return res.status(200).json({ success: true }); } - if (mode === "jsSimulatedProd") { - const filePath = path.join( - process.cwd(), - "mocks/device-cgi-simulator/SERVICE/analogInputsMockData.js" - ); - let content = fs.readFileSync(filePath, "utf-8"); - - for (const update of updates) { - const { key, index, value } = update; - const regex = new RegExp(`var\\s+${key}\\s*=\\s*\\[([\\s\\S]*?)\\];`); - const match = content.match(regex); - if (!match) continue; - - const items = match[1].split(",").map((s) => s.trim()); - if (index >= items.length) continue; - - const isString = typeof value === "string"; - items[index] = isString ? `"${value}"` : `${value}`; - - const updatedLine = `var ${key} = [${items.join(", ")}];`; - content = content.replace(regex, updatedLine); - } - - fs.writeFileSync(filePath, content, "utf-8"); - return res.status(200).json({ success: true }); - } - - return res.status(400).json({ error: "Unsupported mode" }); + fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8"); + return res.status(200).json({ success: true }); }