mirror of
https://gitlab.w-hs.de/an14051/backerup-website.git
synced 2026-07-27 17:35:29 +00:00
984b282a95
- Implemented AdminLinksPage for managing link entries with admin role check. - Created API routes for fetching, updating, and deleting link entries. - Added ProductTabs component for navigation between Backerup and Updaterup. - Developed UpdaterupPage with detailed features, setup instructions, and statistics. - Introduced links database functionality for runtime-editable link overrides.
79 lines
3.9 KiB
TypeScript
79 lines
3.9 KiB
TypeScript
/**
|
|
* Runtime-editable link overrides stored in SQLite.
|
|
* Falls back to the static LINKS defaults for any key without an override.
|
|
*/
|
|
import { getDb, ensureReady } from './db'
|
|
import { LINKS } from './links'
|
|
|
|
export type LinkKey = keyof typeof LINKS
|
|
|
|
/** Human-readable labels for each link key (used in the admin UI). */
|
|
export const LINK_META: Record<LinkKey, { label: string; description: string; group: string }> = {
|
|
gitea: { label: 'Backerup — Gitea repo', description: 'Repository root used in nav, footer, and CTA buttons', group: 'Backerup' },
|
|
giteaReleases: { label: 'Backerup — Releases', description: 'Releases / changelog page', group: 'Backerup' },
|
|
giteaIssues: { label: 'Backerup — Issues', description: 'Issue tracker', group: 'Backerup' },
|
|
giteaDiscussions: { label: 'Backerup — Discussions', description: 'Gitea Discussions forum', group: 'Backerup' },
|
|
giteaContributing: { label: 'Backerup — Contributing', description: 'CONTRIBUTING.md guide', group: 'Backerup' },
|
|
docs: { label: 'Backerup — Docs', description: 'Primary documentation URL', group: 'Backerup' },
|
|
dockerImage: { label: 'Backerup — Docker image', description: 'Full image reference shown in install snippets', group: 'Backerup' },
|
|
uiPort: { label: 'Backerup — UI port', description: 'Default port the Backerup container exposes', group: 'Backerup' },
|
|
updaterupGitea: { label: 'Updaterup — Gitea repo', description: 'Repository root used in Updaterup pages', group: 'Updaterup' },
|
|
updaterupDockerImage: { label: 'Updaterup — Docker image', description: 'Full image reference shown in Updaterup install snippets', group: 'Updaterup' },
|
|
}
|
|
|
|
export interface LinkEntry {
|
|
key: LinkKey
|
|
label: string
|
|
description: string
|
|
group: string
|
|
defaultValue: string
|
|
override: string | null
|
|
currentValue: string
|
|
}
|
|
|
|
/** Returns merged links: DB overrides take precedence over static defaults. */
|
|
export async function getLinks(): Promise<typeof LINKS> {
|
|
await ensureReady()
|
|
const { rows } = await getDb().execute('SELECT key, value FROM links')
|
|
const overrides: Partial<Record<string, string>> = {}
|
|
for (const row of rows) {
|
|
overrides[row.key as string] = row.value as string
|
|
}
|
|
return { ...LINKS, ...overrides } as typeof LINKS
|
|
}
|
|
|
|
/** Returns all link entries with defaults, overrides, and current values — for the admin UI. */
|
|
export async function getAllLinkEntries(): Promise<LinkEntry[]> {
|
|
await ensureReady()
|
|
const { rows } = await getDb().execute('SELECT key, value FROM links')
|
|
const overrides: Partial<Record<string, string>> = {}
|
|
for (const row of rows) {
|
|
overrides[row.key as string] = row.value as string
|
|
}
|
|
|
|
return (Object.keys(LINK_META) as LinkKey[]).map((key) => ({
|
|
key,
|
|
...LINK_META[key],
|
|
defaultValue: LINKS[key],
|
|
override: overrides[key] ?? null,
|
|
currentValue: overrides[key] ?? LINKS[key],
|
|
}))
|
|
}
|
|
|
|
/** Upserts a link override. Pass the static default to effectively reset it, or use resetLink(). */
|
|
export async function setLink(key: LinkKey, value: string): Promise<void> {
|
|
await ensureReady()
|
|
await getDb().execute({
|
|
sql: `INSERT INTO links (key, value, updated_at)
|
|
VALUES (?, ?, datetime('now'))
|
|
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`,
|
|
args: [key, value],
|
|
})
|
|
}
|
|
|
|
/** Removes the DB override for a key, restoring the static default. */
|
|
export async function resetLink(key: LinkKey): Promise<void> {
|
|
await ensureReady()
|
|
await getDb().execute({ sql: 'DELETE FROM links WHERE key = ?', args: [key] })
|
|
}
|