Files
singlechat/server/feedback-store.js
Torsten Schulz (local) 47373a27af Enhance SEO and feedback features across the application
- Updated index.html with improved meta tags for SEO, including author and theme color.
- Added a feedback dialog in ImprintContainer.vue for user feedback submission.
- Refactored LoginForm.vue to utilize a utility for cookie management, simplifying profile persistence.
- Introduced new routes and schemas for feedback in the router and server, enhancing SEO and user experience.
- Improved ChatView.vue with better error handling and command table display.
- Implemented feedback API endpoints in server routes for managing user feedback submissions and admin access.

These changes collectively improve the application's SEO, user interaction, and feedback management capabilities.
2026-03-19 15:21:54 +01:00

56 lines
1.7 KiB
JavaScript

import crypto from 'crypto';
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { join } from 'path';
const FEEDBACK_FILE_NAME = 'feedback.json';
function ensureLogsDir(baseDir) {
const logsDir = join(baseDir, '../logs');
if (!existsSync(logsDir)) {
mkdirSync(logsDir, { recursive: true });
}
return logsDir;
}
function getFeedbackPath(baseDir) {
return join(ensureLogsDir(baseDir), FEEDBACK_FILE_NAME);
}
export function ensureFeedbackFile(baseDir) {
const feedbackPath = getFeedbackPath(baseDir);
if (!existsSync(feedbackPath)) {
writeFileSync(feedbackPath, '[]\n', 'utf-8');
}
}
export function loadFeedback(baseDir) {
ensureFeedbackFile(baseDir);
const feedbackPath = getFeedbackPath(baseDir);
const raw = readFileSync(feedbackPath, 'utf-8').trim();
if (!raw) return [];
try {
const parsed = JSON.parse(raw);
return Array.isArray(parsed) ? parsed : [];
} catch (error) {
throw new Error(`Ungültige ${FEEDBACK_FILE_NAME}: ${error.message}`);
}
}
export function saveFeedback(baseDir, items) {
const feedbackPath = getFeedbackPath(baseDir);
writeFileSync(feedbackPath, `${JSON.stringify(items, null, 2)}\n`, 'utf-8');
}
export function createFeedbackEntry(input) {
return {
id: crypto.randomUUID(),
createdAt: new Date().toISOString(),
name: typeof input.name === 'string' ? input.name.trim() : '',
age: Number.isFinite(input.age) ? input.age : null,
country: typeof input.country === 'string' ? input.country.trim() : '',
gender: typeof input.gender === 'string' ? input.gender.trim() : '',
comment: typeof input.comment === 'string' ? input.comment.trim() : ''
};
}