Refactor Docker setup for frontend-only builds by removing server-side API files, creating mock APIs, and updating health check notes. Adjusted Vite configuration for browser compatibility and refined API handling in various components to improve user experience and maintainability.

This commit is contained in:
2025-08-15 22:35:15 +01:00
parent f7dc75d514
commit 7d100e7e0f
16 changed files with 224 additions and 124 deletions

View File

@ -2,7 +2,7 @@ import { useState } from 'react';
import { Header } from '@/components/Header';
import { Footer } from '@/components/Footer';
import { Button } from '@/components/ui/button';
import { Shield, Users, BarChart3, FileText, ArrowLeft } from 'lucide-react';
import { Shield, Users, ArrowLeft } from 'lucide-react';
import { AdminDashboard } from '@/components/admin/AdminDashboard';
import AnalyticsDashboard from '@/components/admin/AnalyticsDashboard';
import ScriptReviewDashboard from '@/components/admin/ScriptReviewDashboard';

View File

@ -11,7 +11,7 @@ import { Separator } from '@/components/ui/separator';
import {
Plus,
Folder,
Users,
Lock,
FileText,
Calendar,
@ -38,7 +38,7 @@ export default function Collections() {
// API hooks
const { data: publicCollections, isLoading: publicLoading } = usePublicCollections();
const { data: userCollections, isLoading: userLoading } = useUserCollections(user?.id || '');
const { data: userCollections } = useUserCollections(user?.id || '');
const createCollection = useCreateCollection();
const handleCreateCollection = async (e: React.FormEvent) => {

View File

@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Separator } from '@/components/ui/separator';
import {
Download,
Star,
@ -141,9 +141,9 @@ export default function ScriptDetail() {
const { theme } = useTheme();
// API hooks
const { data: script, isLoading: scriptLoading } = useScript(scriptId || '');
const { data: script } = useScript(scriptId || '');
const { data: userRatingData } = useUserRating(scriptId || '', user?.id);
const { data: ratingStats } = useScriptRatingStats(scriptId || '');
const { } = useScriptRatingStats(scriptId || '');
const trackView = useTrackView();
const trackDownload = useTrackDownload();
const rateScript = useRateScript();
@ -203,7 +203,7 @@ export default function ScriptDetail() {
};
const handleCopyCode = async () => {
await copyToClipboard(displayScript.content || displayScript.code || '');
await copyToClipboard((displayScript as any).content || displayScript.description || '');
setCopied(true);
showSuccess('Code copied to clipboard!');
setTimeout(() => setCopied(false), 2000);
@ -260,9 +260,9 @@ export default function ScriptDetail() {
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<span>v{displayScript.version}</span>
<span></span>
<span>{displayScript.license || 'MIT'} License</span>
<span>{(displayScript as any).license || 'MIT'} License</span>
<span></span>
<span>{displayScript.size || 'N/A'}</span>
<span>{(displayScript as any).size || 'N/A'}</span>
</div>
</div>
</div>
@ -301,7 +301,7 @@ export default function ScriptDetail() {
</div>
<div className="flex items-center gap-2">
<Calendar className="h-4 w-4 text-muted-foreground" />
<span>Updated {formatDate(displayScript.updatedAt || displayScript.lastUpdated)}</span>
<span>Updated {formatDate((displayScript as any).updatedAt || displayScript.createdAt || new Date())}</span>
</div>
</div>
@ -333,7 +333,7 @@ export default function ScriptDetail() {
<CardContent className="space-y-4">
<div className="prose prose-sm max-w-none">
<p className="whitespace-pre-line">
{showFullDescription ? displayScript.longDescription : displayScript.longDescription.slice(0, 300) + '...'}
{showFullDescription ? displayScript.description : displayScript.description.slice(0, 300) + '...'}
</p>
</div>
<Button
@ -371,18 +371,18 @@ export default function ScriptDetail() {
wrapLongLines={true}
>
{showFullCode
? (displayScript.content || displayScript.code || '')
: (displayScript.content || displayScript.code || '').slice(0, 1000) + (((displayScript.content || displayScript.code || '').length > 1000) ? '\n...' : '')
? ((displayScript as any).content || displayScript.description || '')
: ((displayScript as any).content || displayScript.description || '').slice(0, 1000) + ((((displayScript as any).content || displayScript.description || '').length > 1000) ? '\n...' : '')
}
</SyntaxHighlighter>
</div>
{!showFullCode && (displayScript.content || displayScript.code || '').length > 1000 && (
{!showFullCode && ((displayScript as any).content || displayScript.description || '').length > 1000 && (
<Button
variant="ghost"
className="mt-2"
onClick={() => setShowFullCode(true)}
>
Show full code ({((displayScript.content || displayScript.code || '').length / 1000).toFixed(1)}k characters)
Show full code ({(((displayScript as any).content || displayScript.description || '').length / 1000).toFixed(1)}k characters)
</Button>
)}
</CardContent>
@ -396,7 +396,7 @@ export default function ScriptDetail() {
<CardContent className="space-y-6">
<div>
<h4 className="font-semibold mb-2">Requirements</h4>
<p className="text-sm text-muted-foreground">{displayScript.requirements}</p>
<p className="text-sm text-muted-foreground">{(displayScript as any).requirements || 'No specific requirements'}</p>
</div>
<div>
@ -413,7 +413,7 @@ export default function ScriptDetail() {
}}
wrapLongLines={true}
>
{displayScript.installation || ''}
{(displayScript as any).installation || 'No installation instructions provided'}
</SyntaxHighlighter>
</div>
</div>
@ -432,7 +432,7 @@ export default function ScriptDetail() {
}}
wrapLongLines={true}
>
{displayScript.usage || ''}
{(displayScript as any).usage || 'No usage instructions provided'}
</SyntaxHighlighter>
</div>
</div>
@ -446,7 +446,7 @@ export default function ScriptDetail() {
</CardHeader>
<CardContent>
<div className="space-y-4">
{displayScript.changelog.map((change, index) => (
{((displayScript as any).changelog || []).map((change: any, index: number) => (
<div key={index} className="border-l-2 border-primary/20 pl-4">
<div className="flex items-center gap-2 mb-1">
<Badge variant="outline">v{change.version}</Badge>
@ -455,7 +455,7 @@ export default function ScriptDetail() {
</span>
</div>
<ul className="text-sm space-y-1">
{change.changes.map((item, itemIndex) => (
{change.changes.map((item: string, itemIndex: number) => (
<li key={itemIndex} className="flex items-start gap-2">
<span className="text-primary mt-1"></span>
{item}
@ -481,7 +481,7 @@ export default function ScriptDetail() {
<CardContent className="space-y-3">
<div className="flex items-center gap-3">
<Avatar className="h-12 w-12">
<AvatarImage src={displayScript.author.avatarUrl} />
<AvatarImage src={displayScript.author.avatarUrl || undefined} />
<AvatarFallback>{displayScript.author.displayName[0]}</AvatarFallback>
</Avatar>
<div>
@ -489,7 +489,7 @@ export default function ScriptDetail() {
<div className="text-sm text-muted-foreground">@{displayScript.author.username}</div>
</div>
</div>
{displayScript.author.isVerified && (
{(displayScript.author as any)?.isVerified && (
<Badge variant="outline" className="w-fit">
<User className="h-3 w-3 mr-1" />
Verified Author
@ -510,11 +510,11 @@ export default function ScriptDetail() {
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">License</span>
<span className="font-medium">{displayScript.license}</span>
<span className="font-medium">{(displayScript as any).license || 'MIT'}</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Size</span>
<span className="font-medium">{displayScript.size}</span>
<span className="font-medium">{(displayScript as any).size || 'N/A'}</span>
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Created</span>
@ -522,7 +522,7 @@ export default function ScriptDetail() {
</div>
<div className="flex justify-between">
<span className="text-muted-foreground">Updated</span>
<span className="font-medium">{formatDate(displayScript.lastUpdated)}</span>
<span className="font-medium">{formatDate((displayScript as any).updatedAt || displayScript.createdAt || new Date())}</span>
</div>
</CardContent>
</Card>
@ -550,7 +550,7 @@ export default function ScriptDetail() {
</CardHeader>
<CardContent>
<div className="space-y-2">
{displayScript.dependencies.map(dep => (
{((displayScript as any).dependencies || []).map((dep: string) => (
<Badge key={dep} variant="secondary" className="w-full justify-center">
{dep}
</Badge>

View File

@ -11,48 +11,7 @@ import { ScriptFilters } from '@/components/ScriptFilters';
import { ScriptGrid } from '@/components/ScriptGrid';
import { useScripts } from '@/hooks/useScripts';
// Mock search results - in a real app, this would come from an API
const mockSearchResults = [
{
id: '1',
name: 'Docker Setup Script',
description: 'Automated Docker environment setup for development projects',
compatible_os: ['Linux', 'macOS', 'Windows'],
categories: ['DevOps', 'Docker'],
git_repository_url: 'https://github.com/john_doe/docker-setup',
author_name: 'john_doe',
view_count: 1247,
created_at: '2023-12-01T08:00:00Z',
updated_at: '2024-01-15T10:30:00Z',
is_approved: true,
},
{
id: '2',
name: 'Backup Automation',
description: 'Automated backup script for servers and databases',
compatible_os: ['Linux', 'macOS'],
categories: ['Backup', 'Automation'],
git_repository_url: 'https://github.com/jane_smith/backup-automation',
author_name: 'jane_smith',
view_count: 892,
created_at: '2023-11-15T10:00:00Z',
updated_at: '2024-01-10T14:20:00Z',
is_approved: true,
},
{
id: '3',
name: 'Network Monitor',
description: 'Real-time network monitoring and alerting script',
compatible_os: ['Linux'],
categories: ['Monitoring', 'Network'],
git_repository_url: 'https://github.com/admin/network-monitor',
author_name: 'admin',
view_count: 567,
created_at: '2023-12-10T09:00:00Z',
updated_at: '2024-01-12T09:15:00Z',
is_approved: true,
},
];
// Mock search results removed - using real API
export default function Search() {
const [searchParams, setSearchParams] = useSearchParams();
@ -75,7 +34,22 @@ export default function Search() {
isApproved: true, // Only show approved scripts in search
});
const searchResults = scriptsData?.scripts || [];
const rawResults = scriptsData?.scripts || [];
// Transform API results to match ScriptCard interface
const searchResults = rawResults.map((script: any) => ({
id: script.id,
name: script.name,
description: script.description,
compatible_os: script.compatibleOs || [],
categories: script.categories || [],
git_repository_url: script.gitRepositoryUrl,
author_name: script.authorName || script.author?.displayName || 'Unknown',
view_count: script.viewCount || 0,
created_at: script.createdAt || new Date().toISOString(),
updated_at: script.updatedAt || new Date().toISOString(),
is_approved: script.isApproved || false,
}));
useEffect(() => {
// Update search query when URL params change