This commit is contained in:
nocnico
2025-04-24 23:29:55 +02:00
6 changed files with 130 additions and 36 deletions

View File

@@ -29,6 +29,7 @@ export const useMissionsStore = create<MissionStore>((set) => ({
missionPatientInfo: "TestPatientInfo",
missionStationIds: [],
createdUserId: "1",
hpgMissionString: null,
missionLog: [],
missionStationUserIds: [],
hpgLocationLat: 52.520008,
@@ -49,7 +50,7 @@ export const useMissionsStore = create<MissionStore>((set) => ({
},
body: JSON.stringify(mission),
});
if (!res.ok) return undefined;
if (!res.ok) return new Error("Failed to create mission");
const data = await res.json();
set((state) => ({ missions: [...state.missions, data] }));
return data;

View File

@@ -58,6 +58,7 @@ export const ContextMenu = () => {
road: string;
state: string;
city: string;
town: string;
};
display_name: string;
importance: number;
@@ -71,11 +72,12 @@ export const ContextMenu = () => {
place_rank: number;
type: string;
};
console.log(data);
setMissionFormValues({
addressLat: contextMenu.lat,
addressLng: contextMenu.lng,
addressCity: data.address.city,
addressStreet: `${data.address.road}, ${data.address.house_number}`,
addressCity: data.address.city || data.address.town,
addressStreet: `${data.address.road}, ${data.address.house_number || "keine HN"}`,
addressZip: data.address.postcode,
state: "draft",
});

View File

@@ -6,6 +6,7 @@ import { Audio } from "./_components/Audio";
import { useState } from "react";
import { ExitIcon, ExternalLinkIcon } from "@radix-ui/react-icons";
import { Chat } from "./_components/Chat";
import Link from "next/link";
export default function Navbar() {
const [isDark, setIsDark] = useState(false);
@@ -42,9 +43,11 @@ export default function Navbar() {
<button className="btn btn-ghost">
<ExternalLinkIcon className="w-4 h-4" /> HUB
</button>
<button className="btn btn-ghost">
<ExitIcon className="w-4 h-4" />
</button>
<Link href={"/logout"}>
<button className="btn btn-ghost">
<ExitIcon className="w-4 h-4" />
</button>
</Link>
</div>
</div>
</div>

View File

@@ -1,25 +1,49 @@
"use client";
import React, { use, useEffect, useState } from "react";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { BellRing, BookmarkPlus, Trash2 } from "lucide-react";
import { BellRing, BookmarkPlus } from "lucide-react";
import { Select } from "_components/Select";
import { Keyword, Station } from "@repo/db";
import { Keyword, KEYWORD_CATEGORY, missionType, Station } from "@repo/db";
import { getKeywords, getStations } from "dispatch/_components/pannel/action";
import {
MissionOptionalDefaults,
MissionOptionalDefaultsSchema,
} from "@repo/db/zod";
import { usePannelStore } from "_store/pannelStore";
import { useSession } from "next-auth/react";
import { toast } from "react-hot-toast";
import { useMissionsStore } from "_store/missionsStore";
export const MissionForm = () => {
const createMission = useMissionsStore((state) => state.createMission);
const session = useSession();
const defaultFormValues = React.useMemo(
() =>
({
createdUserId: session.data?.user.id,
type: "primär",
addressOSMways: [],
hpgFireEngineState: null,
hpgAmbulanceState: null,
hpgPoliceState: null,
hpgMissionString: null,
missionLog: [],
}) as Partial<MissionOptionalDefaults>,
[session.data?.user.id],
);
const form = useForm<MissionOptionalDefaults>({
resolver: zodResolver(MissionOptionalDefaultsSchema),
defaultValues: {},
defaultValues: defaultFormValues,
});
const { missionFormValues, setMissionFormValues } = usePannelStore(
(state) => state,
);
const { missionFormValues } = usePannelStore((state) => state);
useEffect(() => {
if (session.data?.user.id) {
form.setValue("createdUserId", session.data.user.id);
}
}, [session.data?.user.id, form]);
/* const formValues = form.watch();
useEffect(() => {
@@ -30,9 +54,12 @@ export const MissionForm = () => {
useEffect(() => {
if (missionFormValues) {
form.reset(missionFormValues);
form.reset({
...missionFormValues,
...defaultFormValues,
});
}
}, [missionFormValues, form]);
}, [missionFormValues, form, defaultFormValues]);
const [stations, setStations] = useState<Station[]>([]);
const [keywords, setKeywords] = useState<Keyword[]>([]);
@@ -46,12 +73,10 @@ export const MissionForm = () => {
});
}, []);
const onSubmit = (data: MissionOptionalDefaults) => {
console.log({
...data,
});
};
console.log(
form.watch("missionKeywordName"),
form.watch("missionKeywordAbbreviation"),
);
console.log(form.formState.errors);
return (
@@ -127,6 +152,12 @@ export const MissionForm = () => {
<select
{...form.register("type")}
className="select select-primary select-bordered w-full mb-4"
onChange={(e) => {
form.setValue("type", e.target.value as missionType);
form.setValue("missionKeywordName", null);
form.setValue("missionKeywordAbbreviation", null);
form.setValue("hpgMissionString", null);
}}
>
<option value="primär">PRIMÄR</option>
<option value="sekundär">SEKUNDÄR</option>
@@ -134,31 +165,77 @@ export const MissionForm = () => {
{form.watch("type") === "primär" && (
<>
<select
{...form.register("missionKeyword")}
{...form.register("missionKeywordCategory")}
className="select select-primary select-bordered w-full mb-4"
onChange={(e) =>
form.setValue("missionKeyword", e.target.value as string)
}
onChange={(e) => {
form.setValue(
"missionKeywordCategory",
e.target.value as string,
);
form.setValue("missionKeywordName", null);
form.setValue("missionKeywordAbbreviation", null);
form.setValue("hpgMissionString", null);
}}
defaultValue="default"
>
{keywords.map((keyword) => (
<option key={keyword.id} value={keyword.name}>
{keyword.name}
<option disabled value="default">
Einsatz Kathegorie auswählen...
</option>
{Object.keys(KEYWORD_CATEGORY).map((use) => (
<option key={use} value={use}>
{use}
</option>
))}
</select>
<select
{...form.register("missionKeywordAbbreviation")}
className="select select-primary select-bordered w-full mb-4"
onChange={(e) => {
const keyword = keywords.find(
(k) => k.abreviation === e.target.value,
);
form.setValue("missionKeywordName", keyword?.name || null);
form.setValue(
"missionKeywordAbbreviation",
keyword?.abreviation || null,
);
}}
defaultValue="default"
>
<option disabled value="default">
Einsatzstichwort auswählen...
</option>
{keywords
.filter(
(k) => k.category === form.watch("missionKeywordCategory"),
)
.map((keyword) => (
<option key={keyword.id} value={keyword.abreviation}>
{keyword.name}
</option>
))}
</select>
<select
/* {...form.register("missionKeyword")} */
className="select select-primary select-bordered w-full mb-4"
onChange={(e) =>
form.setValue("missionKeyword", e.target.value as string)
form.setValue("hpgMissionString", e.target.value as string)
}
defaultValue="default"
>
<option defaultChecked disabled value="">
<option disabled value="default">
Einsatz Szenerie auswählen...
</option>
<option value="typ1">typ1</option>
<option value="typ2">typ2</option>
<option value="typ3">typ3</option>
{keywords
.find((k) => k.name === form.watch("missionKeywordName"))
?.hpgMissionTypes?.map((missionString) => {
const [name, code] = missionString.split(":");
return (
<option key={missionString} value={missionString}>
{name}
</option>
);
})}
</select>
</>
)}
@@ -195,9 +272,19 @@ export const MissionForm = () => {
<button
type="submit"
className="btn btn-warning"
onClick={form.handleSubmit(() => {
console.log("Alarmieren");
})}
onClick={form.handleSubmit(
async (mission: MissionOptionalDefaults) => {
try {
const newMission = await createMission(mission);
toast.success(`Einsatz ${newMission.id} erstellt`);
// TODO: Einsatz alarmieren
} catch (error) {
toast.error(
`Fehler beim Erstellen des Einsatzes: ${(error as Error).message}`,
);
}
},
)}
>
<BellRing className="h-4 w-4" /> Alarmieren
</button>