Use class heirarchy for different report types.

This commit is contained in:
Eli Ribble 2026-04-10 23:57:47 +00:00
parent 4735734404
commit 60eb6b9bbf
No known key found for this signature in database
13 changed files with 539 additions and 380 deletions

View file

@ -30,20 +30,19 @@
import { computed, ref } from "vue";
import { router } from "@/rmo/router";
import type { District } from "@/type/api";
import type { District, PublicReport } from "@/type/api";
import HeaderCompliance from "@/rmo/components/HeaderCompliance.vue";
import ProgressBarCompliance from "@/rmo/components/ProgressBarCompliance.vue";
import AddressAndMapLocator from "@/rmo/components/AddressAndMapLocator.vue";
import { Compliance } from "@/rmo/view/Compliance.vue";
import { Camera } from "@/type/map";
interface Emits {
(e: "doAddress"): void;
(e: "update:modelValue", value: Compliance): void;
(e: "update:modelValue", value: PublicReport): void;
}
interface Props {
district: District;
modelValue: Compliance;
modelValue: PublicReport;
}
const emit = defineEmits<Emits>();
const error = ref<string>("");

View file

@ -45,7 +45,7 @@
id="contact-name"
name="name"
placeholder="Enter your name"
v-model="modelValue.contact.name"
v-model="modelValue.reporter.name"
/>
</div>
@ -61,7 +61,7 @@
id="contact-phone"
name="phone"
placeholder="(555) 123-4567"
v-model="modelValue.contact.phone"
v-model="modelValue.reporter.phone"
/>
</div>
@ -72,7 +72,7 @@
class="form-check-input"
type="checkbox"
id="can-text"
v-model="modelValue.contact.can_text"
v-model="modelValue.reporter.can_text"
/>
<label class="form-check-label" for="can-text">
You may send text messages to this number
@ -94,7 +94,7 @@
class="form-control"
id="contact-email"
placeholder="your.email@example.com"
v-model="modelValue.contact.email"
v-model="modelValue.reporter.email"
/>
<div class="form-text">
We'll send you a confirmation and any updates about this request
@ -125,10 +125,9 @@
import { ref } from "vue";
import { router } from "@/rmo/router";
import type { District } from "@/type/api";
import type { District, PublicReport } from "@/type/api";
import HeaderCompliance from "@/rmo/components/HeaderCompliance.vue";
import ProgressBarCompliance from "@/rmo/components/ProgressBarCompliance.vue";
import type { Compliance } from "@/rmo/view/Compliance.vue";
export interface Contact {
name: string;
@ -138,11 +137,11 @@ export interface Contact {
}
interface Emits {
(e: "doContact"): void;
(e: "update:modelValue", value: Compliance): void;
(e: "update:modelValue", value: PublicReport): void;
}
interface Props {
district: District;
modelValue: Compliance;
modelValue: PublicReport;
}
const emit = defineEmits<Emits>();
const props = defineProps<Props>();

View file

@ -110,7 +110,7 @@
<!-- Upload Area -->
<div class="mb-4">
<label class="form-label fw-semibold">Photos</label>
<ImageUpload v-model="modelValue.images" />
<ImageUpload v-model="images" />
</div>
<!-- Photo Previews -->
@ -166,25 +166,25 @@
import { ref } from "vue";
import { router } from "@/rmo/router";
import type { District } from "@/type/api";
import type { District, PublicReportCompliance } from "@/type/api";
import HeaderCompliance from "@/rmo/components/HeaderCompliance.vue";
import ImageUpload, { Image } from "@/components/ImageUpload.vue";
import ProgressBarCompliance from "@/rmo/components/ProgressBarCompliance.vue";
import type { Compliance } from "@/rmo/view/Compliance.vue";
interface Emits {
(e: "update:modelValue", value: Compliance): void;
(e: "doEvidence"): void;
(e: "update:modelValue", value: PublicReportCompliance): void;
(e: "doEvidence", images: Image[]): void;
}
interface Props {
district: District;
modelValue: Compliance;
modelValue: PublicReportCompliance;
}
const emit = defineEmits<Emits>();
const images = ref<Image[]>([]);
const props = defineProps<Props>();
function doContinue() {
emit("update:modelValue", props.modelValue);
emit("doEvidence");
emit("doEvidence", images.value);
router.push("./permission");
}
</script>

View file

@ -84,7 +84,7 @@
type="radio"
id="access-allowed"
:value="PermissionAccess.GRANTED"
v-model="modelValue.permission.access"
v-model="modelValue.access"
class="mt-1"
/>
<label for="access-allowed">
@ -99,8 +99,7 @@
<!-- Conditional fields for Option 1 -->
<div
v-if="
modelValue.permission.access &&
modelValue.permission.access == PermissionAccess.GRANTED
modelValue.access && modelValue.access == PermissionAccess.GRANTED
"
class="conditional-section"
>
@ -115,7 +114,7 @@
name="access_instructions"
placeholder="Example: Side gate on left, backyard near shed..."
rows="3"
v-model="modelValue.permission.access_instructions"
v-model="modelValue.access_instructions"
></textarea>
</div>
@ -130,7 +129,7 @@
name="gate_code"
placeholder="Enter code if applicable"
type="text"
v-model="modelValue.permission.gate_code"
v-model="modelValue.gate_code"
/>
</div>
@ -141,7 +140,7 @@
type="checkbox"
name="has_dog"
id="has_dog"
v-model="modelValue.permission.has_dog"
v-model="modelValue.has_dog"
/>
<label class="form-check-label" for="has_dog"
>Dog on Property?</label
@ -149,7 +148,7 @@
</div>
</div>
<div class="dog-warning" v-if="modelValue.permission.has_dog">
<div class="dog-warning" v-if="modelValue.has_dog">
<small>
<i class="bi bi-exclamation-triangle"></i>
<strong>Important:</strong> Our staff will only enter if the dog
@ -166,7 +165,7 @@
type="radio"
id="access-with-owner"
:value="PermissionAccess.WITH_OWNER"
v-model="modelValue.permission.access"
v-model="modelValue.access"
class="mt-1"
/>
<label for="access-with-owner">
@ -182,8 +181,8 @@
<div
class="conditional-section"
v-if="
modelValue.permission.access &&
modelValue.permission.access == PermissionAccess.WITH_OWNER
modelValue.access &&
modelValue.access == PermissionAccess.WITH_OWNER
"
>
<div class="form-check mb-3">
@ -192,7 +191,7 @@
type="checkbox"
id="request_scheduled"
name="request_scheduled"
v-model="modelValue.permission.wants_scheduled"
v-model="modelValue.wants_scheduled"
/>
<label class="form-check-label" for="request_scheduled">
I would like to request a scheduled visit
@ -221,7 +220,7 @@
type="radio"
id="access-denied"
:value="PermissionAccess.DENIED"
v-model="modelValue.permission.access"
v-model="modelValue.access"
class="mt-1"
/>
<label for="access-denied">
@ -237,8 +236,7 @@
<div
class="conditional-section"
v-if="
modelValue.permission.access &&
modelValue.permission.access == PermissionAccess.DENIED
modelValue.access && modelValue.access == PermissionAccess.DENIED
"
>
<div class="encouragement-box">
@ -284,24 +282,19 @@ import { ref } from "vue";
import { router } from "@/rmo/router";
import HeaderCompliance from "@/rmo/components/HeaderCompliance.vue";
import ProgressBarCompliance from "@/rmo/components/ProgressBarCompliance.vue";
import { type District, PermissionAccess } from "@/type/api";
import type { Compliance } from "@/rmo/view/Compliance.vue";
import {
type District,
PermissionAccess,
PublicReportCompliance,
} from "@/type/api";
interface Emits {
(e: "doPermission"): void;
(e: "update:modelValue", value: Compliance): void;
}
export interface Permission {
access?: PermissionAccess;
access_instructions: string;
availability_notes: string;
gate_code: string;
has_dog: boolean;
wants_scheduled: boolean;
(e: "update:modelValue", value: PublicReportCompliance): void;
}
interface Props {
district: District;
modelValue: Compliance;
modelValue: PublicReportCompliance;
}
const emit = defineEmits<Emits>();
const props = defineProps<Props>();

View file

@ -155,25 +155,21 @@
<div class="summary-value">
<span
class="status-badge status-provided"
v-if="modelValue.permission?.access == PermissionAccess.GRANTED"
v-if="modelValue.access == PermissionAccess.GRANTED"
>
<i class="bi bi-check-circle"></i> Entry permitted without owner
present
</span>
<span
class="status-badge status-provided"
v-else-if="
modelValue.permission?.access == PermissionAccess.WITH_OWNER
"
v-else-if="modelValue.access == PermissionAccess.WITH_OWNER"
>
<i class="bi bi-check-circle"></i> Entry permitted with owner
present
</span>
<span
class="status-badge status-not-provided"
v-else-if="
modelValue.permission?.access == PermissionAccess.DENIED
"
v-else-if="modelValue.access == PermissionAccess.DENIED"
>
<i class="bi bi-x-circle"></i> Entry denied
</span>
@ -189,8 +185,8 @@
<h3><i class="bi bi-person"></i> Contact Information</h3>
<div class="summary-item">
<div class="summary-label">Name</div>
<div class="summary-value" v-if="modelValue.contact?.name">
{{ modelValue.contact.name }}
<div class="summary-value" v-if="modelValue.reporter?.name">
{{ modelValue.reporter.name }}
</div>
<div class="summary-value status-badge status-not-provided" v-else>
<i class="bi bi-x-circle"></i> Not provided
@ -198,9 +194,9 @@
</div>
<div class="summary-item">
<div class="summary-label">Phone</div>
<div class="summary-value" v-if="modelValue.contact?.phone">
{{ modelValue.contact.phone }}
<small class="text-muted" v-if="modelValue.contact?.can_text"
<div class="summary-value" v-if="modelValue.reporter?.phone">
{{ modelValue.reporter.phone }}
<small class="text-muted" v-if="modelValue.reporter?.can_text"
>(texting OK)</small
>
</div>
@ -210,8 +206,8 @@
</div>
<div class="summary-item">
<div class="summary-label">Email</div>
<div class="summary-value" v-if="modelValue.contact?.email">
{{ modelValue.contact?.email }}
<div class="summary-value" v-if="modelValue.reporter?.email">
{{ modelValue.reporter?.email }}
</div>
<div class="summary-value status-badge status-not-provided" v-else>
<i class="bi bi-x-circle"></i> Not provided
@ -244,14 +240,17 @@
import { router } from "@/rmo/router";
import HeaderCompliance from "@/rmo/components/HeaderCompliance.vue";
import ProgressBarCompliance from "@/rmo/components/ProgressBarCompliance.vue";
import { type District, PermissionAccess } from "@/type/api";
import type { Compliance } from "@/rmo/view/Compliance.vue";
import {
type District,
PermissionAccess,
PublicReportCompliance,
} from "@/type/api";
interface Emits {
(e: "doSubmit"): void;
}
interface Props {
modelValue: Compliance;
modelValue: PublicReportCompliance;
district: District;
}
const emit = defineEmits<Emits>();