99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
type SiteUrlKey =
|
|
| "missionControl"
|
|
| "ganttBoard"
|
|
| "blogBackup"
|
|
| "gitea"
|
|
| "github"
|
|
| "vercel"
|
|
| "supabase"
|
|
| "google"
|
|
| "googleCalendar"
|
|
| "googleCalendarSettings";
|
|
|
|
const DEFAULT_SITE_URLS: Record<SiteUrlKey, string> = {
|
|
missionControl: "https://mission-control.twisteddevices.com",
|
|
ganttBoard: "https://gantt-board.twisteddevices.com",
|
|
blogBackup: "https://blog-backup-two.vercel.app",
|
|
gitea: "http://192.168.1.128:3000",
|
|
github: "https://github.com",
|
|
vercel: "https://vercel.com",
|
|
supabase: "https://supabase.com",
|
|
google: "https://google.com",
|
|
googleCalendar: "https://calendar.google.com",
|
|
googleCalendarSettings: "https://calendar.google.com/calendar/u/0/r/settings",
|
|
};
|
|
|
|
const ENV_SITE_URLS: Partial<Record<SiteUrlKey, string | undefined>> = {
|
|
missionControl: process.env.NEXT_PUBLIC_MISSION_CONTROL_URL,
|
|
ganttBoard: process.env.NEXT_PUBLIC_GANTT_BOARD_URL,
|
|
blogBackup: process.env.NEXT_PUBLIC_BLOG_BACKUP_URL,
|
|
gitea: process.env.NEXT_PUBLIC_GITEA_URL,
|
|
github: process.env.NEXT_PUBLIC_GITHUB_URL,
|
|
vercel: process.env.NEXT_PUBLIC_VERCEL_URL,
|
|
supabase: process.env.NEXT_PUBLIC_SUPABASE_SITE_URL,
|
|
google: process.env.NEXT_PUBLIC_GOOGLE_URL,
|
|
googleCalendar: process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_URL,
|
|
googleCalendarSettings: process.env.NEXT_PUBLIC_GOOGLE_CALENDAR_SETTINGS_URL,
|
|
};
|
|
|
|
function normalizeBaseUrl(value: string, fallback: string): string {
|
|
try {
|
|
const normalized = new URL(value.trim()).toString();
|
|
return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
|
|
} catch {
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
const configuredSiteUrls = Object.entries(DEFAULT_SITE_URLS).reduce(
|
|
(acc, [key, fallback]) => {
|
|
const envValue = ENV_SITE_URLS[key as SiteUrlKey];
|
|
acc[key as SiteUrlKey] = normalizeBaseUrl(envValue || fallback, fallback);
|
|
return acc;
|
|
},
|
|
{} as Record<SiteUrlKey, string>,
|
|
);
|
|
|
|
export const siteUrls = Object.freeze(configuredSiteUrls);
|
|
|
|
function toUrl(base: string, path = ""): string {
|
|
if (!path) return base;
|
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
return `${base}${normalizedPath}`;
|
|
}
|
|
|
|
function toUrlWithQuery(
|
|
base: string,
|
|
path: string,
|
|
params: Record<string, string | undefined>,
|
|
): string {
|
|
const query = new URLSearchParams();
|
|
for (const [key, value] of Object.entries(params)) {
|
|
if (value) query.set(key, value);
|
|
}
|
|
const queryString = query.toString();
|
|
return queryString ? `${toUrl(base, path)}?${queryString}` : toUrl(base, path);
|
|
}
|
|
|
|
export function getGanttTaskUrl(taskId: string): string {
|
|
return toUrl(siteUrls.ganttBoard, `/tasks/${encodeURIComponent(taskId)}`);
|
|
}
|
|
|
|
export function getGanttProjectUrl(projectId: string): string {
|
|
return toUrl(siteUrls.ganttBoard, `/projects/${encodeURIComponent(projectId)}`);
|
|
}
|
|
|
|
export function getGanttSprintUrl(sprintId: string): string {
|
|
return toUrl(siteUrls.ganttBoard, `/sprints/${encodeURIComponent(sprintId)}`);
|
|
}
|
|
|
|
export function getGanttTasksUrl(params?: Record<string, string | undefined>): string {
|
|
return params
|
|
? toUrlWithQuery(siteUrls.ganttBoard, "/tasks", params)
|
|
: toUrl(siteUrls.ganttBoard, "/tasks");
|
|
}
|
|
|
|
export function getMissionControlDocumentsUrl(): string {
|
|
return toUrl(siteUrls.missionControl, "/documents");
|
|
}
|