store raffles, wheel of fortune

main
Norman Köhring 1 year ago
parent 1645b3be50
commit fd3ac2c9fc

@ -3,12 +3,12 @@
@tailwind utilities;
body {
@apply min-h-screen bg-slate-900 text-slate-100 leading-relaxed;
@apply min-h-screen m-0 p-0 bg-slate-900 text-slate-100 leading-relaxed;
transition: color 0.3s, background-color 0.2s;
}
#app {
@apply flex justify-around items-center w-screen min-h-screen m-0 p-4;
@apply flex justify-around items-center w-screen min-h-screen;
}
button, input {

@ -11,6 +11,7 @@ export default function useRaffle() {
const raffleStore = useStorage<Raffle[]>('', EMPTY_STORE)
const newRaffle = ref<Raffle>({
id: genId(),
title: '',
date: new Date().toLocaleDateString('de'),
participants: [],

@ -1,5 +1,6 @@
<script setup lang="ts">
import { useHead } from '@vueuse/head'
import { useRouter } from 'vue-router'
import useRaffle from '../composables/useRaffle'
useHead({
@ -19,13 +20,27 @@ const showNewRaffleForm = $ref(false)
function startRaffle() {
if (!readyToRaffle) return
//
raffleStore.value.push(newRaffle.value)
const router = useRouter()
router.push(`/raffle/${newRaffle.value.id}`)
}
</script>
<template>
<header>
<h1 class="text-4xl">Raffle Me That!</h1>
<div class="mt-8" v-if="raffleStore.length">
<strong>Select Existing:</strong>
<ul>
<li v-for="raffle in raffleStore">
<router-link :to="`/raffle/${raffle.id}`">
{{ raffle.title }}
</router-link>
</li>
</ul>
</div>
</header>
<main>

@ -1,6 +1,111 @@
<script setup lang="ts">
import { onMounted } from 'vue'
import { useHead } from '@vueuse/head'
useHead({
title: 'Lets go!',
import { useStorage } from '@vueuse/core'
import { useRoute } from 'vue-router'
const route = useRoute()
const raffleId = route.params.id as string
const raffleStore = useStorage<Raffle[]>('', [])
const raffle = raffleStore.value.find(r => r.id === raffleId)
const participants = $computed(() => {
return raffle ? raffle.participants : []
})
const amount = $computed(() => participants.length)
let aligned = $ref(false) // used for animation
function degrees(index: number) {
if (!aligned) return 0
return (360 / amount) * index
}
useHead({ title: raffle ? raffle.title : 'Lets Go' })
onMounted(() => {
setTimeout(() => {
aligned = true
}, 100)
})
</script>
<template>
<div class="relative w-screen h-screen overflow-hidden flex justify-end items-center">
<ol class="absolute top-0 -left-1/2 w-screen h-screen transition-transform duration-500 ease-in" :class="aligned ? 'aligned' : 'shifted'">
<li v-for="(participant, i) in participants"
class="slice"
:style="`
transform: rotate(${degrees(i)}deg);
`"
>
<div>
{{ participant }}bcdef ghijklmn
</div>
</li>
<div class="absolute top-1/2 left-1/2 w-32 h-32 -ml-16 -mt-16 rounded-full bg-black"></div>
</ol>
</div>
</template>
<style scoped>
.shifted {
transform: translateX(-100%);
}
.aligned {
transform: translateX(0);
}
.slice {
--w: 50vw;
--h: calc(6.283185307179586 * var(--w) / v-bind(amount));
position: absolute;
width: var(--w);
height: var(--h);
left: 50%;
top: 28%;
padding: 0;
text-align: right;
transform-origin: left center;
transition: transform 1s ease-out .4s;
color: white;
font-weight: bold;
font-size: 2em;
}
.slice:nth-child(even) {
color: black;
}
.slice::before, .slice::after {
content: '';
display: block;
width: 0;
height: 0;
border-style: solid;
}
.slice::before {
margin-bottom: -1px;
border-width: 0 0 calc(var(--h) / 2) calc(var(--w) * .97);
border-color: transparent transparent #0074D9 transparent;
}
.slice:nth-child(even)::before {
border-color: transparent transparent #2ECC40 transparent;
}
.slice::after {
border-width: 0 calc(var(--w) * .97) calc(var(--h) / 2) 0;
border-color: transparent #0074D9 transparent transparent;
}
.slice:nth-child(even)::after {
border-color: transparent #2ECC40 transparent transparent;
}
.slice > div {
position: absolute;
top: 0;
bottom: 0;
display: flex;
justify-content: flex-end;
align-items: center;
width: 85%;
height: 100%;
}
</style>

1
src/types.d.ts vendored

@ -1,5 +1,6 @@
declare global {
type Raffle = {
id: string
title: string
date: string
participants: string[]

Loading…
Cancel
Save