feat: FAQ management from admin, public /faq, homepage section, llms.txt

- Backend: faq_questions table (schema + migration), CRUD + reorder API, Swagger docs
- Admin: FAQ page with create/edit, enable/disable, show on homepage, drag reorder
- Public /faq page fetches enabled FAQs from API; layout builds dynamic JSON-LD
- Homepage: FAQ section under Stay updated (homepage-enabled only) with See full FAQ link
- llms.txt: FAQ section uses homepage FAQs from API
- i18n: home.faq title/seeFull, admin FAQ nav

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Michilis
2026-02-12 04:49:16 +00:00
parent 5885044369
commit 07ba357194
15 changed files with 1137 additions and 149 deletions

View File

@@ -1078,3 +1078,71 @@ export const legalPagesApi = {
method: 'POST',
}),
};
// ==================== FAQ Types ====================
export interface FaqItem {
id: string;
question: string;
questionEs?: string | null;
answer: string;
answerEs?: string | null;
rank?: number;
}
export interface FaqItemAdmin extends FaqItem {
enabled: boolean;
showOnHomepage: boolean;
createdAt: string;
updatedAt: string;
}
// ==================== FAQ API ====================
export const faqApi = {
// Public
getList: (homepageOnly?: boolean) =>
fetchApi<{ faqs: FaqItem[] }>(`/api/faq${homepageOnly ? '?homepage=true' : ''}`),
// Admin
getAdminList: () =>
fetchApi<{ faqs: FaqItemAdmin[] }>('/api/faq/admin/list'),
getById: (id: string) =>
fetchApi<{ faq: FaqItemAdmin }>(`/api/faq/admin/${id}`),
create: (data: {
question: string;
questionEs?: string;
answer: string;
answerEs?: string;
enabled?: boolean;
showOnHomepage?: boolean;
}) =>
fetchApi<{ faq: FaqItemAdmin }>('/api/faq/admin', {
method: 'POST',
body: JSON.stringify(data),
}),
update: (id: string, data: {
question?: string;
questionEs?: string | null;
answer?: string;
answerEs?: string | null;
enabled?: boolean;
showOnHomepage?: boolean;
}) =>
fetchApi<{ faq: FaqItemAdmin }>(`/api/faq/admin/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
}),
delete: (id: string) =>
fetchApi<{ message: string }>(`/api/faq/admin/${id}`, { method: 'DELETE' }),
reorder: (ids: string[]) =>
fetchApi<{ faqs: FaqItemAdmin[] }>('/api/faq/admin/reorder', {
method: 'POST',
body: JSON.stringify({ ids }),
}),
};