201 lines
6.1 KiB
Vue
201 lines
6.1 KiB
Vue
<script setup>
|
|
import { computed } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { useRoute } from 'vue-router';
|
|
import LandingSiteMenu from '@/features/landing/components/LandingSiteMenu.vue';
|
|
import { getProductFeature, productFeatureItems } from '@/features/landing/productFeatures.js';
|
|
import { usePublicPageMeta } from '@/features/landing/publicPageMeta.js';
|
|
|
|
const route = useRoute();
|
|
const { t } = useI18n();
|
|
|
|
const feature = computed(() => getProductFeature(route.params.featureSlug));
|
|
const featurePath = computed(() => `/product/${feature.value.slug}`);
|
|
const relatedFeatures = computed(() =>
|
|
productFeatureItems.filter(item => item.slug !== feature.value.slug).slice(0, 3)
|
|
);
|
|
const bullets = computed(() =>
|
|
[0, 1, 2].map(index => t(`public.features.${feature.value.slug}.bullets.${index}`))
|
|
);
|
|
|
|
usePublicPageMeta({
|
|
title: computed(() => `${t(`public.features.${feature.value.slug}.title`)} | Socialize`),
|
|
description: computed(() => t(`public.features.${feature.value.slug}.description`)),
|
|
path: featurePath,
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="public-page">
|
|
<LandingSiteMenu />
|
|
|
|
<main class="feature-page-content">
|
|
<section class="feature-hero">
|
|
<span class="feature-icon">
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
aria-hidden="true"
|
|
>
|
|
<path :d="feature.icon" />
|
|
</svg>
|
|
</span>
|
|
<div class="eyebrow">{{ t('public.product.eyebrow') }}</div>
|
|
<h1>{{ t(`public.features.${feature.slug}.detailTitle`) }}</h1>
|
|
<p>{{ t(`public.features.${feature.slug}.detailDescription`) }}</p>
|
|
</section>
|
|
|
|
<section class="feature-detail-panel">
|
|
<div class="eyebrow">{{ t('public.product.featureEyebrow') }}</div>
|
|
<ul>
|
|
<li
|
|
v-for="bullet in bullets"
|
|
:key="bullet"
|
|
>
|
|
<span aria-hidden="true">✓</span>
|
|
<strong>{{ bullet }}</strong>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
|
|
<section class="related-features">
|
|
<div>
|
|
<div class="eyebrow">{{ t('public.product.featureEyebrow') }}</div>
|
|
<h2>{{ t('public.product.featureTitle') }}</h2>
|
|
</div>
|
|
<div class="related-grid">
|
|
<router-link
|
|
v-for="item in relatedFeatures"
|
|
:key="item.slug"
|
|
class="related-card"
|
|
:to="`/product/${item.slug}`"
|
|
>
|
|
<span class="related-icon">
|
|
<svg
|
|
viewBox="0 0 24 24"
|
|
aria-hidden="true"
|
|
>
|
|
<path :d="item.icon" />
|
|
</svg>
|
|
</span>
|
|
<strong>{{ t(`public.features.${item.slug}.title`) }}</strong>
|
|
<span>{{ t(`public.features.${item.slug}.description`) }}</span>
|
|
</router-link>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.public-page {
|
|
@apply min-h-screen w-full;
|
|
}
|
|
|
|
.feature-page-content {
|
|
@apply mx-auto flex w-full max-w-7xl flex-col gap-8 px-5 py-8 md:px-8 md:py-12;
|
|
}
|
|
|
|
.feature-hero {
|
|
@apply rounded-[2rem] p-6 md:p-10;
|
|
background: rgba(255, 255, 255, 0.84);
|
|
border: 1px solid rgba(23, 32, 51, 0.08);
|
|
box-shadow: 0 18px 40px rgba(23, 32, 51, 0.06);
|
|
}
|
|
|
|
.feature-icon,
|
|
.related-icon {
|
|
@apply flex h-12 w-12 items-center justify-center rounded-[0.9rem];
|
|
background: rgba(15, 118, 110, 0.1);
|
|
color: #0f766e;
|
|
}
|
|
|
|
.feature-icon svg,
|
|
.related-icon svg {
|
|
@apply h-5 w-5;
|
|
fill: currentColor;
|
|
}
|
|
|
|
.eyebrow {
|
|
@apply mt-5 text-xs font-bold uppercase tracking-[0.26em];
|
|
color: #ff8a3d;
|
|
}
|
|
|
|
h1 {
|
|
@apply mt-4 max-w-4xl text-4xl font-black leading-tight md:text-6xl;
|
|
color: #172033;
|
|
}
|
|
|
|
p {
|
|
@apply mt-5 max-w-3xl text-base leading-7 md:text-lg;
|
|
color: #44516a;
|
|
}
|
|
|
|
.related-grid {
|
|
@apply grid gap-4 md:grid-cols-3;
|
|
}
|
|
|
|
.related-card {
|
|
@apply rounded-[1.25rem] border bg-white/80 p-5;
|
|
border-color: rgba(23, 32, 51, 0.08);
|
|
box-shadow: 0 18px 40px rgba(23, 32, 51, 0.05);
|
|
}
|
|
|
|
.feature-detail-panel {
|
|
@apply rounded-[1.5rem] border bg-white/80 p-5 md:p-7;
|
|
border-color: rgba(23, 32, 51, 0.08);
|
|
box-shadow: 0 18px 40px rgba(23, 32, 51, 0.05);
|
|
}
|
|
|
|
.feature-detail-panel .eyebrow {
|
|
@apply mt-0;
|
|
}
|
|
|
|
.feature-detail-panel ul {
|
|
@apply mt-5 grid gap-3;
|
|
}
|
|
|
|
.feature-detail-panel li {
|
|
@apply grid grid-cols-[2rem_1fr] items-start gap-3 rounded-[1rem] p-4;
|
|
background: rgba(15, 118, 110, 0.08);
|
|
}
|
|
|
|
.feature-detail-panel li span {
|
|
@apply flex h-8 w-8 items-center justify-center rounded-full text-sm font-black;
|
|
background: #0f766e;
|
|
color: #fffaf2;
|
|
}
|
|
|
|
.feature-detail-panel li strong {
|
|
@apply pt-1 text-base font-semibold leading-7;
|
|
color: #172033;
|
|
}
|
|
|
|
.related-features {
|
|
@apply flex flex-col gap-5;
|
|
}
|
|
|
|
.related-features h2 {
|
|
@apply mt-3 max-w-3xl text-2xl font-black leading-tight md:text-3xl;
|
|
color: #172033;
|
|
}
|
|
|
|
.related-card {
|
|
@apply flex min-h-48 flex-col gap-3 no-underline transition-colors;
|
|
}
|
|
|
|
.related-card:hover {
|
|
background: #fff;
|
|
border-color: rgba(15, 118, 110, 0.28);
|
|
}
|
|
|
|
.related-card strong {
|
|
@apply text-base font-black;
|
|
color: #172033;
|
|
}
|
|
|
|
.related-card span:last-child {
|
|
@apply text-sm leading-6;
|
|
color: #44516a;
|
|
}
|
|
</style>
|