Next.js mit App -Router für export zu statische dateien
This commit is contained in:
136
app/access/page.jsx
Normal file
136
app/access/page.jsx
Normal file
@@ -0,0 +1,136 @@
|
||||
// pages/Zutrittskontrolle.jsx
|
||||
import React from "react";
|
||||
import Layout from "../components/Layout";
|
||||
|
||||
function Access() {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="bg-gray-100 min-h-screen p-8">
|
||||
<div className="bg-white rounded-lg shadow p-6 mb-8">
|
||||
<h2 className="text-xl font-bold text-blue-500 mb-4">
|
||||
Zutrittskontrolle 1
|
||||
</h2>
|
||||
<div className="flex justify-between">
|
||||
<div className="w-full lg:w-1/2 p-4">
|
||||
<table className="min-w-full text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="py-3 px-4">
|
||||
<b>Betrieb</b>
|
||||
</td>
|
||||
<td className="py-3 px-4">Status: ...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">
|
||||
<b>Status</b>
|
||||
</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">Letzte Chip-ID</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">Zeitstempel</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">Access Typ</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="w-full lg:w-1/2 p-4">
|
||||
<table className="min-w-full text-sm">
|
||||
<thead className="bg-gray-200">
|
||||
<tr>
|
||||
<th className="py-3 px-4 text-center">Eingang</th>
|
||||
<th className="py-3 px-4 text-center">Zustand</th>
|
||||
<th className="py-3 px-4">Bezeichnung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="py-3 px-4 text-center">1</td>
|
||||
<td className="py-3 px-4 text-center">...</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4 text-center">2</td>
|
||||
<td className="py-3 px-4 text-center">...</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Zutrittskontrolle 2 */}
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<h2 className="text-xl font-bold text-blue-500 mb-4">
|
||||
Zutrittskontrolle 2
|
||||
</h2>
|
||||
<div className="flex justify-between">
|
||||
<div className="w-full lg:w-1/2 p-4">
|
||||
<table className="min-w-full text-sm">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="py-3 px-4">
|
||||
<b>Betrieb</b>
|
||||
</td>
|
||||
<td className="py-3 px-4">Status: ...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">
|
||||
<b>Status</b>
|
||||
</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">Letzte Chip-ID</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">Zeitstempel</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4">Access Typ</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className="w-full lg:w-1/2 p-4">
|
||||
<table className="min-w-full text-sm">
|
||||
<thead className="bg-gray-200">
|
||||
<tr>
|
||||
<th className="py-3 px-4 text-center">Eingang</th>
|
||||
<th className="py-3 px-4 text-center">Zustand</th>
|
||||
<th className="py-3 px-4">Bezeichnung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="py-3 px-4 text-center">1</td>
|
||||
<td className="py-3 px-4 text-center">...</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="py-3 px-4 text-center">2</td>
|
||||
<td className="py-3 px-4 text-center">...</td>
|
||||
<td className="py-3 px-4">...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Access;
|
||||
224
app/analogeEingaenge/page.jsx
Normal file
224
app/analogeEingaenge/page.jsx
Normal file
@@ -0,0 +1,224 @@
|
||||
import React, { useState } from "react";
|
||||
import Layout from "../components/Layout";
|
||||
|
||||
function AnalogeEingaenge() {
|
||||
const [activeConfig, setActiveConfig] = useState(null);
|
||||
|
||||
// Beispiel-Daten, du kannst die Daten dynamisch laden
|
||||
const inputs = [
|
||||
{
|
||||
id: 1,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
value: 0,
|
||||
name: "------------------",
|
||||
uG: true,
|
||||
uW: true,
|
||||
oW: true,
|
||||
oG: true,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="bg-gray-100 min-h-screen p-8">
|
||||
<h1 className="text-2xl font-bold mb-4">Analoge Eingänge</h1>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{inputs.map((input) => (
|
||||
<div key={input.id} className="bg-white rounded-lg shadow-lg p-6">
|
||||
<div className="flex justify-between items-center bg-blue-500 text-white rounded-t-lg p-4">
|
||||
<h2 className="text-lg">XIO-PM {input.id}</h2>
|
||||
<button
|
||||
className="bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded"
|
||||
onClick={() => setActiveConfig(input.id)}
|
||||
>
|
||||
Online
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<table className="min-w-full bg-white border border-gray-300">
|
||||
<thead>
|
||||
<tr className="bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
|
||||
<th className="py-3 px-4 text-center">Eingang</th>
|
||||
<th className="py-3 px-4 text-center">Wert</th>
|
||||
<th className="py-3 px-4 text-left">Bezeichnung</th>
|
||||
<th className="py-3 px-4 text-center">uG</th>
|
||||
<th className="py-3 px-4 text-center">uW</th>
|
||||
<th className="py-3 px-4 text-center">oW</th>
|
||||
<th className="py-3 px-4 text-center">oG</th>
|
||||
<th className="py-3 px-4 text-center">Konfig</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-gray-600 text-sm">
|
||||
<tr className="border-b border-gray-200">
|
||||
<td className="py-3 px-4 text-center">{input.id}</td>
|
||||
<td className="py-3 px-4 text-right">{input.value}</td>
|
||||
<td className="py-3 px-4">{input.name}</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<i
|
||||
className={`bi bi-circle-fill text-${
|
||||
input.uG ? "green" : "gray"
|
||||
}-500`}
|
||||
></i>
|
||||
</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<i
|
||||
className={`bi bi-circle-fill text-${
|
||||
input.uW ? "green" : "gray"
|
||||
}-500`}
|
||||
></i>
|
||||
</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<i
|
||||
className={`bi bi-circle-fill text-${
|
||||
input.oW ? "green" : "gray"
|
||||
}-500`}
|
||||
></i>
|
||||
</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<i
|
||||
className={`bi bi-circle-fill text-${
|
||||
input.oG ? "green" : "gray"
|
||||
}-500`}
|
||||
></i>
|
||||
</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<button
|
||||
className="text-blue-500"
|
||||
onClick={() => setActiveConfig(input.id)}
|
||||
>
|
||||
<i className="bi bi-gear-fill"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Modal für Konfiguration */}
|
||||
{activeConfig && (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div className="bg-white p-8 rounded-lg shadow-lg w-96">
|
||||
<h2 className="text-xl font-bold mb-4">
|
||||
Konfiguration - XIO-PM {activeConfig}
|
||||
</h2>
|
||||
<button
|
||||
className="absolute top-4 right-4 text-gray-500 hover:text-gray-700"
|
||||
onClick={() => setActiveConfig(null)}
|
||||
>
|
||||
<i className="bi bi-x-lg"></i>
|
||||
</button>
|
||||
{/* Konfigurationsformular hier einfügen */}
|
||||
<form>
|
||||
<div className="mb-4">
|
||||
<label
|
||||
className="block text-gray-700 text-sm font-bold mb-2"
|
||||
htmlFor="bezeichnung"
|
||||
>
|
||||
Bezeichnung
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="bezeichnung"
|
||||
name="bezeichnung"
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
placeholder="Bezeichnung eingeben"
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<label
|
||||
className="block text-gray-700 text-sm font-bold mb-2"
|
||||
htmlFor="ug"
|
||||
>
|
||||
Unterer Grenzwert
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id="ug"
|
||||
name="ug"
|
||||
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
|
||||
placeholder="Wert eingeben"
|
||||
/>
|
||||
</div>
|
||||
{/* Weitere Felder hier hinzufügen */}
|
||||
<button
|
||||
type="button"
|
||||
className="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
|
||||
onClick={() => setActiveConfig(null)}
|
||||
>
|
||||
Speichern
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default AnalogeEingaenge;
|
||||
24
app/dashboard/page.jsx
Normal file
24
app/dashboard/page.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React, { useEffect } from "react";
|
||||
import Layout from "../components/Layout";
|
||||
import Image from "next/image";
|
||||
import "tailwindcss/tailwind.css"; // Stelle sicher, dass Tailwind CSS korrekt importiert wird
|
||||
import "@fontsource/roboto"; // Standardimport für alle Schriftstärken
|
||||
import "bootstrap-icons/font/bootstrap-icons.css";
|
||||
|
||||
function Dashboard() {
|
||||
return (
|
||||
<Layout>
|
||||
<div className="bg-gray-100 flex flex-col min-h-screen">
|
||||
<div className="flex flex-grow w-full">
|
||||
{/* Main Section */}
|
||||
<main className="flex-1 bg-white p-8 ml-4 shadow rounded-lg overflow-hidden">
|
||||
{/* Hauptinhalt */}
|
||||
<h1 className="text-2xl font-bold mb-4">Dashboard Übersicht</h1>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Dashboard;
|
||||
166
app/einausgaenge/page.jsx
Normal file
166
app/einausgaenge/page.jsx
Normal file
@@ -0,0 +1,166 @@
|
||||
// pages/Einausgaenge.jsx
|
||||
import React, { useState } from "react";
|
||||
import Layout from "../components/Layout";
|
||||
|
||||
function Einausgaenge() {
|
||||
// Beispiel-Daten für Ein- und Ausgänge (kannst du durch deine Daten ersetzen)
|
||||
const inputs = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Eingang 1",
|
||||
status: "Aktiv",
|
||||
description: "Beschreibung 1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Eingang 2",
|
||||
status: "Inaktiv",
|
||||
description: "Beschreibung 2",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Eingang 3",
|
||||
status: "Aktiv",
|
||||
description: "Beschreibung 3",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Eingang 4",
|
||||
status: "Inaktiv",
|
||||
description: "Beschreibung 4",
|
||||
},
|
||||
];
|
||||
|
||||
const outputs = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Ausgang 1",
|
||||
status: "Aktiv",
|
||||
description: "Beschreibung 1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Ausgang 2",
|
||||
status: "Inaktiv",
|
||||
description: "Beschreibung 2",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Ausgang 3",
|
||||
status: "Aktiv",
|
||||
description: "Beschreibung 3",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Ausgang 4",
|
||||
status: "Inaktiv",
|
||||
description: "Beschreibung 4",
|
||||
},
|
||||
];
|
||||
|
||||
// Zustand für aktiven Tab (Ein- oder Ausgänge)
|
||||
const [activeTab, setActiveTab] = useState("inputs");
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="bg-gray-100 min-h-screen p-8">
|
||||
{/* Tabs für Ein- und Ausgänge */}
|
||||
<ul className="flex border-b border-gray-200">
|
||||
<li
|
||||
className={`mr-1 ${
|
||||
activeTab === "inputs" ? "border-blue-500 text-blue-600" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={() => setActiveTab("inputs")}
|
||||
className={`inline-block px-4 py-2 rounded-t-lg ${
|
||||
activeTab === "inputs"
|
||||
? "bg-blue-500 text-white"
|
||||
: "bg-white text-black hover:bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
Eingänge
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
className={`mr-1 ${
|
||||
activeTab === "outputs" ? "border-blue-500 text-blue-600" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={() => setActiveTab("outputs")}
|
||||
className={`inline-block px-4 py-2 rounded-t-lg ${
|
||||
activeTab === "outputs"
|
||||
? "bg-blue-500 text-white"
|
||||
: "bg-white text-black hover:bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
Ausgänge
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{/* Inhalt für die aktiven Tabs */}
|
||||
<div className="mt-4 p-4 bg-white rounded-lg shadow overflow-auto">
|
||||
{activeTab === "inputs" && (
|
||||
<div>
|
||||
<h2 className="text-lg font-bold mb-4">Eingänge</h2>
|
||||
<table className="min-w-full bg-white border border-gray-300">
|
||||
<thead>
|
||||
<tr className="w-full bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
|
||||
<th className="py-3 px-4 text-left">ID</th>
|
||||
<th className="py-3 px-4 text-left">Name</th>
|
||||
<th className="py-3 px-4 text-left">Status</th>
|
||||
<th className="py-3 px-4 text-left">Beschreibung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-gray-600 text-sm">
|
||||
{inputs.map((input) => (
|
||||
<tr key={input.id} className="border-b border-gray-200">
|
||||
<td className="py-3 px-4 text-left">{input.id}</td>
|
||||
<td className="py-3 px-4 text-left">{input.name}</td>
|
||||
<td className="py-3 px-4 text-left">{input.status}</td>
|
||||
<td className="py-3 px-4 text-left">
|
||||
{input.description}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === "outputs" && (
|
||||
<div>
|
||||
<h2 className="text-lg font-bold mb-4">Ausgänge</h2>
|
||||
<table className="min-w-full bg-white border border-gray-300">
|
||||
<thead>
|
||||
<tr className="w-full bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
|
||||
<th className="py-3 px-4 text-left">ID</th>
|
||||
<th className="py-3 px-4 text-left">Name</th>
|
||||
<th className="py-3 px-4 text-left">Status</th>
|
||||
<th className="py-3 px-4 text-left">Beschreibung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-gray-600 text-sm">
|
||||
{outputs.map((output) => (
|
||||
<tr key={output.id} className="border-b border-gray-200">
|
||||
<td className="py-3 px-4 text-left">{output.id}</td>
|
||||
<td className="py-3 px-4 text-left">{output.name}</td>
|
||||
<td className="py-3 px-4 text-left">{output.status}</td>
|
||||
<td className="py-3 px-4 text-left">
|
||||
{output.description}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Einausgaenge;
|
||||
98
app/kabelueberwachung/page.jsx
Normal file
98
app/kabelueberwachung/page.jsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import React, { useState } from "react";
|
||||
import Layout from "../components/Layout";
|
||||
|
||||
function Kabelueberwachung() {
|
||||
const [activeTab, setActiveTab] = useState(1);
|
||||
|
||||
const racks = [
|
||||
{ id: 1, name: "Rack 1" },
|
||||
{ id: 2, name: "Rack 2" },
|
||||
{ id: 3, name: "Rack 3" },
|
||||
{ id: 4, name: "Rack 4" },
|
||||
];
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="bg-gray-100 flex-1 p-4 overflow-hidden">
|
||||
{" "}
|
||||
{/* overflow-hidden hinzugefügt */}
|
||||
{/* Tabs */}
|
||||
<ul className="flex border-b border-gray-200">
|
||||
{racks.map((rack) => (
|
||||
<li
|
||||
key={rack.id}
|
||||
className={`mr-1 ${
|
||||
activeTab === rack.id ? "border-blue-500 text-blue-600" : ""
|
||||
}`}
|
||||
>
|
||||
<button
|
||||
onClick={() => setActiveTab(rack.id)}
|
||||
className={`inline-block px-4 py-2 rounded-t-lg ${
|
||||
activeTab === rack.id
|
||||
? "bg-blue-500 text-white"
|
||||
: "bg-white text-black hover:bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
{rack.name}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{/* Rack-Inhalte */}
|
||||
<div className="mt-4 p-4 bg-white rounded-lg shadow overflow-auto max-h-full">
|
||||
{" "}
|
||||
{/* max-h-full und overflow-auto für Inhalt */}
|
||||
{racks.map(
|
||||
(rack) =>
|
||||
activeTab === rack.id && (
|
||||
<div key={rack.id}>
|
||||
<h2 className="text-lg font-bold mb-4">
|
||||
{rack.name} Inhalte
|
||||
</h2>
|
||||
{/* Hier kannst du den Inhalt für jedes Rack einfügen */}
|
||||
<table className="min-w-full bg-white border border-gray-300">
|
||||
<thead>
|
||||
<tr className="w-full bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
|
||||
<th className="py-3 px-4 text-left">Slot</th>
|
||||
<th className="py-3 px-4 text-left">Bezeichnung</th>
|
||||
<th className="py-3 px-4 text-center">
|
||||
Isolationsgrenzwert
|
||||
</th>
|
||||
<th className="py-3 px-4 text-center">
|
||||
Schleifengrenzwert
|
||||
</th>
|
||||
<th className="py-3 px-4 text-center">Filterzeit</th>
|
||||
<th className="py-3 px-4 text-center">Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-gray-600 text-sm">
|
||||
{Array.from({ length: 8 }, (_, index) => (
|
||||
<tr key={index} className="border-b border-gray-200">
|
||||
<td className="py-3 px-4 text-left">
|
||||
Slot {index + 1}
|
||||
</td>
|
||||
<td className="py-3 px-4 text-left">
|
||||
Beispielbezeichnung
|
||||
</td>
|
||||
<td className="py-3 px-4 text-center">0.5 MOhm</td>
|
||||
<td className="py-3 px-4 text-center">10 kOhm</td>
|
||||
<td className="py-3 px-4 text-center">5 sek.</td>
|
||||
<td className="py-3 px-4 text-center">
|
||||
<button className="bg-blue-500 text-white px-3 py-1 rounded">
|
||||
Bearbeiten
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Kabelueberwachung;
|
||||
@@ -1,30 +1,21 @@
|
||||
import localFont from "next/font/local";
|
||||
import "./globals.css";
|
||||
// src/components/Layout.jsx
|
||||
import React from "react";
|
||||
import Header from "../components/Header"; // Passe den Pfad an, falls nötig
|
||||
import Navigation from "../components/Navigation"; // Passe den Pfad an, falls nötig
|
||||
import Footer from "../components/Footer"; // Passe den Pfad an, falls nötig
|
||||
|
||||
const geistSans = localFont({
|
||||
src: "./fonts/GeistVF.woff",
|
||||
variable: "--font-geist-sans",
|
||||
weight: "100 900",
|
||||
});
|
||||
const geistMono = localFont({
|
||||
src: "./fonts/GeistMonoVF.woff",
|
||||
variable: "--font-geist-mono",
|
||||
weight: "100 900",
|
||||
});
|
||||
|
||||
export const metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
function Layout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body
|
||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||
>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
<div className="bg-gray-100 flex flex-col min-h-screen">
|
||||
<Header className="bg-gray-300 p-4 flex-shrink-0" />
|
||||
<div className="flex flex-grow w-full">
|
||||
<Navigation />
|
||||
{/* Der eigentliche Seiteninhalt */}
|
||||
<main className="flex-1 p-8">{children}</main>
|
||||
</div>
|
||||
<Footer className="bg-gray-300 p-4 flex-shrink-0" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Layout;
|
||||
|
||||
138
app/meldungen/page.jsx
Normal file
138
app/meldungen/page.jsx
Normal file
@@ -0,0 +1,138 @@
|
||||
// pages/Meldungen.jsx
|
||||
import React, { useState } from "react";
|
||||
import Layout from "../components/Layout";
|
||||
|
||||
function Meldungen() {
|
||||
const [rowsPerPage, setRowsPerPage] = useState(25);
|
||||
const [filter, setFilter] = useState("");
|
||||
const [selectedMonth, setSelectedMonth] = useState("01");
|
||||
const [selectedYear, setSelectedYear] = useState("23");
|
||||
const [selectedDay, setSelectedDay] = useState("");
|
||||
|
||||
// Platzhalter für Meldungen
|
||||
const messages = Array.from({ length: 50 }, (_, i) => ({
|
||||
date: `2023-01-${String(i + 1).padStart(2, "0")}`,
|
||||
message: `Meldung ${i + 1}`,
|
||||
}));
|
||||
|
||||
const filteredMessages = messages.filter((msg) => {
|
||||
const dayMatch = selectedDay
|
||||
? msg.date.split("-")[2] === selectedDay.padStart(2, "0")
|
||||
: true;
|
||||
const monthMatch = msg.date.split("-")[1] === selectedMonth;
|
||||
const yearMatch = msg.date.split("-")[0].substring(2) === selectedYear;
|
||||
const filterMatch = msg.message
|
||||
.toLowerCase()
|
||||
.includes(filter.toLowerCase());
|
||||
return dayMatch && monthMatch && yearMatch && filterMatch;
|
||||
});
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<div className="flex flex-col h-full">
|
||||
{/* Filterleiste */}
|
||||
<div className="flex justify-between items-center bg-blue-500 p-4 text-white rounded-t">
|
||||
<div className="flex items-center space-x-4">
|
||||
<span>Interner Meldungsspeicher</span>
|
||||
<select
|
||||
value={selectedMonth}
|
||||
onChange={(e) => setSelectedMonth(e.target.value)}
|
||||
className="bg-white text-black p-1 rounded"
|
||||
>
|
||||
<option value="01">Januar</option>
|
||||
<option value="02">Februar</option>
|
||||
<option value="03">März</option>
|
||||
<option value="04">April</option>
|
||||
<option value="05">Mai</option>
|
||||
<option value="06">Juni</option>
|
||||
<option value="07">Juli</option>
|
||||
<option value="08">August</option>
|
||||
<option value="09">September</option>
|
||||
<option value="10">Oktober</option>
|
||||
<option value="11">November</option>
|
||||
<option value="12">Dezember</option>
|
||||
</select>
|
||||
<select
|
||||
value={selectedYear}
|
||||
onChange={(e) => setSelectedYear(e.target.value)}
|
||||
className="bg-white text-black p-1 rounded"
|
||||
>
|
||||
<option value="22">2022</option>
|
||||
<option value="23">2023</option>
|
||||
<option value="24">2024</option>
|
||||
<option value="25">2025</option>
|
||||
<option value="26">2026</option>
|
||||
</select>
|
||||
<input
|
||||
type="number"
|
||||
value={selectedDay}
|
||||
onChange={(e) => setSelectedDay(e.target.value)}
|
||||
min="1"
|
||||
max="31"
|
||||
placeholder="Tag"
|
||||
className="bg-white text-black p-1 rounded"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<input
|
||||
type="text"
|
||||
value={filter}
|
||||
onChange={(e) => setFilter(e.target.value)}
|
||||
placeholder="Filter"
|
||||
className="bg-white text-black p-1 rounded"
|
||||
/>
|
||||
<select
|
||||
value={rowsPerPage}
|
||||
onChange={(e) => setRowsPerPage(e.target.value)}
|
||||
className="bg-white text-black p-1 rounded"
|
||||
>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Meldungen Tabelle */}
|
||||
<div className="flex-grow overflow-auto mt-4">
|
||||
<table className="min-w-full bg-white border border-gray-300">
|
||||
<thead>
|
||||
<tr className="bg-gray-200 text-gray-600 text-sm leading-normal">
|
||||
<th className="py-3 px-4 text-left">Datum</th>
|
||||
<th className="py-3 px-4 text-left">Meldung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="text-gray-600 text-sm">
|
||||
{filteredMessages.slice(0, rowsPerPage).map((msg, index) => (
|
||||
<tr key={index} className="border-b border-gray-200">
|
||||
<td className="py-3 px-4">{msg.date}</td>
|
||||
<td className="py-3 px-4">{msg.message}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* Pagination */}
|
||||
<div className="flex justify-center mt-4">
|
||||
<ul className="flex space-x-2">
|
||||
{Array.from(
|
||||
{ length: Math.ceil(filteredMessages.length / rowsPerPage) },
|
||||
(_, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="cursor-pointer bg-blue-500 text-white p-2 rounded"
|
||||
>
|
||||
{i + 1}
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
|
||||
export default Meldungen;
|
||||
21
components/Footer.jsx
Normal file
21
components/Footer.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
// src/components/Footer.jsx
|
||||
import React from 'react';
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<footer className="bg-gray-300 p-4 flex-shrink-0">
|
||||
<div className="container mx-auto flex justify-between">
|
||||
<div>
|
||||
<p className="text-sm">Littwin Systemtechnik GmbH & Co. KG</p>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<p className="text-sm">Telefon: 04402 972577-0</p>
|
||||
<p className="text-sm">E-Mail: kontakt@littwin-systemtechnik.de</p>
|
||||
<p className="text-sm">Handbücher</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
63
components/Header.jsx
Normal file
63
components/Header.jsx
Normal file
@@ -0,0 +1,63 @@
|
||||
// src/components/Header.jsx
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
function Header() {
|
||||
return (
|
||||
<header className="bg-gray-300 flex justify-between items-center w-full h-28 p-4">
|
||||
<div className="relative w-1/4 h-full">
|
||||
<Image
|
||||
src="/images/Logo.png"
|
||||
alt="Logo"
|
||||
fill
|
||||
style={{ objectFit: "contain" }}
|
||||
className="absolute -bottom-8 transform translate-y-1/2"
|
||||
priority={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* CPL Status und Stationsname */}
|
||||
<div className="flex items-center space-x-4 w-full justify-center">
|
||||
<div className="flex flex-col text-left">
|
||||
<h2 className="text-sm font-semibold">Stationsname</h2>
|
||||
<p className="font-bold text-lg">CPLV4Rastede</p>
|
||||
</div>
|
||||
<div className="flex flex-col text-left">
|
||||
<p className="text-sm font-medium">CPL Status</p>
|
||||
<span className="text-green-500 font-bold">normiert</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Temperatur und Icons */}
|
||||
<div className="flex items-center space-x-4 w-1/4 justify-end">
|
||||
{/* Temperatur und Luftfeuchtigkeit */}
|
||||
<div className="hidden sm:flex items-center space-x-4">
|
||||
<div className="flex items-center">
|
||||
<i className="bi bi-thermometer-half"></i>
|
||||
<p className="text-lg ml-1">20.5 °C</p>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<i className="bi bi-droplet"></i>
|
||||
<p className="text-lg ml-1">60%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Toggle Switch light and dark mode */}
|
||||
<div className="hidden sm:flex items-center space-x-4">
|
||||
<i className="bi bi-moon"></i>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="bi bi-toggle-off"></i>
|
||||
<i className="bi bi-brightness-high"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* User Icon */}
|
||||
<div className="flex items-center">
|
||||
<i className="bi bi-person-circle text-3xl text-black"></i>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
export default Header;
|
||||
21
components/Layout.jsx
Normal file
21
components/Layout.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
// src/components/Layout.jsx
|
||||
import React from "react";
|
||||
import Header from "./Header"; // Passe den Pfad an, falls nötig
|
||||
import Navigation from "./Navigation"; // Passe den Pfad an, falls nötig
|
||||
import Footer from "./Footer"; // Passe den Pfad an, falls nötig
|
||||
|
||||
function Layout({ children }) {
|
||||
return (
|
||||
<div className="bg-gray-100 flex flex-col min-h-screen">
|
||||
<Header className="bg-gray-300 p-4 flex-shrink-0" />
|
||||
<div className="flex flex-grow w-full">
|
||||
<Navigation />
|
||||
{/* Der eigentliche Seiteninhalt */}
|
||||
<main className="flex-1 p-8">{children}</main>
|
||||
</div>
|
||||
<Footer className="bg-gray-300 p-4 flex-shrink-0" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Layout;
|
||||
46
components/Navigation.jsx
Normal file
46
components/Navigation.jsx
Normal file
@@ -0,0 +1,46 @@
|
||||
// src/components/Navigation.jsx
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Link from "next/link"; // Importiere Link von Next.js
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
function Navigation() {
|
||||
const router = useRouter();
|
||||
const [activeLink, setActiveLink] = useState(router.pathname); // Verwende den aktuellen Pfad als initialen Wert
|
||||
|
||||
useEffect(() => {
|
||||
// Wenn sich die Route ändert, wird der activeLink-Zustand aktualisiert
|
||||
setActiveLink(router.pathname);
|
||||
}, [router.pathname]);
|
||||
|
||||
const menuItems = [
|
||||
{ name: "Übersicht", path: "/" },
|
||||
{ name: "Kabelüberwachung", path: "/Kabelueberwachung" },
|
||||
{ name: "Zutrittskontrolle", path: "/Access" }, // Pfad angepasst
|
||||
{ name: "Ein- und Ausgänge", path: "/Einausgaenge" },
|
||||
{ name: "Analoge Eingänge", path: "/AnalogeEingaenge" },
|
||||
{ name: "Meldungen", path: "/Meldungen" },
|
||||
];
|
||||
|
||||
return (
|
||||
<aside className="w-1/6 flex-shrink-0 h-full mt-24">
|
||||
<nav className="space-y-6 p-4">
|
||||
{menuItems.map((item) => (
|
||||
<Link href={item.path} key={item.name} legacyBehavior>
|
||||
<a
|
||||
className={`block px-4 py-2 font-bold whitespace-nowrap transition duration-300 ${
|
||||
activeLink === item.path
|
||||
? "bg-sky-500 text-white rounded-r-full" // Aktivierte Schaltfläche
|
||||
: "text-black hover:bg-gray-200 rounded-r-full" // Nicht aktive Schaltfläche bei Hover
|
||||
}`}
|
||||
onClick={() => setActiveLink(item.path)} // Setzt das aktive Element beim Klick
|
||||
>
|
||||
{item.name}
|
||||
</a>
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
|
||||
export default Navigation;
|
||||
@@ -1,4 +1,10 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {};
|
||||
const nextConfig = {
|
||||
reactStrictMode: true,
|
||||
output: "export", // Stellt den statischen Export sicher
|
||||
images: {
|
||||
unoptimized: true, // Deaktiviert Bildoptimierung für den Export
|
||||
},
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||
BIN
public/images/Logo.png
Normal file
BIN
public/images/Logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
Reference in New Issue
Block a user