Add StickerView.
This commit is contained in:
parent
ddc8c5fc5c
commit
3ef1507bab
5 changed files with 125 additions and 227 deletions
32
server.js
32
server.js
|
|
@ -1,19 +1,43 @@
|
||||||
import http from "http";
|
import http from "http";
|
||||||
|
|
||||||
const host = 'localhost';
|
const host = '127.0.0.1';
|
||||||
const port = 8000;
|
const port = 8000;
|
||||||
|
|
||||||
const user = JSON.stringify({
|
const user = JSON.stringify({
|
||||||
name: "Joe User",
|
name: "Joe User",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stickers = {
|
||||||
|
"88ae126f-b19a-4287-abe0-a8f5ac763cb7": {
|
||||||
|
backgroundColor: "#000088",
|
||||||
|
layout: "layout1",
|
||||||
|
message1: "I am an activist!",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const requestListener = function (req, res) {
|
const requestListener = function (req, res) {
|
||||||
res.setHeader("Content-Type", "application/json");
|
res.setHeader("Content-Type", "application/json");
|
||||||
switch (req.url) {
|
const urlParts = req.url.split("/");
|
||||||
case "/login":
|
console.log(urlParts);
|
||||||
|
switch (urlParts[1]) {
|
||||||
|
case "login":
|
||||||
res.writeHead(200);
|
res.writeHead(200);
|
||||||
res.end(user);
|
res.end(user);
|
||||||
break
|
break;
|
||||||
|
case "sticker":
|
||||||
|
if (!(urlParts[2] in stickers)) {
|
||||||
|
res.writeHead(404);
|
||||||
|
res.end('not found')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
res.writeHead(200);
|
||||||
|
const sticker = stickers[urlParts[2]];
|
||||||
|
const response = JSON.stringify(sticker);
|
||||||
|
res.end(response);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
res.writeHead(200);
|
||||||
|
res.end(JSON.stringify({nothing: 'here'}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import HomeView from '../views/HomeView.vue'
|
||||||
import LoginView from '../views/LoginView.vue'
|
import LoginView from '../views/LoginView.vue'
|
||||||
import ProfileView from '../views/ProfileView.vue'
|
import ProfileView from '../views/ProfileView.vue'
|
||||||
import StickerBuilderView from '../views/StickerBuilderView.vue'
|
import StickerBuilderView from '../views/StickerBuilderView.vue'
|
||||||
|
import StickerView from '../views/StickerView.vue'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
|
@ -22,7 +23,7 @@ const router = createRouter({
|
||||||
title: 'Profile',
|
title: 'Profile',
|
||||||
},
|
},
|
||||||
name: 'profile',
|
name: 'profile',
|
||||||
path: '/:uuid([0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12})',
|
path: '/profile',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: AboutView,
|
component: AboutView,
|
||||||
|
|
@ -40,6 +41,14 @@ const router = createRouter({
|
||||||
name: 'stickerbuilder',
|
name: 'stickerbuilder',
|
||||||
path: '/stickerbuilder',
|
path: '/stickerbuilder',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: StickerView,
|
||||||
|
meta: {
|
||||||
|
title: 'Sticker',
|
||||||
|
},
|
||||||
|
name: 'sticker',
|
||||||
|
path: '/:uuid([0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12})',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
component: LoginView,
|
component: LoginView,
|
||||||
meta: {
|
meta: {
|
||||||
|
|
|
||||||
24
src/stores/stickerStore.ts
Normal file
24
src/stores/stickerStore.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useStickerStore = defineStore('sticker', {
|
||||||
|
actions: {
|
||||||
|
async fetch(uuid: string) {
|
||||||
|
console.log('fetch');
|
||||||
|
// TODO: Check if we have it already and if it's stale.
|
||||||
|
const response = await fetch(
|
||||||
|
`/sticker/${uuid}`,
|
||||||
|
);
|
||||||
|
const json = await response.json();
|
||||||
|
console.log(json);
|
||||||
|
// this.stickers.push(json);
|
||||||
|
this.sticker = json;
|
||||||
|
console.log('done in fetch');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state: () => {
|
||||||
|
return {
|
||||||
|
// stickers: [],
|
||||||
|
sticker: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
@ -1,235 +1,71 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {computed, ref} from 'vue';
|
import {computed, onBeforeMount, ref} from 'vue';
|
||||||
|
|
||||||
import Button from 'primevue/button';
|
import Button from 'primevue/button';
|
||||||
import Card from 'primevue/card';
|
import Panel from 'primevue/panel';
|
||||||
import ColorPicker from 'primevue/colorpicker';
|
import Sticker from "@/components/Sticker.vue";
|
||||||
import { Form } from '@primevue/forms';
|
import { useRoute } from 'vue-router';
|
||||||
import InputGroup from 'primevue/inputgroup';
|
import { useUserStore } from "@/stores/userStore";
|
||||||
import InputGroupAddon from 'primevue/inputgroupaddon';
|
import { useStickerStore } from "@/stores/stickerStore";
|
||||||
import InputText from 'primevue/inputtext';
|
|
||||||
import RadioButton from 'primevue/radiobutton';
|
|
||||||
import Select from 'primevue/select';
|
|
||||||
import ToggleSwitch from 'primevue/toggleswitch';
|
|
||||||
|
|
||||||
import IconLayout1Vue from '@/components/layouts/IconLayout1.vue';
|
const stickerStore = useStickerStore();
|
||||||
import IconLayout2Vue from '@/components/layouts/IconLayout2.vue';
|
const userStore = useUserStore();
|
||||||
import IconLayout3Vue from '@/components/layouts/IconLayout3.vue';
|
|
||||||
import IconLayout4Vue from '@/components/layouts/IconLayout4.vue';
|
|
||||||
import Sticker from '@/components/Sticker.vue';
|
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const uuid = ref<string>(route.params.uuid as string);
|
||||||
|
// const uuid = ref(route.params.uuid);
|
||||||
|
console.log('uuid', uuid.value);
|
||||||
|
|
||||||
const checked = ref(true);
|
onBeforeMount(async () => {
|
||||||
const selectedCountry = ref(null);
|
await stickerStore.fetch(uuid.value);
|
||||||
const countries = ref([
|
});
|
||||||
{ name: 'Afghanistan', code: 'AF' },
|
|
||||||
{ name: 'Åland Islands', code: 'AX' },
|
|
||||||
{ name: 'Albania', code: 'AL' },
|
|
||||||
{ name: 'Algeria', code: 'DZ' },
|
|
||||||
{ name: 'American Samoa', code: 'AS' },
|
|
||||||
{ name: 'AndorrA', code: 'AD' },
|
|
||||||
{ name: 'Angola', code: 'AO' },
|
|
||||||
{ name: 'Anguilla', code: 'AI' },
|
|
||||||
{ name: 'Antarctica', code: 'AQ' },
|
|
||||||
{ name: 'Antigua and Barbuda', code: 'AG' },
|
|
||||||
{ name: 'Argentina', code: 'AR' },
|
|
||||||
{ name: 'Armenia', code: 'AM' },
|
|
||||||
{ name: 'Aruba', code: 'AW' },
|
|
||||||
{ name: 'Australia', code: 'AU' },
|
|
||||||
{ name: 'Austria', code: 'AT' },
|
|
||||||
{ name: 'Azerbaijan', code: 'AZ' },
|
|
||||||
{ name: 'Bahamas', code: 'BS' }
|
|
||||||
]);
|
|
||||||
const initialValues = {};
|
|
||||||
const resolver = () => {
|
|
||||||
return {};
|
|
||||||
};
|
|
||||||
|
|
||||||
const layout = defineModel('layout');
|
const first = computed(() => {
|
||||||
layout.value = 'layout1';
|
const parts = uuid.value.split('-')
|
||||||
const message1 = defineModel('message1');
|
return [parts[0], parts[1], parts[2]].join('-');
|
||||||
message1.value = "I SUPPORT M4A";
|
})
|
||||||
const message2 = defineModel('message2');
|
const second = computed(() => {
|
||||||
message2.value = "m2";
|
const parts = uuid.value.split('-')
|
||||||
const message3 = defineModel('message3');
|
return [parts[3], parts[4]].join('-');
|
||||||
message3.value = "m3";
|
|
||||||
const message4 = defineModel('message4');
|
|
||||||
message4.value = "";
|
|
||||||
const color = defineModel('background-color');
|
|
||||||
color.value = '000088';
|
|
||||||
|
|
||||||
const color2 = computed(() => {
|
|
||||||
return '#' + color.value;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function onFormSubmit() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="StickerPage">
|
<div class="profilePage">
|
||||||
<h1>Sticker</h1>
|
<Panel>
|
||||||
<!-- <Button class="w-20" type="submit" severity="secondary" label="Take a snapshot" />-->
|
<div class="flex flex-row content-end">
|
||||||
<div id="StickerWrapper" class="sticky top-0 z-10">
|
<div>
|
||||||
|
<div class="font-mono text-sn tracking-wider col">
|
||||||
|
{{ first }}
|
||||||
|
</div>
|
||||||
|
<div class="font-mono text-sn tracking-wider col">
|
||||||
|
{{ second }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="Sticker">
|
||||||
|
<div class="flex flex-col gap-5">
|
||||||
|
<div id="StickerWrapper">
|
||||||
<Sticker
|
<Sticker
|
||||||
id="Sticker1"
|
:color="stickerStore.sticker.backgroundColor"
|
||||||
v-bind:layout v-bind:color="color2"
|
:layout="stickerStore.sticker.layout"
|
||||||
v-bind:message1 v-bind:message2
|
:message1="stickerStore.sticker.message1"
|
||||||
v-bind:message3 v-bind:message4
|
message2="message2"
|
||||||
|
message3="message3"
|
||||||
|
message4="message4"
|
||||||
|
v-if="stickerStore.sticker"
|
||||||
/>
|
/>
|
||||||
<!-- <p>8-inch sticker</p>-->
|
|
||||||
<!-- <Sticker-->
|
|
||||||
<!-- id="Sticker2"-->
|
|
||||||
<!-- v-bind:layout v-bind:color="color2"-->
|
|
||||||
<!-- v-bind:message1 v-bind:message2-->
|
|
||||||
<!-- v-bind:message3 v-bind:message4-->
|
|
||||||
<!-- />-->
|
|
||||||
</div>
|
</div>
|
||||||
<Card>
|
<Button
|
||||||
<template #content>
|
v-bind:disabled="userStore.isAnonymous"
|
||||||
<Form v-slot="$form"
|
>
|
||||||
v-bind:initialValues
|
This is my sticker!
|
||||||
v-bind:resolver="resolver"
|
</Button>
|
||||||
@submit="onFormSubmit">
|
<span v-if="userStore.isAnonymous">
|
||||||
<div class="bg-surface-50 dark:bg-surface-950 px-3 py-5 md:px-12 lg:px-5">
|
Log in to claim your sticker.
|
||||||
<div class="grid grid-cols-12 gap-4">
|
</span>
|
||||||
<div class="col-span-12">
|
|
||||||
<label for="nickname2">Layout {{layout}}</label>
|
|
||||||
<div class="flex flex-wrap gap-4">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<RadioButton v-model="layout" inputId="layout1" name="layout" value="layout1" />
|
|
||||||
<label for="layout1"><IconLayout1Vue /></label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
</Panel>
|
||||||
<RadioButton v-model="layout" inputId="layout2" name="layout" value="layout2" />
|
|
||||||
<label for="layout2"><IconLayout2Vue /></label>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<RadioButton v-model="layout" inputId="layout3" name="layout" value="layout3" />
|
|
||||||
<label for="layout3"><IconLayout3Vue /></label>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<RadioButton v-model="layout" inputId="layout4" name="layout" value="layout4" />
|
|
||||||
<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>
|
|
||||||
<InputText class="w-full" id="message1" name="message1" type="text" v-model="message1" fluid />
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="message2">Message 2</label>
|
|
||||||
<InputText class="w-full" id="message2" name="message2" type="text" v-model="message2" fluid />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="message1">Message 3</label>
|
|
||||||
<InputText class="w-full" id="message3" name="message3" type="text" v-model="message3" fluid />
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="message4">Message 4</label>
|
|
||||||
<InputText class="w-full" id="message4" name="message4" type="text" v-model="message4" fluid />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider" />
|
|
||||||
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="email2">Background Color {{color}}</label>
|
|
||||||
<ColorPicker v-model="color" />
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="country2">Country</label>
|
|
||||||
<Select id="country2" v-model="selectedCountry" :options="countries" option-label="name" :filter="true" filter-by="name" :show-clear="true" placeholder="Select a Country" class="w-full">
|
|
||||||
<template #option="slotProps">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<img src="https://fqjltiegiezfetthbags.supabase.co/storage/v1/render/image/public/block.images/blocks/flag/flag_placeholder.png" :class="'mr-2 w-[18px]' + slotProps.option.code.toLowerCase()" />
|
|
||||||
<div>{{ slotProps.option.name }}</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider" />
|
|
||||||
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="city2">City</label>
|
|
||||||
<InputText id="city2" type="text" class="w-full" />
|
|
||||||
</div>
|
|
||||||
<div class="col-span-12 md:col-span-6">
|
|
||||||
<label for="state2">State</label>
|
|
||||||
<InputText id="state2" type="text" class="w-full" />
|
|
||||||
</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">
|
|
||||||
<label for="privacy2">Privacy</label>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<ToggleSwitch id="privacy2" v-model="checked" />
|
|
||||||
<span class="ml-2">Share my data with contacts</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider" />
|
|
||||||
|
|
||||||
<div class="col-span-12">
|
|
||||||
<Button label="Save Changes" class="w-auto mt-4" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Form>
|
|
||||||
</template>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,16 @@ export default defineConfig({
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
'/login': {
|
'/login': {
|
||||||
target: 'http://localhost:8000',
|
target: 'http://127.0.0.1:8000',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
secure: false,
|
secure: false,
|
||||||
// rewrite: (path) => path.replace(/^\/api/, '')
|
// rewrite: (path) => path.replace(/^\/api/, '')
|
||||||
},
|
},
|
||||||
|
'^/sticker/.*': {
|
||||||
|
target: 'http://127.0.0.1:8000',
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue