2024-11-24 22:07:09 -05:00
|
|
|
<script setup lang="ts">
|
2024-12-08 16:21:39 -05:00
|
|
|
import { computed, ref, toRaw, watch } from 'vue'
|
2024-11-24 22:07:09 -05:00
|
|
|
|
|
|
|
|
import Button from 'primevue/button';
|
|
|
|
|
import Card from 'primevue/card';
|
2024-12-08 16:21:39 -05:00
|
|
|
import Chip from 'primevue/chip';
|
2024-11-24 22:07:09 -05:00
|
|
|
import ColorPicker from 'primevue/colorpicker';
|
|
|
|
|
import { Form } from '@primevue/forms';
|
2024-12-08 16:21:39 -05:00
|
|
|
import Image from 'primevue/image';
|
2024-11-24 22:07:09 -05:00
|
|
|
import InputGroup from 'primevue/inputgroup';
|
|
|
|
|
import InputGroupAddon from 'primevue/inputgroupaddon';
|
|
|
|
|
import InputText from 'primevue/inputtext';
|
|
|
|
|
import RadioButton from 'primevue/radiobutton';
|
|
|
|
|
|
|
|
|
|
import IconLayout1Vue from '@/components/layouts/IconLayout1.vue';
|
|
|
|
|
import IconLayout2Vue from '@/components/layouts/IconLayout2.vue';
|
|
|
|
|
import IconLayout3Vue from '@/components/layouts/IconLayout3.vue';
|
|
|
|
|
import IconLayout4Vue from '@/components/layouts/IconLayout4.vue';
|
|
|
|
|
import Sticker from '@/components/Sticker.vue';
|
2024-12-08 16:21:39 -05:00
|
|
|
import { type Organization, useOrganization } from '@/queries/organization';
|
|
|
|
|
import { useSticker } from '@/composables/sticker';
|
|
|
|
|
import { activist, type Sticker as StickerType } from '@/stores/stickersStore';
|
2024-12-05 20:43:01 -05:00
|
|
|
|
|
|
|
|
|
2024-12-08 16:21:39 -05:00
|
|
|
const { state: orgs } = useOrganization();
|
|
|
|
|
const myOrgs = ref<Organization[]>([]);
|
2024-12-06 22:48:38 -05:00
|
|
|
const original = useSticker();
|
|
|
|
|
let sticker = ref<StickerType>(activist);
|
2024-12-08 16:21:39 -05:00
|
|
|
const orgFilter = ref("");
|
2024-11-24 22:07:09 -05:00
|
|
|
|
2024-12-06 22:48:38 -05:00
|
|
|
// When the original sticker appears, copy it into a local coy.
|
2024-12-07 18:21:44 -05:00
|
|
|
watch(original, (newValue) => {
|
2024-12-06 22:48:38 -05:00
|
|
|
sticker.value = structuredClone(toRaw(newValue));
|
|
|
|
|
});
|
2024-11-24 22:07:09 -05:00
|
|
|
|
|
|
|
|
const initialValues = {};
|
|
|
|
|
const resolver = () => {
|
|
|
|
|
return {};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function onFormSubmit() {
|
2024-12-06 22:48:38 -05:00
|
|
|
original.value = sticker.value;
|
2024-11-24 22:07:09 -05:00
|
|
|
}
|
2024-12-08 16:21:39 -05:00
|
|
|
|
|
|
|
|
function addOrg(id: string) {
|
|
|
|
|
myOrgs.value.push(orgs.value.data.find((org: Organization) => org.id === id));
|
|
|
|
|
}
|
|
|
|
|
function removeOrg(orgId: string) {
|
|
|
|
|
const myIds = myOrgs.value.map(org => org.id);
|
|
|
|
|
let start = myIds.indexOf(orgId);
|
|
|
|
|
myOrgs.value.splice(start, 1);
|
|
|
|
|
}
|
|
|
|
|
const orgOptions = computed(() => {
|
|
|
|
|
const myIds = myOrgs.value.map(org => org.id);
|
|
|
|
|
return orgs.value.data.filter(({ id, name }) => {
|
|
|
|
|
return !myIds.includes(id)
|
|
|
|
|
&& name.toLowerCase().includes(orgFilter.value.toLowerCase());
|
|
|
|
|
});
|
|
|
|
|
});
|
2024-11-24 22:07:09 -05:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<div id="StickerPage">
|
|
|
|
|
<!-- <Button class="w-20" type="submit" severity="secondary" label="Take a snapshot" />-->
|
|
|
|
|
<div id="StickerWrapper" class="sticky top-0 z-10">
|
2024-12-05 20:43:01 -05:00
|
|
|
<Sticker id="Sticker1" v-bind="sticker" />
|
2024-11-24 22:07:09 -05:00
|
|
|
<!-- <p>8-inch sticker</p>-->
|
2024-12-05 20:43:01 -05:00
|
|
|
<!-- <Sticker id="Sticker2" v-bind="sticker2" />-->
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
<Card>
|
|
|
|
|
<template #content>
|
2024-12-05 20:43:01 -05:00
|
|
|
<Form v-bind:initialValues
|
2024-11-24 22:07:09 -05:00
|
|
|
v-bind:resolver="resolver"
|
|
|
|
|
@submit="onFormSubmit">
|
2024-12-07 18:55:09 -05:00
|
|
|
<div class="bg-surface-50 dark:bg-surface-950 px-3 py-5 md:px-12">
|
2024-11-24 22:07:09 -05:00
|
|
|
<div class="grid grid-cols-12 gap-4">
|
2024-12-08 16:21:39 -05:00
|
|
|
<div class="col-span-12 flex flex-col gap-4">
|
|
|
|
|
<label for="nickname2">Organizations I Support</label>
|
|
|
|
|
<div class="my-orgs">
|
|
|
|
|
<div v-for="org in myOrgs" :key="org.id">
|
|
|
|
|
<Chip
|
|
|
|
|
:image="org.logo"
|
|
|
|
|
:label="org.abbrev"
|
|
|
|
|
removable
|
|
|
|
|
v-on:remove="removeOrg(org.id)"
|
|
|
|
|
>
|
|
|
|
|
</Chip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<InputText
|
|
|
|
|
id="nickname2"
|
|
|
|
|
type="text"
|
|
|
|
|
class="w-full"
|
|
|
|
|
placeholder="search"
|
|
|
|
|
v-model="orgFilter"
|
|
|
|
|
/>
|
|
|
|
|
<div v-if="orgs.status === 'pending'">
|
|
|
|
|
loading
|
|
|
|
|
</div>
|
|
|
|
|
<div v-if="orgs.error">
|
|
|
|
|
There was an error loading organization data.
|
|
|
|
|
</div>
|
|
|
|
|
<div class="logos" v-else-if="orgs.data">
|
|
|
|
|
<div v-for="org in orgOptions" :key="org.id">
|
|
|
|
|
<a @click="addOrg(org.id)">
|
|
|
|
|
<Image class="logo" :src="org.logo" alt="Image" />
|
|
|
|
|
{{ org.name }}
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider" />
|
|
|
|
|
|
2024-11-24 22:07:09 -05:00
|
|
|
<div class="col-span-12">
|
2024-12-05 20:43:01 -05:00
|
|
|
<label for="nickname2">Layout {{sticker.layout}}</label>
|
2024-11-24 22:07:09 -05:00
|
|
|
<div class="flex flex-wrap gap-4">
|
|
|
|
|
<div class="flex items-center gap-2">
|
2024-12-05 20:43:01 -05:00
|
|
|
<RadioButton v-model="sticker.layout" inputId="layout1" name="layout" value="layout1" />
|
2024-11-24 22:07:09 -05:00
|
|
|
<label for="layout1"><IconLayout1Vue /></label>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2">
|
2024-12-05 20:43:01 -05:00
|
|
|
<RadioButton v-model="sticker.layout" inputId="layout2" name="layout" value="layout2" />
|
2024-11-24 22:07:09 -05:00
|
|
|
<label for="layout2"><IconLayout2Vue /></label>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2">
|
2024-12-05 20:43:01 -05:00
|
|
|
<RadioButton v-model="sticker.layout" inputId="layout3" name="layout" value="layout3" />
|
2024-11-24 22:07:09 -05:00
|
|
|
<label for="layout3"><IconLayout3Vue /></label>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2">
|
2024-12-05 20:43:01 -05:00
|
|
|
<RadioButton v-model="sticker.layout" inputId="layout4" name="layout" value="layout4" />
|
2024-11-24 22:07:09 -05:00
|
|
|
<label for="layout4"><IconLayout4Vue /></label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider" />
|
|
|
|
|
|
|
|
|
|
<div class="col-span-12 md:col-span-6">
|
|
|
|
|
<label for="message1">Message 1</label>
|
2024-12-05 20:43:01 -05:00
|
|
|
<InputText class="w-full" id="message1" name="message1" type="text" v-model="sticker.message1" fluid />
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
<div class="col-span-12 md:col-span-6">
|
|
|
|
|
<label for="message2">Message 2</label>
|
2024-12-05 20:43:01 -05:00
|
|
|
<InputText class="w-full" id="message2" name="message2" type="text" v-model="sticker.message2" fluid />
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="col-span-12 md:col-span-6">
|
|
|
|
|
<label for="message1">Message 3</label>
|
2024-12-05 20:43:01 -05:00
|
|
|
<InputText class="w-full" id="message3" name="message3" type="text" v-model="sticker.message3" fluid />
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
<div class="col-span-12 md:col-span-6">
|
|
|
|
|
<label for="message4">Message 4</label>
|
2024-12-05 20:43:01 -05:00
|
|
|
<InputText class="w-full" id="message4" name="message4" type="text" v-model="sticker.message4" fluid />
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider" />
|
|
|
|
|
|
|
|
|
|
<div class="col-span-12 md:col-span-6">
|
2024-12-05 20:43:01 -05:00
|
|
|
<label>Background Color {{sticker.color}}</label>
|
|
|
|
|
<ColorPicker v-model="sticker.color" />
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
<div class="col-span-12 md:col-span-6">
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider" />
|
|
|
|
|
|
|
|
|
|
<div class="col-span-12">
|
|
|
|
|
<label for="nickname2">My note about this sticker</label>
|
|
|
|
|
<InputText id="nickname2" type="text" class="w-full" placeholder="First one I made" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider" />
|
|
|
|
|
|
|
|
|
|
<div class="col-span-12">
|
|
|
|
|
<label for="website2">Website</label>
|
|
|
|
|
<InputGroup>
|
|
|
|
|
<InputGroupAddon>URL</InputGroupAddon>
|
|
|
|
|
<InputText id="website2" placeholder="https://" />
|
|
|
|
|
</InputGroup>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="divider" />
|
|
|
|
|
|
|
|
|
|
<div class="col-span-12">
|
2024-12-06 22:48:38 -05:00
|
|
|
<Button label="Save Changes" class="w-auto mt-4" type="submit" />
|
2024-11-24 22:07:09 -05:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Form>
|
|
|
|
|
</template>
|
|
|
|
|
</Card>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
label {
|
|
|
|
|
@apply font-medium text-surface-900 dark:text-surface-0 mb-1 block;
|
|
|
|
|
}
|
|
|
|
|
.divider {
|
|
|
|
|
@apply border-surface border-t opacity-50 mb-4 col-span-12;
|
|
|
|
|
}
|
|
|
|
|
#StickerPage {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
> * {
|
|
|
|
|
margin-bottom: 1em;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#StickerWrapper {
|
|
|
|
|
background-color: #CCC;
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 1em;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
#Sticker1 {
|
|
|
|
|
width: 300px;
|
|
|
|
|
}
|
|
|
|
|
#Sticker2 {
|
|
|
|
|
width: 400px;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-08 16:21:39 -05:00
|
|
|
.logos {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 1em;
|
|
|
|
|
height: 200px;
|
|
|
|
|
overflow: auto;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
> div {
|
|
|
|
|
background-color: #F8F8F8;
|
|
|
|
|
border: 1px solid #bbb;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
height: 60px;
|
|
|
|
|
padding: 6px;
|
|
|
|
|
width: 310px;
|
|
|
|
|
> a {
|
|
|
|
|
align-items: center;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 1em;
|
|
|
|
|
.logo {
|
|
|
|
|
filter: grayscale(1);
|
|
|
|
|
width: 50px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.my-orgs {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 1em;
|
|
|
|
|
font-size: 80%;
|
|
|
|
|
.logo {
|
|
|
|
|
display: block;
|
|
|
|
|
filter: grayscale(1);
|
|
|
|
|
width: 50px;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-11-24 22:07:09 -05:00
|
|
|
</style>
|