aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/Button.vue71
-rw-r--r--components/Nav.vue4
-rw-r--r--components/Panel.vue29
-rw-r--r--components/Sidebar.vue43
4 files changed, 112 insertions, 35 deletions
diff --git a/components/Button.vue b/components/Button.vue
index 00cc1e7..97ff928 100644
--- a/components/Button.vue
+++ b/components/Button.vue
@@ -1,9 +1,33 @@
-<script setup>
+<script setup lang="ts">
import { Loader2Icon } from 'lucide-vue-next'
+import { defineProps } from 'vue';
+
+defineProps({
+ isLoading: {
+ type: Boolean,
+ default: false,
+ },
+ disabled: {
+ type: Boolean,
+ default: false
+ },
+ loading: {
+ type: Boolean,
+ default: false
+ },
+ type: {
+ type: String as PropType<"button" | "submit" | "reset">,
+ default: "",
+ },
+ kind: {
+ type: String as PropType<"primary" | "secondary">,
+ default: "primary",
+ },
+});
</script>
<template>
- <button :type="type" :disabled="disabled || loading">
+ <button :type="type" :disabled="disabled || loading" :class="kind">
<Loader2Icon v-if="loading" class="icon-loader" />
<span>
<slot />
@@ -11,30 +35,6 @@ import { Loader2Icon } from 'lucide-vue-next'
</button>
</template>
-<script>
-export default {
- name: "Button",
- props: {
- isLoading: {
- type: Boolean,
- default: false,
- },
- disabled: {
- type: Boolean,
- default: false
- },
- loading: {
- type: Boolean,
- default: false
- },
- type: {
- type: String,
- default: "",
- },
- },
-};
-</script>
-
<style scoped>
button {
width: 100%;
@@ -43,12 +43,10 @@ button {
padding: 0.5rem 1rem;
border: 1px solid transparent;
border-radius: 0.375rem;
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
font-size: var(--text-small);
font-family: var(--font-family);
font-weight: 500;
color: white;
- background-color: var(--color-primary);
cursor: pointer;
transition: background-color 0.2s ease;
}
@@ -60,7 +58,6 @@ button:hover {
button:focus {
outline: none;
border-color: var(--color-accent);
- box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.4);
}
button:disabled {
@@ -76,6 +73,22 @@ button:disabled {
width: 1.25rem;
color: white;
}
+
+button.primary {
+ background-color: var(--color-primary);
+}
+
+button.secondary {
+ background-color: var(--color-background);
+ border: 1px solid var(--color-primary);
+ color: var(--color-primary);
+}
+
+button.secondary:hover {
+ background-color: var(--color-background-muted);
+ border: 1px solid var(--color-primary-dark);
+ color: var(--color-primary-dark);
+}
@keyframes spin {
0% {
diff --git a/components/Nav.vue b/components/Nav.vue
index 6ab4c9f..06a0295 100644
--- a/components/Nav.vue
+++ b/components/Nav.vue
@@ -48,7 +48,7 @@ route.afterEach(() => {
display: flex;
align-items: center;
gap: 0.5rem;
- color: var(--color-text-muted);
+ color: var(--color-accent);
padding: 0.4rem 1rem;
left: -1rem;
width: calc(100%);
@@ -56,7 +56,7 @@ route.afterEach(() => {
}
.nav-list > li.active > a {
- color: var(--color-text);
+ color: var(--color-primary);
font-weight: 600;
background-color: var(--color-background-muted);
}
diff --git a/components/Panel.vue b/components/Panel.vue
index 007d2b6..8e72414 100644
--- a/components/Panel.vue
+++ b/components/Panel.vue
@@ -1,15 +1,38 @@
+<script setup lang="ts">
+import { defineProps, type PropType } from 'vue';
+
+defineProps({
+ kind: {
+ type: String as PropType<"normal" | "error" | "success">,
+ required: false,
+ default: 'normal',
+ },
+});
+</script>
<template>
- <div class="card">
+ <div class="card" :class="kind">
<slot />
</div>
</template>
<style>
.card {
- background-color: white;
padding: 1rem;
border-radius: 0.5rem;
- /* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06); */
+}
+
+.normal {
+ background-color: white;
border: 0.1rem solid var(--color-border);
}
+
+.error {
+ background-color: var(--color-error);
+ border: 0.1rem solid var(--color-border-error);
+}
+
+.success {
+ background-color: var(--color-success);
+ border: 0.1rem solid var(--color-border-success);
+}
</style> \ No newline at end of file
diff --git a/components/Sidebar.vue b/components/Sidebar.vue
index 755f200..9366696 100644
--- a/components/Sidebar.vue
+++ b/components/Sidebar.vue
@@ -1,5 +1,21 @@
<script setup lang="ts">
+import { formatDistanceToNow } from "date-fns";
+import { LucideClock, LucideRadio } from "lucide-vue-next";
+
const scheduleStore = useScheduleStore();
+const errorStore = useErrorStore();
+
+const timeUntilConferenceStart = computed(() => {
+ if (!scheduleStore.schedule) {
+ return 0;
+ }
+
+ const now = new Date();
+ const conferenceStart = new Date(scheduleStore.schedule.conference.start);
+ const diff = conferenceStart.getTime() - now.getTime();
+
+ return diff;
+});
</script>
<template>
@@ -8,6 +24,21 @@ const scheduleStore = useScheduleStore();
<span class="conference-title">{{ scheduleStore.schedule?.conference.title }}</span>
<span class="conference-venue">{{ scheduleStore.schedule?.conference.venue }}</span>
<span class="conference-city">{{ scheduleStore.schedule?.conference.city }}</span>
+
+ <Button kind="secondary" @click="errorStore.setError('This doesn\'t do anything yet :-)')">Change conference</Button>
+ </Panel>
+
+ <Panel kind="success" class="ongoing" v-if="scheduleStore.isConferenceOngoing()">
+ <span class="text-icon"><LucideRadio size="var(--text-small)"/> <span>This conference is ongoing</span></span>
+ <Button kind="primary" @click="navigateTo('/live')">View live</Button>
+ </Panel>
+
+ <Panel kind="error" class="finished" v-else-if="scheduleStore.isConferenceFinished()">
+ <span>This conference has finished</span>
+ </Panel>
+
+ <Panel class="upcoming" v-else>
+ <span class="text-icon"><LucideClock size="var(--text-small)" /> <span>Starts in {{ formatDistanceToNow(scheduleStore.getStartDate()) }}</span></span>
</Panel>
<Nav />
@@ -18,13 +49,23 @@ const scheduleStore = useScheduleStore();
</div>
</template>
-<style>
+<style scoped>
.sidebar {
display: flex;
flex-direction: column;
gap: 1rem;
}
+.finished, .ongoing, .upcoming {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1rem;
+ font-size: var(--text-small);
+ font-style: oblique;
+ text-align: center;
+}
+
.conference {
display: flex;
flex-direction: column;