add: OpenGraph image, timeline card state

Added three states to timeline card, added open graph image and description
This commit is contained in:
Fiona Lena Urban 2025-05-23 08:58:14 +02:00
parent f75d66a0d0
commit d71e59b9c0
12 changed files with 112 additions and 34 deletions

View file

@ -26,6 +26,10 @@
.home-text {
padding: var(--padding-xxl) var(--padding-default);
text-align: center;
& h3:has(+ .padding) {
margin-bottom: 0;
}
}
.timeline {

View file

@ -2,7 +2,7 @@
position: relative;
width: 100%;
color: var(--color-darkest);
border-bottom: 1px solid var(--color-light);
border-bottom: 1px dashed var(--color-light);
.bottom {
position: absolute;

View file

@ -6,7 +6,7 @@
border-radius: var(--radius-default);
padding: var(--padding-xs);
& .icon {
& > .icon {
flex: 0 0 25%;
font-size: var(--font-size-xxl);
color: var(--color-main-dark);
@ -16,4 +16,13 @@
text-align: left;
flex-grow: 1;
}
& .state {
--color: var(--color-darkest);
display: flex;
align-items: center;
gap: var(--padding-xxs);
margin-top: var(--padding-s);
color: var(--color);
}
}

View file

@ -58,11 +58,11 @@
</template>
<script setup lang="ts">
import type { Card } from '../../../shared/Card'
import type { PriceCard } from '../../../shared/PriceCard'
type Props = {
deletable: boolean
card: Card
card: PriceCard
}
const { card } = defineProps<Props>()

View file

@ -86,11 +86,11 @@
</template>
<script setup lang="ts">
import type { Card } from '../../../shared/Card'
import type { PriceCard } from '../../../shared/PriceCard'
type Props = {
currentCardIndex: number
currentCard?: Card
currentCard?: PriceCard
}
const { currentCardIndex, currentCard } = defineProps<Props>()

View file

@ -4,16 +4,48 @@
<div class="text">
<strong>{{ title }}</strong>
<p>{{ description }}</p>
<div class="state" :style="{
'--color': stateColor,
}">
<Icon :name="stateIcon" mode="svg" />
<span>{{ stateMessage }}</span>
</div>
</div>
</article>
</template>
<script setup lang="ts">
type Props = {
icon: string
title: string
description: string
import type { TimelineCard, TimelineState } from '../../../shared/TimelineCard'
const { state } = defineProps<TimelineCard>()
const icons : Record<TimelineState, string> = {
planned: 'uil:clock',
inProgress: 'uil:cog',
done: 'uil:check-circle'
}
defineProps<Props>()
const colors : Record<TimelineState, string> = {
planned: 'var(--color-darkest)',
inProgress: 'var(--color-main-dark)',
done: 'var(--color-accent-darkest)',
}
const stateColor = computed(() => colors[state.value])
const stateIcon = computed(() => icons[state.value])
const stateMessage = computed(() => {
switch (state.value) {
case 'planned':
let planned = 'Geplant'
if (state.message) planned += ` für ${state.message}`
return planned
case 'inProgress':
return 'In Bearbeitung'
case 'done':
let done = 'Abgeschlossen'
if (state.message) done += ` am ${state.message}`
return done
}
})
</script>

View file

@ -13,15 +13,18 @@
</h2>
</div>
</div>
<div class="home-text padding ">
<div class="home-text padding">
<p>
Mit <strong>ProPapier</strong> vergleichst du schnell & unkompliziert Preise für Klopapier und sparst so bares Geld.
</p>
</div>
<div class="home-text padding ">
<div class="home-text padding">
<h3>
Wir haben noch viel vor!
</h3>
<p class="padding">
Für ProPapier sind über die nächste Zeit noch einige weitere Features geplant.
</p>
<div class="timeline">
<PpTimelineCard
v-for="card in timeline"
@ -33,46 +36,62 @@
</template>
<script setup lang="ts">
import type { TimelineCard } from '../../shared/TimelineCard'
definePageMeta({
layout: 'landingpage'
})
type Card = {
icon: string
title: string
description: string
}
const timeline : Card[] = [
const timeline : TimelineCard[] = [
{
icon: 'uil:chart-bar',
title: 'Mehr Vergleiche',
description: 'Zusätzliche Kategorien für Taschentücher und Küchenrolle',
state: {
value: 'inProgress',
}
},
{
icon: 'uil:cloud-database-tree',
title: 'Datenbank',
description: 'Eine von der Community gestützte Datenbank mit Preisen für alle Produkte'
description: 'Eine von der Community gestützte Datenbank mit Preisen für alle Produkte',
state: {
value: 'planned',
message: '2025',
}
},
{
icon: 'uil:qrcode-scan',
title: 'Barcode Scan',
description: 'Ganz einfach Barcode Scannen und Produkt direkt zum Rechner hinzufügen'
description: 'Ganz einfach Barcode Scannen und Produkt direkt zum Rechner hinzufügen',
state: {
value: 'planned',
message: '2025',
}
},
{
icon: 'uil:user',
title: 'Optionale Accounts',
description: 'Zur Synchronisierung auf mehreren Geräten'
description: 'Zur Synchronisierung auf mehreren Geräten',
state: {
value: 'planned',
}
},
{
icon: 'uil:cog',
title: 'Personalisierung',
description: 'Persönliche Präferenzen zur Wortwahl, Standardsortierung und mehr'
description: 'Persönliche Präferenzen zur Wortwahl, Standardsortierung und mehr',
state: {
value: 'planned',
}
},
{
icon: 'uil:vector-square',
title: 'm² Preise',
description: 'Quadratmeterpreise für noch genauere Vergleiche'
description: 'Quadratmeterpreise für noch genauere Vergleiche',
state: {
value: 'planned',
}
},
]
</script>

View file

@ -46,19 +46,19 @@
</template>
<script setup lang="ts">
import type { Card } from '../../shared/Card'
import type { PriceCard } from '../../shared/PriceCard'
import type { Button } from '../../shared/ButtonGroup'
import { PpPriceCardDialog, PpDeleteDialog, PpPriceCard } from '#components'
const cards = useLocalStorage<Card[]>('cards', [])
const cards = useLocalStorage<PriceCard[]>('cards', [])
const currentSort = useLocalStorage<number>('sort', 0)
const currentCard = ref<Card>()
const currentCard = ref<PriceCard>()
const currentCardIndex = ref<number>(-1)
const modal = useTemplateRef<typeof PpPriceCardDialog>('modal')
const deleteModal = useTemplateRef<typeof PpDeleteDialog>('deleteModal')
const priceCards = useTemplateRef<(typeof PpPriceCard)[]>('priceCard')
const createCard = (uuid : string) : Card => ({
const createCard = (uuid : string) : PriceCard => ({
uuid,
name: '',
price: '',
@ -68,7 +68,7 @@ const createCard = (uuid : string) : Card => ({
})
const addCard = (card : Card) => {
const addCard = (card : PriceCard) => {
cards.value.unshift({ ...card })
sort()
}

View file

@ -1,4 +1,6 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
const description = 'Bezahlt du zuviel fürs Papier? Vergleiche schnell und unkompliziert die Preise für Toiletten-, Küchen- und andere Papier hier.'
export default defineNuxtConfig({
compatibilityDate: '2024-11-01',
devtools: { enabled: false },
@ -73,7 +75,7 @@ export default defineNuxtConfig({
seo: {
meta: {
title: 'ProPapier',
description: '"Bezahlt du zuviel fürs Papier? Vergleiche schnell und unkompliziert die Preise für Toiletten-, Küchen- und andere Papier hier."',
description,
themeColor: [
{ content: '#18181b', media: '(prefers-color-scheme: dark)' },
{ content: 'white', media: '(prefers-color-scheme: light)' },
@ -90,9 +92,10 @@ export default defineNuxtConfig({
ogType: 'website',
ogUrl: 'https://pro-papier.de',
ogTitle: 'ProPapier',
ogDescription: description,
// Other Nuxt SEO modules handles these
ogImage: 'https://example.com/my-og-image.png',
ogImage: '/img/og.png',
robots: 'index, follow',
}
},

BIN
public/img/og.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

View file

@ -1,4 +1,4 @@
export type Card = {
export type PriceCard = {
uuid : string
name : string
price : string

11
shared/TimelineCard.ts Normal file
View file

@ -0,0 +1,11 @@
export type TimelineState = 'planned' | 'inProgress' | 'done'
export type TimelineCard = {
icon: string
title: string
description: string
state: {
value: TimelineState
message ?: string
}
}