[FEAT] Add FAQ
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
<router-link to="/blog" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Read our blog posts" aria-label="Navigate to blog">Blog</router-link>
|
<router-link to="/blog" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Read our blog posts" aria-label="Navigate to blog">Blog</router-link>
|
||||||
<router-link to="/about" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Learn more about us" aria-label="Navigate to about page">About Us</router-link>
|
<router-link to="/about" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Learn more about us" aria-label="Navigate to about page">About Us</router-link>
|
||||||
<router-link to="/contact" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Get in touch with us" aria-label="Navigate to contact page">Contact</router-link>
|
<router-link to="/contact" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Get in touch with us" aria-label="Navigate to contact page">Contact</router-link>
|
||||||
|
<router-link to="/faq" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Frequently Asked Questions" aria-label="Navigate to FAQ page">FAQ</router-link>
|
||||||
<router-link to="/privacy-policy" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Read our privacy policy" aria-label="Navigate to privacy policy">Privacy Policy</router-link>
|
<router-link to="/privacy-policy" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="Read our privacy policy" aria-label="Navigate to privacy policy">Privacy Policy</router-link>
|
||||||
<a href="/sitemap.xml" target="_blank" rel="noopener noreferrer" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="View XML sitemap" aria-label="View sitemap">Sitemap</a>
|
<a href="/sitemap.xml" target="_blank" rel="noopener noreferrer" class="hover:text-gray-900 dark:hover:text-white transition-colors" title="View XML sitemap" aria-label="View sitemap">Sitemap</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ export interface BreadcrumbItem {
|
|||||||
url: string;
|
url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FAQItem {
|
||||||
|
question: string;
|
||||||
|
answer: string;
|
||||||
|
}
|
||||||
|
|
||||||
export function useStructuredData() {
|
export function useStructuredData() {
|
||||||
// Organization Schema
|
// Organization Schema
|
||||||
const addOrganizationSchema = () => {
|
const addOrganizationSchema = () => {
|
||||||
@@ -159,11 +164,37 @@ export function useStructuredData() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FAQ Schema
|
||||||
|
const addFAQSchema = (faqs: FAQItem[]) => {
|
||||||
|
const schema = {
|
||||||
|
'@context': 'https://schema.org',
|
||||||
|
'@type': 'FAQPage',
|
||||||
|
mainEntity: faqs.map(faq => ({
|
||||||
|
'@type': 'Question',
|
||||||
|
name: faq.question,
|
||||||
|
acceptedAnswer: {
|
||||||
|
'@type': 'Answer',
|
||||||
|
text: faq.answer,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
script: [
|
||||||
|
{
|
||||||
|
type: 'application/ld+json',
|
||||||
|
children: JSON.stringify(schema),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addOrganizationSchema,
|
addOrganizationSchema,
|
||||||
addWebSiteSchema,
|
addWebSiteSchema,
|
||||||
addBlogPostSchema,
|
addBlogPostSchema,
|
||||||
addBreadcrumbSchema,
|
addBreadcrumbSchema,
|
||||||
addBlogListSchema,
|
addBlogListSchema,
|
||||||
|
addFAQSchema,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ const router = createRouter({
|
|||||||
name: 'privacy-policy',
|
name: 'privacy-policy',
|
||||||
component: () => import('../views/PrivacyPolicy.vue'),
|
component: () => import('../views/PrivacyPolicy.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/faq',
|
||||||
|
name: 'faq',
|
||||||
|
component: () => import('../views/FAQ.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/blog',
|
path: '/blog',
|
||||||
name: 'blog-overview',
|
name: 'blog-overview',
|
||||||
|
|||||||
80
src/views/FAQ.vue
Normal file
80
src/views/FAQ.vue
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useSEO } from '../composables/useSEO';
|
||||||
|
import { useStructuredData } from '../composables/useStructuredData';
|
||||||
|
|
||||||
|
const { addFAQSchema, addBreadcrumbSchema } = useStructuredData();
|
||||||
|
|
||||||
|
// Set SEO synchronously
|
||||||
|
useSEO({
|
||||||
|
title: 'FAQ - Frequently Asked Questions',
|
||||||
|
description: 'Find answers to common questions about the Spritesheet Generator. Learn about supported formats, export options, and how to use the tool effectively.',
|
||||||
|
url: '/faq',
|
||||||
|
type: 'website',
|
||||||
|
keywords: 'faq, spritesheet generator help, questions, support, documentation',
|
||||||
|
});
|
||||||
|
|
||||||
|
addBreadcrumbSchema([
|
||||||
|
{ name: 'Home', url: '/' },
|
||||||
|
{ name: 'FAQ', url: '/faq' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{
|
||||||
|
question: 'What is a spritesheet?',
|
||||||
|
answer: 'A spritesheet is a single image file that contains multiple smaller images (sprites) arranged in a grid or packed layout. It is commonly used in game development to reduce memory usage and improve performance by reducing the number of draw calls.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Is this tool free to use?',
|
||||||
|
answer: 'Yes, this Spritesheet Generator is completely free and open-source. You can use it for personal and commercial projects without any restrictions.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'What image formats are supported?',
|
||||||
|
answer: 'We support importing common image formats including PNG, JPG, GIF, and WEBP. You can drag and drop multiple files at once to generate your spritesheet.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'How do I export my spritesheet?',
|
||||||
|
answer: 'Once you have arranged your sprites, click the "Export" button. You can choose to download the spritesheet image (PNG) and the accompanying data file (JSON/CSS) that describes the sprite positions.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: 'Can I contribute to the project?',
|
||||||
|
answer: 'Absolutely! The project is open-source. You can find the source code on our Gitea repository and contribute by reporting bugs, suggesting features, or submitting pull requests.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
addFAQSchema(faqs);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-full">
|
||||||
|
<div class="bg-white/80 dark:bg-gray-900/80 backdrop-blur-md rounded-3xl shadow-2xl border border-gray-200/50 dark:border-gray-700/50 p-8 sm:p-12">
|
||||||
|
<h1 class="text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-white mb-6">Frequently Asked Questions</h1>
|
||||||
|
<p class="text-gray-700 dark:text-gray-300 leading-relaxed mb-10">
|
||||||
|
Got questions? We've got answers. If you can't find what you're looking for, feel free to <router-link to="/contact" class="text-blue-600 dark:text-blue-400 hover:underline">contact us</router-link>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="space-y-6">
|
||||||
|
<details v-for="(faq, index) in faqs" :key="index" class="group bg-gray-50 dark:bg-gray-800/50 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden transition-all duration-300 hover:shadow-md open:bg-white dark:open:bg-gray-800 open:shadow-lg open:border-blue-200 dark:open:border-blue-900">
|
||||||
|
<summary class="flex items-center justify-between p-6 cursor-pointer list-none">
|
||||||
|
<h3 class="text-lg font-bold text-gray-900 dark:text-white pr-4">{{ faq.question }}</h3>
|
||||||
|
<span class="transform transition-transform duration-300 group-open:rotate-180 text-gray-500 dark:text-gray-400">
|
||||||
|
<i class="fas fa-chevron-down"></i>
|
||||||
|
</span>
|
||||||
|
</summary>
|
||||||
|
<div class="px-6 pb-6 text-gray-700 dark:text-gray-300 leading-relaxed border-t border-gray-100 dark:border-gray-700/50 pt-4">
|
||||||
|
{{ faq.answer }}
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* Remove default triangle for details/summary */
|
||||||
|
details > summary {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
details > summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user