add: OpenGraph image, timeline card state
Added three states to timeline card, added open graph image and description
This commit is contained in:
parent
f75d66a0d0
commit
d71e59b9c0
12 changed files with 112 additions and 34 deletions
|
@ -26,6 +26,10 @@
|
|||
.home-text {
|
||||
padding: var(--padding-xxl) var(--padding-default);
|
||||
text-align: center;
|
||||
|
||||
& h3:has(+ .padding) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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>()
|
||||
|
|
|
@ -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>()
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
BIN
public/img/og.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 384 KiB |
|
@ -1,4 +1,4 @@
|
|||
export type Card = {
|
||||
export type PriceCard = {
|
||||
uuid : string
|
||||
name : string
|
||||
price : string
|
11
shared/TimelineCard.ts
Normal file
11
shared/TimelineCard.ts
Normal 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
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue