feat: add SPA, serve at /app/, update Dockerfile and README

- React + TanStack Router + shadcn/ui SPA under spa/
- serve spa/dist at /app/ with index.html fallback for client routing
- Dockerfile: node build stage for SPA, copy dist into runtime image
- README: document SPA, CORS_ORIGINS env var, architecture entry
- vite base set to /app/, manifest.json paths fixed
This commit is contained in:
2026-06-04 04:20:15 +02:00
parent 15dc0e526b
commit b9c0b10740
153 changed files with 24329 additions and 1 deletions

423
spa/src/routeTree.gen.ts Normal file
View File

@@ -0,0 +1,423 @@
/* eslint-disable */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// This file was automatically generated by TanStack Router.
// You should NOT make any changes in this file as it will be overwritten.
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as RegisterRouteImport } from './routes/register'
import { Route as LoginRouteImport } from './routes/login'
import { Route as AppRouteImport } from './routes/_app'
import { Route as AppIndexRouteImport } from './routes/_app/index'
import { Route as AppSocialRouteImport } from './routes/_app/social'
import { Route as AppSearchRouteImport } from './routes/_app/search'
import { Route as AppProfileRouteImport } from './routes/_app/profile'
import { Route as AppDiaryRouteImport } from './routes/_app/diary'
import { Route as AppSettingsIndexRouteImport } from './routes/_app/settings/index'
import { Route as AppWrapupIdRouteImport } from './routes/_app/wrapup.$id'
import { Route as AppUsersIdRouteImport } from './routes/_app/users.$id'
import { Route as AppSettingsWrapupRouteImport } from './routes/_app/settings/wrapup'
import { Route as AppSettingsWebhooksRouteImport } from './routes/_app/settings/webhooks'
import { Route as AppSettingsImportRouteImport } from './routes/_app/settings/import'
import { Route as AppSettingsEditProfileRouteImport } from './routes/_app/settings/edit-profile'
import { Route as AppSettingsBlockedRouteImport } from './routes/_app/settings/blocked'
import { Route as AppPeopleIdRouteImport } from './routes/_app/people.$id'
import { Route as AppMoviesIdRouteImport } from './routes/_app/movies.$id'
const RegisterRoute = RegisterRouteImport.update({
id: '/register',
path: '/register',
getParentRoute: () => rootRouteImport,
} as any)
const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => rootRouteImport,
} as any)
const AppRoute = AppRouteImport.update({
id: '/_app',
getParentRoute: () => rootRouteImport,
} as any)
const AppIndexRoute = AppIndexRouteImport.update({
id: '/',
path: '/',
getParentRoute: () => AppRoute,
} as any)
const AppSocialRoute = AppSocialRouteImport.update({
id: '/social',
path: '/social',
getParentRoute: () => AppRoute,
} as any)
const AppSearchRoute = AppSearchRouteImport.update({
id: '/search',
path: '/search',
getParentRoute: () => AppRoute,
} as any)
const AppProfileRoute = AppProfileRouteImport.update({
id: '/profile',
path: '/profile',
getParentRoute: () => AppRoute,
} as any)
const AppDiaryRoute = AppDiaryRouteImport.update({
id: '/diary',
path: '/diary',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsIndexRoute = AppSettingsIndexRouteImport.update({
id: '/settings/',
path: '/settings/',
getParentRoute: () => AppRoute,
} as any)
const AppWrapupIdRoute = AppWrapupIdRouteImport.update({
id: '/wrapup/$id',
path: '/wrapup/$id',
getParentRoute: () => AppRoute,
} as any)
const AppUsersIdRoute = AppUsersIdRouteImport.update({
id: '/users/$id',
path: '/users/$id',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsWrapupRoute = AppSettingsWrapupRouteImport.update({
id: '/settings/wrapup',
path: '/settings/wrapup',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsWebhooksRoute = AppSettingsWebhooksRouteImport.update({
id: '/settings/webhooks',
path: '/settings/webhooks',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsImportRoute = AppSettingsImportRouteImport.update({
id: '/settings/import',
path: '/settings/import',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsEditProfileRoute = AppSettingsEditProfileRouteImport.update({
id: '/settings/edit-profile',
path: '/settings/edit-profile',
getParentRoute: () => AppRoute,
} as any)
const AppSettingsBlockedRoute = AppSettingsBlockedRouteImport.update({
id: '/settings/blocked',
path: '/settings/blocked',
getParentRoute: () => AppRoute,
} as any)
const AppPeopleIdRoute = AppPeopleIdRouteImport.update({
id: '/people/$id',
path: '/people/$id',
getParentRoute: () => AppRoute,
} as any)
const AppMoviesIdRoute = AppMoviesIdRouteImport.update({
id: '/movies/$id',
path: '/movies/$id',
getParentRoute: () => AppRoute,
} as any)
export interface FileRoutesByFullPath {
'/': typeof AppIndexRoute
'/login': typeof LoginRoute
'/register': typeof RegisterRoute
'/diary': typeof AppDiaryRoute
'/profile': typeof AppProfileRoute
'/search': typeof AppSearchRoute
'/social': typeof AppSocialRoute
'/movies/$id': typeof AppMoviesIdRoute
'/people/$id': typeof AppPeopleIdRoute
'/settings/blocked': typeof AppSettingsBlockedRoute
'/settings/edit-profile': typeof AppSettingsEditProfileRoute
'/settings/import': typeof AppSettingsImportRoute
'/settings/webhooks': typeof AppSettingsWebhooksRoute
'/settings/wrapup': typeof AppSettingsWrapupRoute
'/users/$id': typeof AppUsersIdRoute
'/wrapup/$id': typeof AppWrapupIdRoute
'/settings/': typeof AppSettingsIndexRoute
}
export interface FileRoutesByTo {
'/login': typeof LoginRoute
'/register': typeof RegisterRoute
'/diary': typeof AppDiaryRoute
'/profile': typeof AppProfileRoute
'/search': typeof AppSearchRoute
'/social': typeof AppSocialRoute
'/': typeof AppIndexRoute
'/movies/$id': typeof AppMoviesIdRoute
'/people/$id': typeof AppPeopleIdRoute
'/settings/blocked': typeof AppSettingsBlockedRoute
'/settings/edit-profile': typeof AppSettingsEditProfileRoute
'/settings/import': typeof AppSettingsImportRoute
'/settings/webhooks': typeof AppSettingsWebhooksRoute
'/settings/wrapup': typeof AppSettingsWrapupRoute
'/users/$id': typeof AppUsersIdRoute
'/wrapup/$id': typeof AppWrapupIdRoute
'/settings': typeof AppSettingsIndexRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/_app': typeof AppRouteWithChildren
'/login': typeof LoginRoute
'/register': typeof RegisterRoute
'/_app/diary': typeof AppDiaryRoute
'/_app/profile': typeof AppProfileRoute
'/_app/search': typeof AppSearchRoute
'/_app/social': typeof AppSocialRoute
'/_app/': typeof AppIndexRoute
'/_app/movies/$id': typeof AppMoviesIdRoute
'/_app/people/$id': typeof AppPeopleIdRoute
'/_app/settings/blocked': typeof AppSettingsBlockedRoute
'/_app/settings/edit-profile': typeof AppSettingsEditProfileRoute
'/_app/settings/import': typeof AppSettingsImportRoute
'/_app/settings/webhooks': typeof AppSettingsWebhooksRoute
'/_app/settings/wrapup': typeof AppSettingsWrapupRoute
'/_app/users/$id': typeof AppUsersIdRoute
'/_app/wrapup/$id': typeof AppWrapupIdRoute
'/_app/settings/': typeof AppSettingsIndexRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
| '/'
| '/login'
| '/register'
| '/diary'
| '/profile'
| '/search'
| '/social'
| '/movies/$id'
| '/people/$id'
| '/settings/blocked'
| '/settings/edit-profile'
| '/settings/import'
| '/settings/webhooks'
| '/settings/wrapup'
| '/users/$id'
| '/wrapup/$id'
| '/settings/'
fileRoutesByTo: FileRoutesByTo
to:
| '/login'
| '/register'
| '/diary'
| '/profile'
| '/search'
| '/social'
| '/'
| '/movies/$id'
| '/people/$id'
| '/settings/blocked'
| '/settings/edit-profile'
| '/settings/import'
| '/settings/webhooks'
| '/settings/wrapup'
| '/users/$id'
| '/wrapup/$id'
| '/settings'
id:
| '__root__'
| '/_app'
| '/login'
| '/register'
| '/_app/diary'
| '/_app/profile'
| '/_app/search'
| '/_app/social'
| '/_app/'
| '/_app/movies/$id'
| '/_app/people/$id'
| '/_app/settings/blocked'
| '/_app/settings/edit-profile'
| '/_app/settings/import'
| '/_app/settings/webhooks'
| '/_app/settings/wrapup'
| '/_app/users/$id'
| '/_app/wrapup/$id'
| '/_app/settings/'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
AppRoute: typeof AppRouteWithChildren
LoginRoute: typeof LoginRoute
RegisterRoute: typeof RegisterRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/register': {
id: '/register'
path: '/register'
fullPath: '/register'
preLoaderRoute: typeof RegisterRouteImport
parentRoute: typeof rootRouteImport
}
'/login': {
id: '/login'
path: '/login'
fullPath: '/login'
preLoaderRoute: typeof LoginRouteImport
parentRoute: typeof rootRouteImport
}
'/_app': {
id: '/_app'
path: ''
fullPath: '/'
preLoaderRoute: typeof AppRouteImport
parentRoute: typeof rootRouteImport
}
'/_app/': {
id: '/_app/'
path: '/'
fullPath: '/'
preLoaderRoute: typeof AppIndexRouteImport
parentRoute: typeof AppRoute
}
'/_app/social': {
id: '/_app/social'
path: '/social'
fullPath: '/social'
preLoaderRoute: typeof AppSocialRouteImport
parentRoute: typeof AppRoute
}
'/_app/search': {
id: '/_app/search'
path: '/search'
fullPath: '/search'
preLoaderRoute: typeof AppSearchRouteImport
parentRoute: typeof AppRoute
}
'/_app/profile': {
id: '/_app/profile'
path: '/profile'
fullPath: '/profile'
preLoaderRoute: typeof AppProfileRouteImport
parentRoute: typeof AppRoute
}
'/_app/diary': {
id: '/_app/diary'
path: '/diary'
fullPath: '/diary'
preLoaderRoute: typeof AppDiaryRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings/': {
id: '/_app/settings/'
path: '/settings'
fullPath: '/settings/'
preLoaderRoute: typeof AppSettingsIndexRouteImport
parentRoute: typeof AppRoute
}
'/_app/wrapup/$id': {
id: '/_app/wrapup/$id'
path: '/wrapup/$id'
fullPath: '/wrapup/$id'
preLoaderRoute: typeof AppWrapupIdRouteImport
parentRoute: typeof AppRoute
}
'/_app/users/$id': {
id: '/_app/users/$id'
path: '/users/$id'
fullPath: '/users/$id'
preLoaderRoute: typeof AppUsersIdRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings/wrapup': {
id: '/_app/settings/wrapup'
path: '/settings/wrapup'
fullPath: '/settings/wrapup'
preLoaderRoute: typeof AppSettingsWrapupRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings/webhooks': {
id: '/_app/settings/webhooks'
path: '/settings/webhooks'
fullPath: '/settings/webhooks'
preLoaderRoute: typeof AppSettingsWebhooksRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings/import': {
id: '/_app/settings/import'
path: '/settings/import'
fullPath: '/settings/import'
preLoaderRoute: typeof AppSettingsImportRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings/edit-profile': {
id: '/_app/settings/edit-profile'
path: '/settings/edit-profile'
fullPath: '/settings/edit-profile'
preLoaderRoute: typeof AppSettingsEditProfileRouteImport
parentRoute: typeof AppRoute
}
'/_app/settings/blocked': {
id: '/_app/settings/blocked'
path: '/settings/blocked'
fullPath: '/settings/blocked'
preLoaderRoute: typeof AppSettingsBlockedRouteImport
parentRoute: typeof AppRoute
}
'/_app/people/$id': {
id: '/_app/people/$id'
path: '/people/$id'
fullPath: '/people/$id'
preLoaderRoute: typeof AppPeopleIdRouteImport
parentRoute: typeof AppRoute
}
'/_app/movies/$id': {
id: '/_app/movies/$id'
path: '/movies/$id'
fullPath: '/movies/$id'
preLoaderRoute: typeof AppMoviesIdRouteImport
parentRoute: typeof AppRoute
}
}
}
interface AppRouteChildren {
AppDiaryRoute: typeof AppDiaryRoute
AppProfileRoute: typeof AppProfileRoute
AppSearchRoute: typeof AppSearchRoute
AppSocialRoute: typeof AppSocialRoute
AppIndexRoute: typeof AppIndexRoute
AppMoviesIdRoute: typeof AppMoviesIdRoute
AppPeopleIdRoute: typeof AppPeopleIdRoute
AppSettingsBlockedRoute: typeof AppSettingsBlockedRoute
AppSettingsEditProfileRoute: typeof AppSettingsEditProfileRoute
AppSettingsImportRoute: typeof AppSettingsImportRoute
AppSettingsWebhooksRoute: typeof AppSettingsWebhooksRoute
AppSettingsWrapupRoute: typeof AppSettingsWrapupRoute
AppUsersIdRoute: typeof AppUsersIdRoute
AppWrapupIdRoute: typeof AppWrapupIdRoute
AppSettingsIndexRoute: typeof AppSettingsIndexRoute
}
const AppRouteChildren: AppRouteChildren = {
AppDiaryRoute: AppDiaryRoute,
AppProfileRoute: AppProfileRoute,
AppSearchRoute: AppSearchRoute,
AppSocialRoute: AppSocialRoute,
AppIndexRoute: AppIndexRoute,
AppMoviesIdRoute: AppMoviesIdRoute,
AppPeopleIdRoute: AppPeopleIdRoute,
AppSettingsBlockedRoute: AppSettingsBlockedRoute,
AppSettingsEditProfileRoute: AppSettingsEditProfileRoute,
AppSettingsImportRoute: AppSettingsImportRoute,
AppSettingsWebhooksRoute: AppSettingsWebhooksRoute,
AppSettingsWrapupRoute: AppSettingsWrapupRoute,
AppUsersIdRoute: AppUsersIdRoute,
AppWrapupIdRoute: AppWrapupIdRoute,
AppSettingsIndexRoute: AppSettingsIndexRoute,
}
const AppRouteWithChildren = AppRoute._addFileChildren(AppRouteChildren)
const rootRouteChildren: RootRouteChildren = {
AppRoute: AppRouteWithChildren,
LoginRoute: LoginRoute,
RegisterRoute: RegisterRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()