Merge branch 'main' of https://github.com/VAR-Virtual-Air-Rescue/var-monorepo
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Binary file not shown.
@@ -16,6 +16,7 @@ model Mission {
|
||||
missionStationIds String[] @default([])
|
||||
missionStationUserIds String[] @default([])
|
||||
missionLog Json[] @default([])
|
||||
hpgMissionString String?
|
||||
hpgAmbulanceState HpgState?
|
||||
hpgFireEngineState HpgState?
|
||||
hpgPoliceState HpgState?
|
||||
|
||||
Reference in New Issue
Block a user