nidus-sync/ts/rmo/view/ReportSubmitted.vue
Eli Ribble 9dccd21cee
RMO frontend checkpoint
* Create a nwe AddressAndMapLocator which abstracts out the behavior of
   selecting a location
 * Fix the overlay causing render errors on the MapLocator by getting
   rid of the overlay and just using a lock indicator
 * Fix MapLocator zooming in to the wrong place by not framing the
   markers
 * Remove Latlng from platform and just use Location with optional
   accuracy
 * Use nested types with form-encoded POST
 * Fix styles on water report page
2026-04-09 17:21:35 +00:00

326 lines
9.2 KiB
Vue

<style scoped>
.logo {
max-width: 200px;
height: auto;
}
</style>
<template>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<!-- Success Card -->
<div class="card shadow-sm border-success mb-4">
<div class="card-header bg-success text-white">
<h3 class="my-2">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
class="bi bi-check-circle-fill me-2"
viewBox="0 0 16 16"
>
<path
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"
/>
</svg>
Report Successfully Submitted
</h3>
</div>
<div class="card-body p-4">
<div class="text-center mb-4">
<div class="alert alert-info py-3">
<strong>Your Report ID:</strong>
<span class="fs-4 fw-bold">{{ id }}</span>
</div>
</div>
<hr class="my-4" />
<div>
<h4 class="mb-3">
<i class="bi bi-person-rolodex"></i>
Follow-up
</h4>
<p>
Please provide your contact information in case the district has
any follow-up questions.
</p>
<form
id="notificationForm"
@submit.prevent="handleSubmit"
class="needs-validation"
>
<div class="mb-3">
<label class="form-label" for="name">Name</label>
<div class="input-group">
<span class="input-group-text">
<i class="bi bi-person-lines-fill"></i>
</span>
<input
v-model="formData.name"
type="text"
class="form-control"
id="name"
maxlength="100"
placeholder="Adam Smith"
/>
</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email Address</label>
<div class="input-group">
<span class="input-group-text">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-envelope"
viewBox="0 0 16 16"
>
<path
d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4Zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1H2Zm13 2.383-4.708 2.825L15 11.105V5.383Zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741ZM1 11.105l4.708-2.897L1 5.383v5.722Z"
/>
</svg>
</span>
<input
v-model="formData.email"
type="email"
class="form-control"
id="email"
maxlength="200"
placeholder="your@email.com"
/>
</div>
</div>
<div class="mb-3">
<label for="phone" class="form-label">Phone Number</label>
<div class="input-group">
<span class="input-group-text">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-phone"
viewBox="0 0 16 16"
>
<path
d="M11 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h6zM5 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H5z"
/>
<path d="M8 14a1 1 0 1 0 0-2 1 1 0 0 0 0 2z" />
</svg>
</span>
<input
v-model="formData.phone"
type="tel"
class="form-control"
id="phone"
maxlength="100"
placeholder="(123) 456-7890"
/>
</div>
</div>
<div class="form-check mb-3 form-check">
<input
v-model="formData.consent"
class="form-check-input"
id="consent"
type="checkbox"
/>
<label class="form-check-label" for="consent">
I consent to being contacted at my email address or phone
number above just for the purposes of this report.
<i
class="bi bi-info-circle-fill text-primary ms-1"
data-bs-toggle="tooltip"
data-bs-placement="top"
title="We will never sell your information. We'll send you notifications, but only if you ask us to. We'll share your information with the district that is in change of mosquito control in the area you've reported, but not with anybody else."
></i>
</label>
</div>
<div class="form-check mb-3 form-check">
<input
v-model="formData.notification"
class="form-check-input"
id="notification"
type="checkbox"
/>
<label class="form-check-label" for="notification">
I'd like to get updates about my report as it gets handled.
</label>
</div>
<div class="form-check mb-3 form-check">
<input
v-model="formData.subscribe"
class="form-check-input"
id="subscribe"
type="checkbox"
/>
<label class="form-check-label" for="subscribe">
<template v-if="!district">
I'd like to subscribe to periodic updates from my mosquito
control district.
</template>
<template v-else>
I'd like to subscribe to periodic updates from
{{ district.name }}
</template>
</label>
</div>
<button type="submit" class="btn btn-primary">
Update report
</button>
</form>
</div>
<hr class="my-4" />
<!-- Status Check Section -->
<div class="mb-4">
<h4 class="mb-3">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
class="bi bi-search me-2"
viewBox="0 0 16 16"
>
<path
d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"
/>
</svg>
Check Your Report Status
</h4>
<p>
You can check the status of your report at any time using your
Report ID.
</p>
<RouterLink :to="`/status/${id}`" class="btn btn-outline-primary">
Check Status
</RouterLink>
</div>
<div class="row">
<div v-if="district" class="mb-4 text-center">
<p>Your report will be handled by</p>
<p>
<b>{{ district.name }}</b>
</p>
<a :href="district.url_website">
<img
class="logo"
:src="district.url_logo"
:alt="district.name + 'logo'"
/>
</a>
</div>
</div>
</div>
</div>
<!-- Navigation Links -->
<div class="text-center">
<RouterLink to="/nuisance" class="btn btn-outline-success">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-plus-circle me-1"
viewBox="0 0 16 16"
>
<path
d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"
/>
<path
d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"
/>
</svg>
Submit Another Report
</RouterLink>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { computedAsync } from "@vueuse/core";
import { useRouter } from "vue-router";
import { useStoreDistrict } from "@/rmo/store/district";
import { useStorePublicReport } from "@/store/publicreport";
import type { District, PublicReport } from "@/type/api";
interface FormData {
name: string;
email: string;
phone: string;
consent: boolean;
notification: boolean;
subscribe: boolean;
}
interface Props {
id: string;
}
const props = defineProps<Props>();
const formData = ref<FormData>({
name: "",
email: "",
phone: "",
consent: true,
notification: false,
subscribe: false,
});
const router = useRouter();
const storeDistrict = useStoreDistrict();
const storePublicReport = useStorePublicReport();
const report = computedAsync(async (): Promise<PublicReport | undefined> => {
return await storePublicReport.byID(props.id);
});
const district = computedAsync(async (): Promise<District | undefined> => {
if (!(report.value && report.value.district)) {
return undefined;
}
return await storeDistrict.byURI(report.value.district);
});
const handleSubmit = async () => {
try {
const response = await fetch("/api/publicreport-notification", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
report_id: props.id,
...formData.value,
}),
});
if (response.ok) {
// Handle success (e.g., show a success message)
console.log("Form submitted successfully");
} else {
// Handle error
console.error("Form submission failed");
}
} catch (error) {
console.error("Error submitting form:", error);
}
};
onMounted(() => {});
</script>