mirror of
https://github.com/FoggedLens/deflock.git
synced 2026-03-22 10:13:35 +00:00
non-alprs
This commit is contained in:
126
webapp/src/components/ALPRVerificationDialog.vue
Normal file
126
webapp/src/components/ALPRVerificationDialog.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<v-dialog
|
||||
v-model="show"
|
||||
:max-width="$vuetify.display.mobile ? undefined : '600'"
|
||||
:fullscreen="$vuetify.display.mobile"
|
||||
:transition="$vuetify.display.mobile ? 'dialog-bottom-transition' : 'dialog-transition'"
|
||||
@click:outside="dismiss"
|
||||
>
|
||||
<v-card class="h-100 d-flex flex-column">
|
||||
<v-card-title class="text-center py-4 font-weight-bold bg-warning d-flex align-center justify-center">
|
||||
<v-icon icon="mdi-alert-circle" size="large" class="mr-2"></v-icon>
|
||||
<h3 class="headline">Are you sure it's an ALPR?</h3>
|
||||
<v-spacer v-if="$vuetify.display.mobile"></v-spacer>
|
||||
<v-btn
|
||||
v-if="$vuetify.display.mobile"
|
||||
icon="mdi-close"
|
||||
variant="text"
|
||||
color="on-warning"
|
||||
@click="dismiss"
|
||||
></v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="pa-6 flex-grow-1 d-flex flex-column justify-center">
|
||||
<div class="content-wrapper">
|
||||
<div class="text-center mb-6">
|
||||
<img
|
||||
src="/alprs/flock-1.jpg"
|
||||
alt="Example ALPR Camera"
|
||||
style="max-width: 220px; width: 100%; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.08);"
|
||||
/>
|
||||
<div class="mt-2 text-caption text-grey-darken-1">
|
||||
Example ALPR camera (Flock Safety)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-center text-body-1 mb-12">
|
||||
Not every camera on a pole is an ALPR. Many are just traffic monitoring cameras or other equipment.
|
||||
</p>
|
||||
|
||||
<div class="text-center">
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="elevated"
|
||||
size="large"
|
||||
to="/identify"
|
||||
prepend-icon="mdi-image-search"
|
||||
class="mb-3"
|
||||
@click="dismiss"
|
||||
>
|
||||
View ALPR Gallery
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions class="pa-4">
|
||||
<v-btn
|
||||
width="100%"
|
||||
color="success"
|
||||
variant="text"
|
||||
size="large"
|
||||
@click="dismiss"
|
||||
>
|
||||
Continue
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const show = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
if (!localStorage.getItem('alpr-verification-acknowledged')) {
|
||||
show.value = true;
|
||||
}
|
||||
});
|
||||
|
||||
function dismiss() {
|
||||
show.value = false;
|
||||
localStorage.setItem('alpr-verification-acknowledged', 'true');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.headline {
|
||||
color: rgb(var(--v-theme-on-warning));
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
/* Mobile fullscreen styling */
|
||||
@media (max-width: 960px) {
|
||||
.content-wrapper {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.v-card-title h3 {
|
||||
font-size: 1.25rem !important;
|
||||
}
|
||||
|
||||
.v-card-text {
|
||||
padding: 1.5rem !important;
|
||||
}
|
||||
|
||||
.v-card-actions {
|
||||
padding: 1.5rem !important;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.v-card-actions .v-btn {
|
||||
width: 100%;
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<v-container fluid>
|
||||
<v-container fluid style="padding: 0;">
|
||||
<v-row
|
||||
justify="center"
|
||||
class="hero text-center mb-4"
|
||||
:style="`background: url('${imageUrl}') no-repeat center center / cover; --hero-opacity: ${opacity};`"
|
||||
:class="{ 'hero-image': imageUrl, 'hero-gradient': gradient }"
|
||||
:style="heroStyle"
|
||||
>
|
||||
<v-col cols="12" md="8">
|
||||
<h1 class="mb-4">{{ title }}</h1>
|
||||
@@ -32,6 +33,7 @@ const props = defineProps({
|
||||
title: String,
|
||||
description: String,
|
||||
imageUrl: String,
|
||||
gradient: String,
|
||||
buttonText: String,
|
||||
buttonTo: String,
|
||||
buttonHref: String,
|
||||
@@ -44,6 +46,15 @@ const props = defineProps({
|
||||
const target = computed(() =>
|
||||
props.buttonHref && !props.buttonHref.startsWith('#') ? '_blank' : '_self'
|
||||
);
|
||||
|
||||
const heroStyle = computed(() => {
|
||||
if (props.gradient) {
|
||||
return `background: ${props.gradient};`;
|
||||
} else if (props.imageUrl) {
|
||||
return `background: url('${props.imageUrl}') no-repeat center center / cover; --hero-opacity: ${props.opacity};`;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -51,9 +62,11 @@ const target = computed(() =>
|
||||
color: white;
|
||||
padding: 100px 0 !important;
|
||||
position: relative;
|
||||
min-height: 350px;
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
/* Overlay for image backgrounds only */
|
||||
.hero-image::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
@@ -131,6 +131,14 @@ const router = createRouter({
|
||||
name: 'foia',
|
||||
component: () => import('../views/FOIA.vue'),
|
||||
},
|
||||
{
|
||||
path: '/identify',
|
||||
name: 'identify',
|
||||
component: () => import('../views/Identification.vue'),
|
||||
meta: {
|
||||
title: 'Identify ALPRs | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/press',
|
||||
name: 'press',
|
||||
|
||||
250
webapp/src/views/Identification.vue
Normal file
250
webapp/src/views/Identification.vue
Normal file
@@ -0,0 +1,250 @@
|
||||
<template>
|
||||
<!-- Hero Section -->
|
||||
<Hero
|
||||
title="Spot an ALPR"
|
||||
description="Visual guide to identifying license plate readers"
|
||||
gradient="linear-gradient(135deg, rgb(var(--v-theme-primary)) 0%, rgb(var(--v-theme-secondary)) 100%)"
|
||||
/>
|
||||
|
||||
<v-container fluid>
|
||||
<!-- Flock Safety - Featured Section -->
|
||||
<v-container>
|
||||
<v-card class="featured-card" elevation="4">
|
||||
<v-card-title class="text-center bg-green text-h4 pt-6 px-6">
|
||||
<v-img
|
||||
contain
|
||||
src="/vendor-logos/Flock_Safety_Logo.svg"
|
||||
:alt="'Flock Logo'"
|
||||
style="height: 48px; filter: invert(1);"
|
||||
/>
|
||||
</v-card-title>
|
||||
<v-card-subtitle class="text-center pa-4 text-h6" style="white-space: normal; word-break: break-word;">
|
||||
black housing • teardrop shape • usually with solar panels
|
||||
</v-card-subtitle>
|
||||
<v-card-text class="pa-6">
|
||||
<v-row>
|
||||
<v-col v-for="(image, index) in flockImages" :key="index" cols="12" sm="6" md="3">
|
||||
<v-card class="image-card" elevation="2" @click="openImageInNewTab(image)">
|
||||
<v-img
|
||||
:src="image"
|
||||
:aspect-ratio="4/3"
|
||||
cover
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<template v-slot:placeholder>
|
||||
<v-row class="fill-height ma-0" align="center" justify="center">
|
||||
<v-progress-circular indeterminate color="primary"></v-progress-circular>
|
||||
</v-row>
|
||||
</template>
|
||||
</v-img>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-container>
|
||||
|
||||
<!-- Other ALPR Types -->
|
||||
<v-container class="mb-12">
|
||||
<h2 class="text-center mb-8">Other ALPR Types</h2>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="6" v-for="vendor in otherVendors" :key="vendor.vendor" class="mb-4">
|
||||
<v-card class="vendor-card h-100" elevation="2">
|
||||
<v-card-title class="text-center" style="background-color: #f5f5f5;">
|
||||
<v-img v-if="vendor.logoUrl" contain :src="vendor.logoUrl" :alt="`${vendor.vendor} Logo`" style="height: 48px;" />
|
||||
<div
|
||||
style="height: 48px; display: flex; align-items: center; justify-content: center;"
|
||||
class="font-weight-bold"
|
||||
v-else
|
||||
>
|
||||
{{ vendor.vendor }}
|
||||
</div>
|
||||
</v-card-title>
|
||||
<v-card-text class="pa-4">
|
||||
<v-row>
|
||||
<v-col v-for="(image, index) in vendor.imageUrls" :key="index" cols="6">
|
||||
<v-card class="image-card" elevation="1" @click="openImageInNewTab(image)">
|
||||
<v-img
|
||||
:src="image"
|
||||
:aspect-ratio="4/3"
|
||||
cover
|
||||
class="cursor-pointer"
|
||||
>
|
||||
</v-img>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- What ALPRs are NOT -->
|
||||
<v-container class="mb-12">
|
||||
<v-card class="not-alpr-card" elevation="3">
|
||||
<v-card-title
|
||||
class="text-center px-6 bg-warning font-weight-bold"
|
||||
:class="[$vuetify.display.smAndDown ? 'text-h6' : 'text-h4']"
|
||||
style="white-space: normal; word-break: break-word;"
|
||||
>
|
||||
NOT ALPRs
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text class="px-6 pt-6">
|
||||
<v-row>
|
||||
<!-- Traffic Detection Cameras -->
|
||||
<v-col cols="12" md="9" class="mb-6">
|
||||
<h3 class="text-center mb-4">Traffic Detection Cameras</h3>
|
||||
<v-row>
|
||||
<v-col v-for="(image, index) in trafficCameraImages" :key="index" cols="12" md="4">
|
||||
<v-card class="image-card" elevation="1" @click="openImageInNewTab(image)">
|
||||
<v-img
|
||||
:src="image"
|
||||
:aspect-ratio="4/3"
|
||||
cover
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
|
||||
<!-- Snow Detection Cameras -->
|
||||
<v-col cols="12" md="3" class="mb-6">
|
||||
<h3 class="text-center mb-4">Snow/Ice Cameras</h3>
|
||||
<v-row>
|
||||
<v-col v-for="(image, index) in snowDetectionImages" :key="index" cols="12">
|
||||
<v-card class="image-card" elevation="1" @click="openImageInNewTab(image)">
|
||||
<v-img
|
||||
:src="image"
|
||||
:aspect-ratio="4/3"
|
||||
cover
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-container>
|
||||
|
||||
<!-- Action Section -->
|
||||
<v-container class="text-center mb-12">
|
||||
<v-card class="action-card pa-8" elevation="0" color="transparent">
|
||||
<v-card-title class="text-h4 mb-4">Found one?</v-card-title>
|
||||
<v-card-text>
|
||||
<v-btn
|
||||
size="x-large"
|
||||
color="primary"
|
||||
to="/report"
|
||||
prepend-icon="mdi-map-marker-plus"
|
||||
variant="elevated"
|
||||
class="mr-4"
|
||||
>
|
||||
Add to Map
|
||||
</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-container>
|
||||
</v-container>
|
||||
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Hero from '@/components/layout/Hero.vue';
|
||||
import Footer from '@/components/layout/Footer.vue';
|
||||
|
||||
function openImageInNewTab(url: string) {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
// Flock Safety - Featured prominently
|
||||
const flockImages = [
|
||||
'/alprs/flock-5.webp',
|
||||
'/alprs/flock-1.jpg',
|
||||
'/alprs/flock-2.jpg',
|
||||
'/alprs/flock-3.jpg',
|
||||
'/alprs/flock-4.jpg'
|
||||
];
|
||||
|
||||
// Other ALPR vendors
|
||||
const otherVendors = [
|
||||
{
|
||||
vendor: 'Motorola/Vigilant',
|
||||
logoUrl: '/vendor-logos/Motorola_Solutions_Logo.svg',
|
||||
description: 'Usually dark and rectangular, with visible IR illuminators. Often next to an ugly white box.',
|
||||
imageUrls: ['/alprs/motorola-1.jpg', '/alprs/motorola-2.jpg', '/alprs/motorola-3.jpg', '/alprs/motorola-4.jpg']
|
||||
},
|
||||
{
|
||||
vendor: 'Genetec',
|
||||
logoUrl: '/vendor-logos/logo_genetec_rgb_color_tm.svg',
|
||||
description: 'Usually white and rectangular, with visible IR illuminators',
|
||||
imageUrls: ['/alprs/genetec-1.webp', '/alprs/genetec-2.webp', '/alprs/genetec-3.webp']
|
||||
},
|
||||
{
|
||||
vendor: 'Leonardo/ELSAG',
|
||||
logoUrl: '/vendor-logos/Logo_Leonardo.svg',
|
||||
description: 'Large, highly visible array of IR lights',
|
||||
imageUrls: ['/alprs/elsag-3.jpg', '/alprs/elsag-4.jpg', '/alprs/elsag-1.jpg', '/alprs/elsag-2.jpg']
|
||||
},
|
||||
{
|
||||
vendor: 'Neology',
|
||||
description: 'Ugly with a white rounded rectangular shape and long hood',
|
||||
imageUrls: ['/alprs/neology-1.jpg', '/alprs/neology-2.jpg']
|
||||
}
|
||||
];
|
||||
|
||||
const trafficCameraImages = [
|
||||
'/non-alprs/iteris.webp',
|
||||
'/non-alprs/traffic-cam.webp',
|
||||
'/non-alprs/flir.webp',
|
||||
];
|
||||
|
||||
const snowDetectionImages = [
|
||||
'/non-alprs/frost-cam.jpeg'
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.featured-card {
|
||||
/* border: 3px solid rgb(var(--v-theme-secondary)); */
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.vendor-card {
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.vendor-card:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.image-card {
|
||||
transition: transform 0.2s ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.image-card:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.overlay-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
color: rgb(var(--v-theme-on-surface));
|
||||
}
|
||||
</style>
|
||||
@@ -1,17 +1,32 @@
|
||||
<template>
|
||||
<v-container class="my-16">
|
||||
<v-row justify="center" class="mb-8">
|
||||
<!-- ALPR Verification Dialog -->
|
||||
<ALPRVerificationDialog />
|
||||
|
||||
<v-row justify="center" class="mb-4">
|
||||
<v-col cols="12" md="8">
|
||||
<h2 class="text-center text-h4 font-weight-bold">Choose Your Reporting Method</h2>
|
||||
<p class="text-center text-body-1 mt-4">
|
||||
We use OpenStreetMap to source our data. Choose a method below to add to our map.
|
||||
</p>
|
||||
<p class="sans-serif text-center mt-2">
|
||||
<a style="font-size: 0.85em" target="_blank" href="https://deflock.hashnode.dev/why-we-use-openstreetmap">Why do we use OSM?</a>
|
||||
Choose a method below to add to our map.
|
||||
</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- ALPR Identification Warning -->
|
||||
<v-row justify="center" class="mb-8">
|
||||
<v-col cols="12" class="text-center">
|
||||
<v-btn
|
||||
color="blue"
|
||||
variant="tonal"
|
||||
to="/identify"
|
||||
prepend-icon="mdi-image-search"
|
||||
size="large"
|
||||
>
|
||||
View ALPR Gallery
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row justify="center">
|
||||
<v-col cols="12" md="5" class="pa-4">
|
||||
<v-card
|
||||
@@ -88,3 +103,18 @@
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ALPRVerificationDialog from '@/components/ALPRVerificationDialog.vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.verification-alert {
|
||||
border-left-width: 6px !important;
|
||||
}
|
||||
|
||||
.verification-alert .v-alert-title {
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<v-container fluid>
|
||||
<v-row justify="center" class="hero-section-whatis text-center mb-4">
|
||||
</v-row>
|
||||
</v-container>
|
||||
<Hero
|
||||
image-url="/flock-camera.jpeg"
|
||||
:opacity="0"
|
||||
/>
|
||||
|
||||
<v-container class="info-section">
|
||||
<v-container class="info-section mb-16">
|
||||
<h1 class="mt-0">What are ALPRs?</h1>
|
||||
<p>
|
||||
Automated License Plate Readers (ALPRs) are AI-powered cameras that capture and analyze images of all passing vehicles, storing details like your car's location, date, and time. They also capture your car's make, model, color, and identifying features such as dents, roof racks, and bumper stickers, <a href="https://www.flocksafety.com/products/license-plate-readers#:~:text=No%20Plate%3F%20No%20Problem" target="_blank">often turning these into searchable data points</a>. These cameras collect data on millions of vehicles—regardless of whether the driver is suspected of a crime. While these systems can be useful for tracking stolen cars or wanted individuals, they are mostly used to track the movements of innocent people.
|
||||
@@ -12,6 +12,21 @@
|
||||
|
||||
<p>For a detailed explanation of how ALPRs are a threat to privacy, see this <a href="https://www.aclu.org/issues/privacy-technology/you-are-being-tracked" target="_blank">ACLU article</a> as well as this <a href="https://sls.eff.org/technologies/automated-license-plate-readers-alprs" target="_blank">EFF article</a> on ALPRs.</p>
|
||||
|
||||
<v-divider class="my-12" />
|
||||
|
||||
<h2 class="mb-8">
|
||||
<v-icon class="mr-2" color="primary">mdi-camera-outline</v-icon>
|
||||
What do they look like?
|
||||
</h2>
|
||||
<div class="mb-16 text-center">
|
||||
<v-btn size="large" color="primary" to="/identify">
|
||||
<v-icon left class="mr-2">mdi-image-search</v-icon>
|
||||
View ALPR Images
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-divider class="my-12" />
|
||||
|
||||
<h2>Why Should You Be Concerned</h2>
|
||||
<p class="mb-8 text-center">
|
||||
ALPRs invade your privacy and violate your civil liberties. Here's how:
|
||||
@@ -19,73 +34,19 @@
|
||||
|
||||
<Dangers />
|
||||
|
||||
<v-divider class="my-12" />
|
||||
|
||||
<h2>Frequently Asked Questions</h2>
|
||||
<h2 class="mb-8">Frequently Asked Questions</h2>
|
||||
<FAQ />
|
||||
|
||||
<h2 id="photos">What they Look Like</h2>
|
||||
|
||||
<v-row v-for="vendor in vendors" :key="vendor.vendor" class="mb-4">
|
||||
<v-col cols="12">
|
||||
<h3 class="text-center">{{ vendor.vendor }}</h3>
|
||||
</v-col>
|
||||
<v-col v-for="url in vendor.imageUrls" cols="12" sm="6" md="4">
|
||||
<v-img @click="openImageInNewTab(url)" style="cursor: pointer;" cover :aspect-ratio="3/2" :src="url" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
<Footer />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, type Ref } from 'vue';
|
||||
import { useDisplay } from 'vuetify';
|
||||
import Hero from '@/components/layout/Hero.vue';
|
||||
import Dangers from '@/components/Dangers.vue';
|
||||
import FAQ from '@/components/FAQ.vue';
|
||||
import Footer from '@/components/layout/Footer.vue';
|
||||
const { xs: isMobile } = useDisplay();
|
||||
|
||||
const showFullScreenImage = ref(false);
|
||||
const fullScreenImage: Ref<any|undefined> = ref(undefined);
|
||||
|
||||
function openImageInNewTab(url: string, newTab: boolean = true) {
|
||||
window.open(url, newTab ? '_blank' : '_self');
|
||||
}
|
||||
|
||||
const vendors = [
|
||||
{
|
||||
vendor: 'Flock',
|
||||
count: 4,
|
||||
urlScheme: '/alprs/flock-{index}.jpg',
|
||||
},
|
||||
{
|
||||
vendor: 'Motorola/Vigilant',
|
||||
count: 4,
|
||||
urlScheme: '/alprs/motorola-{index}.jpg',
|
||||
},
|
||||
{
|
||||
vendor: 'Genetec',
|
||||
count: 3,
|
||||
urlScheme: '/alprs/genetec-{index}.webp',
|
||||
},
|
||||
{
|
||||
vendor: 'Leonardo/ELSAG',
|
||||
count: 4,
|
||||
urlScheme: '/alprs/elsag-{index}.jpg',
|
||||
},
|
||||
{
|
||||
vendor: 'Neology',
|
||||
count: 2,
|
||||
urlScheme: '/alprs/neology-{index}.jpg',
|
||||
},
|
||||
].reduce((acc: any, vendor: any) => {
|
||||
const imageUrls = Array.from({ length: vendor.count }, (_, index) =>
|
||||
vendor.urlScheme.replace('{index}', String(index + 1)),
|
||||
);
|
||||
|
||||
acc.push({ vendor: vendor.vendor, imageUrls });
|
||||
return acc;
|
||||
}, []);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -129,12 +90,4 @@ h1, h2 {
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.hero-section-whatis {
|
||||
background: url('/flock-camera.jpeg') no-repeat right center;
|
||||
background-size: cover;
|
||||
color: white;
|
||||
position: relative;
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user