- Add WhyOps (whyops.nuc.lan:3002) to service catalog and registry - Show status pill for static (non-Coolify) services too - Merge static services into discovered list so they always appear - Health-check static services via /api/health endpoint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
170 lines
8.9 KiB
TypeScript
170 lines
8.9 KiB
TypeScript
export type ServiceCategory = 'infrastructure' | 'development' | 'knowledge' | 'storage' | 'monitoring' | 'security' | 'automation';
|
|
export type BookmarkCategory = 'developer' | 'ai-tools' | 'ai-platforms' | 'utilities' | 'design' | 'learning' | 'productivity' | 'other';
|
|
|
|
export interface Service {
|
|
name: string;
|
|
url: string;
|
|
port: number;
|
|
icon: string;
|
|
category: ServiceCategory;
|
|
description?: string;
|
|
container?: string;
|
|
}
|
|
|
|
export interface DiscoveredService extends Service {
|
|
source: 'discovered' | 'static';
|
|
fqdn?: string;
|
|
resourceType: 'application' | 'service' | 'database';
|
|
uuid: string;
|
|
coolifyStatus: string;
|
|
}
|
|
|
|
export function getCoolifyUrl(service: DiscoveredService): string {
|
|
const base = process.env.NEXT_PUBLIC_COOLIFY_URL || 'http://coolify.nuc.lan';
|
|
const project = process.env.NEXT_PUBLIC_COOLIFY_PROJECT_UUID || 'a8484ggc88c40w4g4k004ow0';
|
|
const env = process.env.NEXT_PUBLIC_COOLIFY_ENV_UUID || 'dckc0w4ko8s888c4gk84skoo';
|
|
return `${base}/project/${project}/environment/${env}/${service.resourceType}/${service.uuid}`;
|
|
}
|
|
|
|
export function getDozzleUrl(service?: DiscoveredService): string {
|
|
const base = process.env.NEXT_PUBLIC_DOZZLE_URL || 'http://dozzle.nuc.lan';
|
|
const hostId = process.env.NEXT_PUBLIC_DOZZLE_HOST_ID || '6c1738d9-6f12-4ed7-9293-70a91f407347';
|
|
if (service?.container) {
|
|
return `${base}/container/${hostId}~${service.container}`;
|
|
}
|
|
return base;
|
|
}
|
|
|
|
export interface Bookmark {
|
|
name: string;
|
|
url: string;
|
|
icon: string;
|
|
category: BookmarkCategory;
|
|
description?: string;
|
|
}
|
|
|
|
import { clientConfig, getServiceUrl } from './config';
|
|
|
|
const h = clientConfig.nucHost;
|
|
|
|
export const fallbackServices: Service[] = [
|
|
// Infrastructure - prefer domain-based URLs
|
|
{ name: 'Coolify', url: 'http://coolify.nuc.lan', port: 8000, icon: 'server', category: 'infrastructure', description: 'Container deployment & management' },
|
|
{ name: 'Dozzle', url: 'http://dozzle.nuc.lan', port: 9999, icon: 'scroll-text', category: 'infrastructure', description: 'Real-time Docker log viewer' },
|
|
{ name: 'Playwriter Browser', url: `http://${h}:6081/vnc.html`, port: 6081, icon: 'monitor', category: 'infrastructure', description: 'Remote browser for automation' },
|
|
|
|
// Automation
|
|
{ name: 'n8n', url: `http://${h}:5678`, port: 5678, icon: 'workflow', category: 'automation', description: 'Workflow automation platform' },
|
|
|
|
// Development - prefer domain-based URLs
|
|
{ name: 'Gitea', url: 'http://gitea.nuc.lan', port: 3030, icon: 'git-branch', category: 'development', description: 'Self-hosted Git service' },
|
|
{ name: 'CloudBeaver', url: `http://${h}:8978`, port: 8978, icon: 'database', category: 'development', description: 'Database management UI' },
|
|
{ name: 'Adminer', url: `http://${h}:8088`, port: 8088, icon: 'table', category: 'development', description: 'Lightweight database admin' },
|
|
{ name: 'WhyOps', url: 'http://whyops.nuc.lan', port: 3002, icon: 'settings', category: 'automation', description: 'WhyRating scraping, pipelines & testing' },
|
|
|
|
// Knowledge - prefer domain-based URLs
|
|
{ name: 'Outline', url: 'http://outline.nuc.lan', port: 3080, icon: 'book-open', category: 'knowledge', description: 'Team wiki & documentation' },
|
|
{ name: 'NocoDB', url: `http://${h}:8084`, port: 8084, icon: 'grid-3x3', category: 'knowledge', description: 'Airtable alternative database' },
|
|
|
|
// Storage - prefer domain-based URLs
|
|
{ name: 'FileBrowser', url: 'http://files.nuc.lan', port: 8085, icon: 'folder', category: 'storage', description: 'Web file manager' },
|
|
{ name: 'MinIO', url: `http://${h}:9001`, port: 9001, icon: 'hard-drive', category: 'storage', description: 'S3-compatible object storage' },
|
|
{ name: 'Kopia', url: `http://${h}:51515`, port: 51515, icon: 'archive', category: 'storage', description: 'Backup & restore' },
|
|
|
|
// Monitoring
|
|
{ name: 'Uptime Kuma', url: `http://${h}:3001`, port: 3001, icon: 'activity', category: 'monitoring', description: 'Service status monitoring' },
|
|
{ name: 'Ntfy', url: `http://${h}:8333`, port: 8333, icon: 'bell', category: 'monitoring', description: 'Push notifications server' },
|
|
|
|
// Security - prefer domain-based URLs
|
|
{ name: 'Vaultwarden', url: 'http://vault.nuc.lan', port: 8222, icon: 'lock', category: 'security', description: 'Password manager' },
|
|
{ name: 'Authentik', url: `http://${h}:9090`, port: 9090, icon: 'shield', category: 'security', description: 'Identity provider & SSO' },
|
|
];
|
|
|
|
// Re-export for backwards compatibility
|
|
export const services = fallbackServices;
|
|
|
|
export const bookmarks: Bookmark[] = [
|
|
// Developer Tools
|
|
{ name: 'DevDocs', url: 'https://devdocs.io', icon: 'book', category: 'developer', description: 'API documentation browser' },
|
|
{ name: 'Can I Use', url: 'https://caniuse.com', icon: 'check-circle', category: 'developer', description: 'Browser compatibility tables' },
|
|
{ name: 'Regex101', url: 'https://regex101.com', icon: 'brackets', category: 'developer', description: 'Regex tester & debugger' },
|
|
{ name: 'Bundlephobia', url: 'https://bundlephobia.com', icon: 'package', category: 'developer', description: 'NPM package size analyzer' },
|
|
{ name: 'Transform Tools', url: 'https://transform.tools', icon: 'arrow-right-left', category: 'developer', description: 'Code transformers' },
|
|
|
|
// AI Tools
|
|
{ name: 'Claude', url: 'https://claude.ai', icon: 'bot', category: 'ai-tools', description: 'Anthropic AI assistant' },
|
|
{ name: 'ChatGPT', url: 'https://chat.openai.com', icon: 'message-square', category: 'ai-tools', description: 'OpenAI chat assistant' },
|
|
{ name: 'Perplexity', url: 'https://perplexity.ai', icon: 'search', category: 'ai-tools', description: 'AI-powered search' },
|
|
{ name: 'Phind', url: 'https://phind.com', icon: 'code', category: 'ai-tools', description: 'AI for developers' },
|
|
{ name: 'Cursor', url: 'https://cursor.com', icon: 'terminal', category: 'ai-tools', description: 'AI-first code editor' },
|
|
|
|
// AI Platforms
|
|
{ name: 'v0', url: 'https://v0.dev', icon: 'layout', category: 'ai-platforms', description: 'Vercel AI UI generator' },
|
|
{ name: 'Replicate', url: 'https://replicate.com', icon: 'cpu', category: 'ai-platforms', description: 'ML model hosting' },
|
|
{ name: 'Hugging Face', url: 'https://huggingface.co', icon: 'smile', category: 'ai-platforms', description: 'ML models & datasets' },
|
|
{ name: 'Together AI', url: 'https://together.ai', icon: 'users', category: 'ai-platforms', description: 'Open model inference' },
|
|
|
|
// Utilities
|
|
{ name: 'Excalidraw', url: 'https://excalidraw.com', icon: 'pencil', category: 'utilities', description: 'Hand-drawn diagrams' },
|
|
{ name: 'JSON Crack', url: 'https://jsoncrack.com', icon: 'braces', category: 'utilities', description: 'JSON visualizer' },
|
|
{ name: 'Carbon', url: 'https://carbon.now.sh', icon: 'image', category: 'utilities', description: 'Code screenshot tool' },
|
|
{ name: 'Squoosh', url: 'https://squoosh.app', icon: 'image-down', category: 'utilities', description: 'Image compression' },
|
|
{ name: 'TinyPNG', url: 'https://tinypng.com', icon: 'file-image', category: 'utilities', description: 'PNG/JPEG compression' },
|
|
|
|
// Design
|
|
{ name: 'Figma', url: 'https://figma.com', icon: 'figma', category: 'design', description: 'Collaborative design tool' },
|
|
{ name: 'Coolors', url: 'https://coolors.co', icon: 'palette', category: 'design', description: 'Color palette generator' },
|
|
{ name: 'Heroicons', url: 'https://heroicons.com', icon: 'shapes', category: 'design', description: 'Beautiful hand-crafted icons' },
|
|
{ name: 'Lucide', url: 'https://lucide.dev', icon: 'circle', category: 'design', description: 'Icon library' },
|
|
|
|
// Learning
|
|
{ name: 'MDN Web Docs', url: 'https://developer.mozilla.org', icon: 'graduation-cap', category: 'learning', description: 'Web technology docs' },
|
|
{ name: 'web.dev', url: 'https://web.dev', icon: 'globe', category: 'learning', description: 'Modern web guidance' },
|
|
|
|
// Productivity
|
|
{ name: 'Linear', url: 'https://linear.app', icon: 'list-todo', category: 'productivity', description: 'Issue tracking' },
|
|
{ name: 'Notion', url: 'https://notion.so', icon: 'notebook', category: 'productivity', description: 'Notes & docs' },
|
|
];
|
|
|
|
export const categoryLabels: Record<ServiceCategory, string> = {
|
|
infrastructure: 'Infrastructure',
|
|
development: 'Development',
|
|
knowledge: 'Knowledge',
|
|
storage: 'Storage',
|
|
monitoring: 'Monitoring',
|
|
security: 'Security',
|
|
automation: 'Automation',
|
|
};
|
|
|
|
export const bookmarkCategoryLabels: Record<BookmarkCategory, string> = {
|
|
developer: 'Developer Tools',
|
|
'ai-tools': 'AI Tools',
|
|
'ai-platforms': 'AI Platforms',
|
|
utilities: 'Utilities',
|
|
design: 'Design',
|
|
learning: 'Learning',
|
|
productivity: 'Productivity',
|
|
other: 'Other',
|
|
};
|
|
|
|
export const categoryOrder: ServiceCategory[] = [
|
|
'infrastructure',
|
|
'automation',
|
|
'development',
|
|
'knowledge',
|
|
'storage',
|
|
'monitoring',
|
|
'security',
|
|
];
|
|
|
|
export const bookmarkCategoryOrder: BookmarkCategory[] = [
|
|
'developer',
|
|
'ai-tools',
|
|
'ai-platforms',
|
|
'utilities',
|
|
'design',
|
|
'learning',
|
|
'productivity',
|
|
'other',
|
|
];
|