feat: initial commit — site + admin panel + Postgres content pipeline

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
AyrisAI
2026-07-21 01:24:47 +03:00
co-authored by Claude Fable 5
commit 3420d32271
188 changed files with 25053 additions and 0 deletions
+164
View File
@@ -0,0 +1,164 @@
import fs from "node:fs";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { fileURLToPath } from "node:url";
import { dirname, resolve } from "node:path";
import Sitemap from "vite-plugin-sitemap";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
import tailwindcss from "@tailwindcss/vite";
import Components from "unplugin-vue-components/vite";
import { VitePWA } from "vite-plugin-pwa";
// Tip ve yardımcı okuma fonksiyonu
type PostEntry = { slug: string };
function safeReadJSON<T>(p: string): T | null {
try {
return JSON.parse(fs.readFileSync(p, "utf-8"));
} catch (e) {
console.warn(`[ssg] '${p}' okunamadı: ${(e as Error).message}`);
return null;
}
}
// Compute all static + menu routes (TR/EN) for SSG & sitemap
function computeRoutes(): string[] {
// Base routes (TR and EN)
const routes = new Set<string>([
"/",
"/menu/",
"/legal/",
"/en/",
"/en/menu/",
"/en/legal/",
]);
return Array.from(routes);
}
export default defineConfig({
plugins: [
vue(),
Sitemap({
hostname: "https://www.mucomutfak.com",
outDir: process.env.BUILD_OUT_DIR || "dist",
// Include ALL prerendered routes (from SSG) explicitly
dynamicRoutes: computeRoutes(),
generateRobotsTxt: true,
robots: [{ userAgent: "*", allow: "/" }],
// Produce a clean, human-readable XML and drop extra namespaces
readable: true,
xmlns: { news: false, xhtml: false, image: false, video: false },
}),
tailwindcss(),
Components({
dirs: ["src/components"],
extensions: ["vue"],
directoryAsNamespace: true,
collapseSamePrefixes: true,
globalNamespaces: ["global"],
dts: "./components.d.ts",
}),
VitePWA({
registerType: "autoUpdate",
includeAssets: [
"favicon.ico",
"apple-touch-icon.png",
"pwa-192x192.png",
"pwa-512x512.png",
"pwa-512x512-maskable.png",
],
manifest: {
name: "Müco Mutfak ve Kahve",
short_name: "Müco",
start_url: "/",
scope: "/",
display: "standalone",
background_color: "#ffffff",
theme_color: "#3FA0C7",
icons: [
{ src: "pwa-192x192.png", sizes: "192x192", type: "image/png" },
{ src: "pwa-512x512.png", sizes: "512x512", type: "image/png" },
{
src: "pwa-512x512-maskable.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
screenshots: [
{
src: "home-wide-1280x720.jpg",
sizes: "1280x720",
type: "image/jpeg",
form_factor: "wide",
},
{
src: "home-narrow-750x1334.jpg",
sizes: "750x1334",
type: "image/jpeg",
form_factor: "narrow",
},
],
},
workbox: {
cleanupOutdatedCaches: true,
skipWaiting: true,
clientsClaim: true,
globPatterns: [
"**/*.{html,js,txt,xml,webmanifest,css,gif,ico,png,svg,jpg,jpeg,webp,ttf,woff2}",
],
navigateFallback: null,
runtimeCaching: [
{
urlPattern: ({ request }) => request.mode === "navigate",
handler: "NetworkFirst",
options: {
cacheName: "pages",
networkTimeoutSeconds: 3,
expiration: {
maxEntries: 20,
maxAgeSeconds: 60,
},
},
},
{
urlPattern: ({ request }) =>
["image", "font"].includes(request.destination),
handler: "StaleWhileRevalidate",
options: {
cacheName: "assets-v2",
},
},
],
},
devOptions: {
enabled: false,
},
}),
],
build: {
chunkSizeWarningLimit: 1600,
// Publish pipeline builds into a staging dir, then swaps it into dist
outDir: process.env.BUILD_OUT_DIR || "dist",
},
server: {
host: true,
port: 5173,
proxy: {
"/api": "http://localhost:3001",
},
},
resolve: { alias: { "@": resolve(__dirname, "src") } },
ssgOptions: {
script: "async",
dirStyle: "nested",
formatting: "minify",
includedRoutes: computeRoutes,
},
});