Skip to content

Commit 820aff1

Browse files
author
Marvin Zhang
committed
feat: refactor project initialization and create ProjectListPage component
1 parent 309d752 commit 820aff1

File tree

9 files changed

+17
-47
lines changed

9 files changed

+17
-47
lines changed

.github/instructions/all.instructions.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,6 @@ export class ProjectService {
355355
if (!this.database.isInitialized) {
356356
await this.database.initialize();
357357
}
358-
359-
// Create default project if it doesn't exist
360-
await this.createDefaultProject();
361358
}
362359

363360
async list(): Promise<ProjectMetadata[]> {

GEMINI.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,9 +385,6 @@ export class ProjectService {
385385
if (!this.database.isInitialized) {
386386
await this.database.initialize();
387387
}
388-
389-
// Create default project if it doesn't exist
390-
await this.createDefaultProject();
391388
}
392389

393390
async list(): Promise<ProjectMetadata[]> {

packages/core/src/services/project-service.ts

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,36 +43,13 @@ export class ProjectService {
4343
this.database.entityMetadatas.length,
4444
);
4545
console.log('[ProjectService] Repository initialized:', !!this.repository);
46-
47-
// Create default project if it doesn't exist
48-
await this.createDefaultProject();
4946
}
5047
} catch (error) {
5148
console.error('[ProjectService] Failed to initialize:', error);
5249
throw error;
5350
}
5451
}
5552

56-
/**
57-
* Create default project
58-
*/
59-
private async createDefaultProject(): Promise<void> {
60-
const defaultProject: Omit<Project, 'id' | 'createdAt' | 'lastAccessedAt'> = {
61-
name: 'Default Project',
62-
description: 'Default devlog project',
63-
};
64-
65-
// Create project directly without initialization check since this is called during initialization
66-
const existing = await this.repository.findOne({ where: { name: defaultProject.name } });
67-
if (existing) {
68-
return; // Default project already exists
69-
}
70-
71-
// Create and save new project entity
72-
const entity = ProjectEntity.fromProjectData(defaultProject);
73-
await this.repository.save(entity);
74-
}
75-
7653
async list(): Promise<Project[]> {
7754
await this.ensureInitialized(); // Ensure initialization
7855

packages/web/app/AppLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import React, { useEffect, useState } from 'react';
44
import { AppLayoutSkeleton, ErrorBoundary, NavigationSidebar, TopNavbar } from '@/components';
55
import { SidebarProvider, SidebarInset } from '@/components/ui/sidebar';
6+
import { Toaster } from 'sonner';
67

78
interface AppLayoutProps {
89
children: React.ReactNode;
@@ -23,6 +24,7 @@ export function AppLayout({ children }: AppLayoutProps) {
2324

2425
return (
2526
<ErrorBoundary>
27+
<Toaster />
2628
<div className="min-h-screen bg-background w-full">
2729
<TopNavbar />
2830
<SidebarProvider>

packages/web/app/api/projects/[id]/route.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,8 @@ export const PUT = withErrorHandling(
5656
return projectResult.response;
5757
}
5858

59-
// Parse request body
60-
const data = await request.json();
61-
6259
// Update project
63-
const updatedProject = await projectResult.data.projectService.update(projectId, data);
60+
const updatedProject = await projectResult.data.projectService.update(projectId, bodyValidation.data);
6461

6562
return createSuccessResponse(updatedProject, { sseEventType: RealtimeEventType.PROJECT_UPDATED });
6663
},

packages/web/app/components/common/project-card-skeleton/ProjectCardSkeleton.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Skeleton } from '@/components/ui/skeleton';
66

77
export function ProjectCardSkeleton() {
88
return (
9-
<Card className="w-96 h-48">
9+
<Card className="h-48">
1010
<CardHeader className="pb-3">
1111
<div className="flex items-start justify-between">
1212
<Skeleton className="h-6 w-32" />
@@ -28,7 +28,7 @@ export function ProjectCardSkeleton() {
2828

2929
export function ProjectGridSkeleton({ count = 6 }: { count?: number }) {
3030
return (
31-
<div className="flex items-center gap-6 flex-wrap">
31+
<div className="grid gap-6 lg:grid-cols-3 md:grid-cols-2">
3232
{Array.from({ length: count }).map((_, index) => (
3333
<ProjectCardSkeleton key={index} />
3434
))}

packages/web/app/projects/ProjectManagementPage.tsx renamed to packages/web/app/projects/ProjectListPage.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ interface ProjectFormData {
3434
description?: string;
3535
}
3636

37-
export function ProjectManagementPage() {
37+
export function ProjectListPage() {
3838
const { projectsContext, fetchProjects } = useProjectStore();
3939
const [isModalVisible, setIsModalVisible] = useState(false);
4040
const [creating, setCreating] = useState(false);
@@ -43,11 +43,14 @@ export function ProjectManagementPage() {
4343
const { subscribe, unsubscribe } = useRealtimeStore();
4444

4545
useEffect(() => {
46-
subscribe(RealtimeEventType.PROJECT_CREATED, fetchProjects);
46+
subscribe(RealtimeEventType.PROJECT_CREATED, async () => {
47+
await fetchProjects();
48+
toast.success('Project created successfully');
49+
});
4750
return () => {
4851
unsubscribe(RealtimeEventType.PROJECT_CREATED);
4952
};
50-
}, []);
53+
}, [fetchProjects]);
5154

5255
useEffect(() => {
5356
fetchProjects();
@@ -118,10 +121,7 @@ export function ProjectManagementPage() {
118121
<div className="w-full max-w-full p-6">
119122
<div className="max-w-7xl mx-auto">
120123
<div className="flex items-center gap-4 mb-6">
121-
<Button
122-
className="bg-primary"
123-
onClick={() => setIsModalVisible(true)}
124-
>
124+
<Button className="bg-primary" onClick={() => setIsModalVisible(true)}>
125125
New Project
126126
</Button>
127127
<div className="relative">
@@ -138,11 +138,11 @@ export function ProjectManagementPage() {
138138

139139
{/* Show skeleton loading state */}
140140
{isLoadingProjects ? (
141-
<ProjectGridSkeleton count={3} />
141+
<ProjectGridSkeleton count={2} />
142142
) : (
143143
<>
144144
{/* Projects grid */}
145-
<div className="grid gap-6 lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-2">
145+
<div className="grid gap-6 lg:grid-cols-3 md:grid-cols-2">
146146
{projects?.map((project) => (
147147
<Card
148148
key={project.id}

packages/web/app/projects/[id]/settings/ProjectSettingsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ export function ProjectSettingsPage({ projectId }: ProjectSettingsPageProps) {
307307
<CardDescription>View project metadata and statistics</CardDescription>
308308
</CardHeader>
309309
<CardContent className="space-y-4">
310-
<div className="grid grid-cols-2 gap-4">
310+
<div className="grid gap-4 lg:grid-cols-4 md:grid-cols-2">
311311
<div>
312312
<Label className="text-sm text-muted-foreground">Project ID</Label>
313313
<p className="text-sm font-mono">{project.id}</p>

packages/web/app/projects/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { ProjectManagementPage } from './ProjectManagementPage';
1+
import { ProjectListPage } from './ProjectListPage';
22

33
export default function ProjectsPage() {
4-
return <ProjectManagementPage />;
4+
return <ProjectListPage />;
55
}

0 commit comments

Comments
 (0)