braindrops.nicwands.com/app/src/components/Panel.vue
2026-07-17 13:52:32 -04:00

132 lines
3 KiB
Vue

<template>
<div class="panel">
<div class="header">
<p class="label">Braindrops #{{ String(index + 1).padStart(2, '0') }}</p>
</div>
<div class="content">
<div v-if="drop.date" class="date meta-item label">
<span class="meta-value">{{ formattedDate }}</span>
</div>
<!-- <div v-if="drop.tags && drop.tags.length" class="tags">
<span v-for="tag in drop.tags" :key="tag" class="tag">{{ tag }}</span>
</div> -->
<h1 class="name h2">{{ displayTitle }}</h1>
<rich-text v-if="drop.description" class="description" :content="drop.description" />
</div>
<div class="btn-wrap">
<btn @click="emit('previous')" :disabled="!previousActive">Last Drop</btn>
<btn @click="emit('next')" :disabled="!nextActive">Next Drop</btn>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import Btn from '@shared/Btn.vue'
import RichText from '@shared/RichText.vue';
const props = defineProps({
drop: Object,
index: Number,
previousActive: Boolean,
nextActive: Boolean,
});
const emit = defineEmits(['previous', 'next'])
const displayTitle = computed(() => {
if (props.drop.title) return props.drop.title
// Fallback: format name as title
return props.drop.name
?.split('-')
?.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(' ')
})
const formattedDate = computed(() => {
if (!props.drop.date) return ''
const date = new Date(props.drop.date)
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
})
})
</script>
<style lang="scss">
.panel {
background: var(--theme-bg);
border-radius: rs(10px);
padding: var(--layout-margin);
grid-template-rows: auto 1fr auto;
display: grid;
gap: rs(30px);
.header {
text-align: center;
}
.content {
text-align: center;
display: flex;
flex-direction: column;
gap: rs(15px);
.name {
margin-bottom: rs(5px);
}
.description, .date {
color: var(--theme-grey);
}
.description {
text-align: left;
a {
word-break: break-word;
}
}
.meta-item {
font-size: rs(12px);
.meta-label {
opacity: 0.7;
margin-right: rs(8px);
}
.meta-value {
opacity: 0.9;
}
}
.tags {
display: flex;
flex-wrap: wrap;
gap: rs(8px);
justify-content: center;
.tag {
background: rgba(255, 255, 255, 0.1);
padding: rs(4px) rs(12px);
border-radius: rs(12px);
font-size: rs(11px);
text-transform: lowercase;
}
}
}
.btn-wrap {
grid-template-columns: 1fr 1fr;
gap: rs(10px);
display: grid;
.btn {
text-align: center;
}
}
}
</style>