nidus-sync/ts/rmo/view/Compliance.vue

151 lines
3.5 KiB
Vue

<style scoped>
body {
background-color: #f8f9fa;
min-height: 100vh;
display: flex;
flex-direction: column;
}
body > .container-fluid {
flex: 1;
}
.progress-bar {
background-color: #0d6efd;
transition: width 0.3s ease;
}
</style>
<template>
<template v-if="district">
<router-view v-slot="{ Component }">
<component
:is="Component"
:district="district"
@doEvidence="doEvidence"
@doContact="doContact"
@doLocator="doLocator"
@doPermission="doPermission"
v-model="compliance"
/>
</router-view>
</template>
<template v-else>
<p>loading {{ slug }}...</p>
</template>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { computedAsync } from "@vueuse/core";
import type { Image } from "@/components/ImageUpload.vue";
import { useStoreDistrict } from "@/rmo/store/district";
import { useStoreLocal } from "@/store/local";
import { useStoreLocation } from "@/store/location";
import Intro from "@/rmo/content/compliance/Intro.vue";
import type { District, Location, PublicReport } from "@/type/api";
import { PermissionAccess } from "@/type/api";
import { Locator } from "@/type/map";
import { type Contact } from "@/rmo/content/compliance/Contact.vue";
import { type Permission } from "@/rmo/content/compliance/Permission.vue";
export interface Compliance {
comments: string;
contact: Contact;
location: Location;
locator: Locator;
images: Image[];
permission: Permission;
}
interface Props {
slug: string;
}
const districtStore = useStoreDistrict();
const compliance = ref<Compliance>({
comments: "",
contact: {
name: "",
phone: "",
can_text: true,
email: "",
},
images: [],
location: {
latitude: 0,
longitude: 0,
},
locator: {
address: {
country: "",
gid: "",
locality: "",
number: "",
postal_code: "",
raw: "",
region: "",
street: "",
unit: "",
},
location: {
latitude: 0,
longitude: 0,
},
},
permission: {
access: PermissionAccess.UNSELECTED,
access_instructions: "",
availability_notes: "",
gate_code: "",
has_dog: false,
wants_scheduled: false,
},
});
const props = defineProps<Props>();
const report = ref<PublicReport | null>();
const district = computedAsync(async (): Promise<District | undefined> => {
const districts = await districtStore.list();
return districts.find((district: District) => district.slug == props.slug);
});
const storeLocal = useStoreLocal();
const storeLocation = useStoreLocation();
function doEvidence() {
console.log("evidence", compliance.value);
}
function doContact() {
console.log("contact", compliance.value.contact);
}
function doLocator() {
console.log("locator done", compliance.value.locator);
}
function doPermission() {
console.log("permission", compliance.value.permission);
}
async function createReport(report_id: string, loc?: GeolocationPosition) {
const formData = new FormData();
formData.append;
const resp = await fetch("/api/rmo/compliance", {
method: "POST",
body: formData,
// Don't set Content-Type, the borwser should do it
});
if (!resp.ok) {
const content = await resp.text();
console.error("Failed to create compliance report", resp.status, content);
}
}
onMounted(() => {
const session_id = storeLocal.getSessionID();
storeLocation
.get()
.then((loc: GeolocationPosition) => {
compliance.value.location = loc.coords;
createReport(session_id, loc);
})
.catch((e) => {
console.log("failed to get location", e);
createReport(session_id);
});
});
</script>