🚀 Add automatic deployment system
- Add auto-deploy.sh script with full CI/CD pipeline - Add quick-deploy.sh for fast development deployments - Add Git post-receive hook for automatic deployment on push - Add comprehensive deployment documentation - Add npm scripts for easy deployment management - Include health checks, logging, and cleanup - Support for automatic rollback on failures
This commit is contained in:
@@ -24,16 +24,37 @@ import {
|
||||
Calendar,
|
||||
Activity
|
||||
} from 'lucide-react';
|
||||
import { projectService, DatabaseProject } from '@/lib/prisma';
|
||||
import { projectService } from '@/lib/prisma';
|
||||
import { useToast } from './Toast';
|
||||
|
||||
interface Project {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
content: string;
|
||||
imageUrl?: string | null;
|
||||
github?: string | null;
|
||||
liveUrl?: string | null;
|
||||
tags: string[];
|
||||
category: string;
|
||||
difficulty: string;
|
||||
featured: boolean;
|
||||
published: boolean;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
_count?: {
|
||||
pageViews: number;
|
||||
userInteractions: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface AdminDashboardProps {
|
||||
onProjectSelect: (project: DatabaseProject) => void;
|
||||
onProjectSelect: (project: Project) => void;
|
||||
onNewProject: () => void;
|
||||
}
|
||||
|
||||
export default function AdminDashboard({ onProjectSelect, onNewProject }: AdminDashboardProps) {
|
||||
const [projects, setProjects] = useState<DatabaseProject[]>([]);
|
||||
const [projects, setProjects] = useState<Project[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('');
|
||||
@@ -52,7 +73,7 @@ export default function AdminDashboard({ onProjectSelect, onNewProject }: AdminD
|
||||
try {
|
||||
setLoading(true);
|
||||
const data = await projectService.getAllProjects();
|
||||
setProjects(data);
|
||||
setProjects(data.projects);
|
||||
} catch (error) {
|
||||
console.error('Error loading projects:', error);
|
||||
// Fallback to localStorage if database fails
|
||||
@@ -79,8 +100,8 @@ export default function AdminDashboard({ onProjectSelect, onNewProject }: AdminD
|
||||
|
||||
switch (sortBy) {
|
||||
case 'date':
|
||||
aValue = new Date(a.created_at);
|
||||
bValue = new Date(b.created_at);
|
||||
aValue = new Date(a.createdAt);
|
||||
bValue = new Date(b.createdAt);
|
||||
break;
|
||||
case 'title':
|
||||
aValue = a.title.toLowerCase();
|
||||
@@ -92,12 +113,12 @@ export default function AdminDashboard({ onProjectSelect, onNewProject }: AdminD
|
||||
bValue = difficultyOrder[b.difficulty as keyof typeof difficultyOrder];
|
||||
break;
|
||||
case 'views':
|
||||
aValue = a.analytics.views;
|
||||
bValue = b.analytics.views;
|
||||
aValue = a._count?.pageViews || 0;
|
||||
bValue = b._count?.pageViews || 0;
|
||||
break;
|
||||
default:
|
||||
aValue = a.created_at;
|
||||
bValue = b.created_at;
|
||||
aValue = a.createdAt;
|
||||
bValue = b.createdAt;
|
||||
}
|
||||
|
||||
if (sortOrder === 'asc') {
|
||||
@@ -113,10 +134,9 @@ export default function AdminDashboard({ onProjectSelect, onNewProject }: AdminD
|
||||
published: projects.filter(p => p.published).length,
|
||||
featured: projects.filter(p => p.featured).length,
|
||||
categories: new Set(projects.map(p => p.category)).size,
|
||||
totalViews: projects.reduce((sum, p) => sum + p.analytics.views, 0),
|
||||
totalLikes: projects.reduce((sum, p) => sum + p.analytics.likes, 0),
|
||||
avgLighthouse: projects.length > 0 ?
|
||||
Math.round(projects.reduce((sum, p) => sum + p.performance.lighthouse, 0) / projects.length) : 0
|
||||
totalViews: projects.reduce((sum, p) => sum + (p._count?.pageViews || 0), 0),
|
||||
totalLikes: projects.reduce((sum, p) => sum + (p._count?.userInteractions || 0), 0),
|
||||
avgLighthouse: 0
|
||||
};
|
||||
|
||||
// Bulk operations
|
||||
@@ -514,15 +534,15 @@ export default function AdminDashboard({ onProjectSelect, onNewProject }: AdminD
|
||||
</span>
|
||||
<span className="flex items-center">
|
||||
<Calendar className="mr-1" size={14} />
|
||||
{new Date(project.created_at).toLocaleDateString()}
|
||||
{new Date(project.createdAt).toLocaleDateString()}
|
||||
</span>
|
||||
<span className="flex items-center">
|
||||
<Eye className="mr-1" size={14} />
|
||||
{project.analytics.views} views
|
||||
{project._count?.pageViews || 0} views
|
||||
</span>
|
||||
<span className="flex items-center">
|
||||
<Activity className="mr-1" size={14} />
|
||||
{project.performance.lighthouse}/100
|
||||
N/A
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user