Intial Setup

This commit is contained in:
Stefan Hardegger
2025-07-21 08:47:52 +02:00
commit 68c7c8115f
20 changed files with 1276 additions and 0 deletions

13
frontend/Dockerfile Normal file
View File

@@ -0,0 +1,13 @@
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]

19
frontend/next.config.js Normal file
View File

@@ -0,0 +1,19 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
appDir: true,
},
async rewrites() {
return [
{
source: '/api/:path*',
destination: `${process.env.NEXT_PUBLIC_API_URL}/api/:path*`,
},
];
},
images: {
domains: ['localhost'],
},
};
module.exports = nextConfig;

32
frontend/package.json Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "storycove-frontend",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit"
},
"dependencies": {
"next": "14.0.0",
"react": "^18",
"react-dom": "^18",
"axios": "^1.6.0",
"dompurify": "^3.0.5",
"react-dropzone": "^14.2.3",
"tailwindcss": "^3.3.0",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@types/dompurify": "^3.0.5",
"eslint": "^8",
"eslint-config-next": "14.0.0"
}
}

View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -0,0 +1,34 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
font-family: Inter, system-ui, sans-serif;
}
}
@layer components {
.reading-content {
@apply max-w-reading mx-auto px-6 py-8;
font-family: Georgia, Times, serif;
line-height: 1.7;
}
.reading-content h1,
.reading-content h2,
.reading-content h3,
.reading-content h4,
.reading-content h5,
.reading-content h6 {
@apply font-bold mt-8 mb-4;
}
.reading-content p {
@apply mb-4;
}
.reading-content blockquote {
@apply border-l-4 border-gray-300 pl-4 italic my-6;
}
}

60
frontend/src/types/api.ts Normal file
View File

@@ -0,0 +1,60 @@
export interface Story {
id: string;
title: string;
authorId: string;
authorName: string;
contentHtml: string;
contentPlain: string;
sourceUrl?: string;
wordCount: number;
seriesId?: string;
seriesName?: string;
volume?: number;
rating?: number;
coverImagePath?: string;
tags: string[];
createdAt: string;
updatedAt: string;
}
export interface Author {
id: string;
name: string;
notes?: string;
authorRating?: number;
avatarImagePath?: string;
urls: AuthorUrl[];
stories: Story[];
createdAt: string;
updatedAt: string;
}
export interface AuthorUrl {
id: string;
url: string;
description?: string;
}
export interface Tag {
id: string;
name: string;
storyCount: number;
}
export interface Series {
id: string;
name: string;
storyCount: number;
}
export interface AuthResponse {
token: string;
expiresIn: number;
}
export interface SearchResult {
stories: Story[];
totalCount: number;
page: number;
totalPages: number;
}

View File

@@ -0,0 +1,21 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
fontFamily: {
serif: ['Georgia', 'Times', 'serif'],
sans: ['Inter', 'system-ui', 'sans-serif'],
},
maxWidth: {
'reading': '800px',
},
},
},
plugins: [],
darkMode: 'class',
};

28
frontend/tsconfig.json Normal file
View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}