Init Repo

This commit is contained in:
2026-02-28 03:22:04 +08:00
commit de59b57ee7
883 changed files with 156857 additions and 0 deletions
+198
View File
@@ -0,0 +1,198 @@
import { apiClient } from './api'
export interface Project {
id: number
name: string
code_name: string
client_name: string
project_type: 'tv' | 'cinema' | 'game'
description?: string
status: 'planning' | 'in_progress' | 'on_hold' | 'completed' | 'cancelled'
start_date?: string
end_date?: string
created_at: string
updated_at: string
member_count?: number
episode_count?: number
asset_count?: number
department_role?: string
project_members?: ProjectMember[]
thumbnail_url?: string | null
custom_asset_task_types?: string[]
custom_shot_task_types?: string[]
}
export interface ProjectMember {
id: number
user_id: number
project_id: number
department_role?: 'layout' | 'animation' | 'lighting' | 'composite' | 'modeling' | 'rigging' | 'surfacing'
joined_at: string
user_email: string
user_first_name: string
user_last_name: string
}
export interface ProjectCreate {
name: string
code_name: string
client_name: string
project_type: 'tv' | 'cinema' | 'game'
description?: string | null
status?: 'planning' | 'in_progress' | 'on_hold' | 'completed' | 'cancelled'
start_date?: string | null
end_date?: string | null
}
export interface ProjectUpdate {
name?: string
code_name?: string
client_name?: string
project_type?: 'tv' | 'cinema' | 'game'
description?: string | null
status?: 'planning' | 'in_progress' | 'on_hold' | 'completed' | 'cancelled'
start_date?: string | null
end_date?: string | null
}
export interface ProjectMemberCreate {
user_id: number
department_role?: 'layout' | 'animation' | 'lighting' | 'composite' | 'modeling' | 'rigging' | 'surfacing'
}
export interface ProjectMemberUpdate {
department_role?: 'layout' | 'animation' | 'lighting' | 'composite' | 'modeling' | 'rigging' | 'surfacing'
}
export interface DeliveryMovieSpec {
resolution: string
format: string
codec?: string
quality?: string
}
export interface ProjectTechnicalSpecs {
frame_rate?: number
data_drive_path?: string
publish_storage_path?: string
delivery_image_resolution?: string
delivery_movie_specs_by_department?: Record<string, DeliveryMovieSpec>
}
export interface AssetTaskTemplates {
characters: string[]
props: string[]
sets: string[]
vehicles: string[]
}
export interface ProjectSettings {
upload_data_location?: string
asset_task_templates?: AssetTaskTemplates
shot_task_templates?: string[]
enabled_asset_tasks?: Record<string, string[]>
enabled_shot_tasks?: string[]
}
export const projectService = {
async getUserProjects(): Promise<Project[]> {
const response = await apiClient.get('/projects/')
return response.data
},
async getProject(projectId: number, includeMembers: boolean = false): Promise<Project> {
const response = await apiClient.get(`/projects/${projectId}`, {
params: { include_members: includeMembers }
})
return response.data
},
async createProject(project: ProjectCreate): Promise<Project> {
// Clean up the project data - convert empty strings to null for optional fields
const cleanedProject = {
...project,
start_date: project.start_date || null,
end_date: project.end_date || null,
description: project.description || null
}
const response = await apiClient.post('/projects/', cleanedProject)
return response.data
},
async updateProject(projectId: number, project: ProjectUpdate): Promise<Project> {
// Clean up the project data - convert empty strings to null for optional fields
const cleanedProject = {
...project,
start_date: project.start_date || null,
end_date: project.end_date || null,
description: project.description || null
}
const response = await apiClient.put(`/projects/${projectId}`, cleanedProject)
return response.data
},
async deleteProject(projectId: number): Promise<void> {
await apiClient.delete(`/projects/${projectId}`)
},
async getProjectMembers(projectId: number): Promise<ProjectMember[]> {
const response = await apiClient.get(`/projects/${projectId}/members`)
return response.data
},
async addProjectMember(projectId: number, member: ProjectMemberCreate): Promise<ProjectMember> {
const response = await apiClient.post(`/projects/${projectId}/members`, member)
return response.data
},
async updateProjectMember(projectId: number, memberId: number, member: ProjectMemberUpdate): Promise<ProjectMember> {
const response = await apiClient.put(`/projects/${projectId}/members/${memberId}`, member)
return response.data
},
async removeProjectMember(projectId: number, memberId: number): Promise<void> {
await apiClient.delete(`/projects/${projectId}/members/${memberId}`)
},
async getProjectTechnicalSpecs(projectId: number): Promise<ProjectTechnicalSpecs> {
const response = await apiClient.get(`/projects/${projectId}/technical-specs`)
return response.data
},
async updateProjectTechnicalSpecs(projectId: number, specs: ProjectTechnicalSpecs): Promise<ProjectTechnicalSpecs> {
const response = await apiClient.put(`/projects/${projectId}/technical-specs`, specs)
return response.data
},
async setDefaultTechnicalSpecs(projectId: number): Promise<ProjectTechnicalSpecs> {
const response = await apiClient.post(`/projects/${projectId}/technical-specs/defaults`)
return response.data
},
async getProjectSettings(projectId: number): Promise<ProjectSettings> {
const response = await apiClient.get(`/projects/${projectId}/settings`)
return response.data
},
async updateProjectSettings(projectId: number, settings: ProjectSettings): Promise<ProjectSettings> {
const response = await apiClient.put(`/projects/${projectId}/settings`, settings)
return response.data
},
async uploadThumbnail(projectId: number, file: File): Promise<{ message: string; thumbnail_url: string }> {
const formData = new FormData()
formData.append('file', file)
const response = await apiClient.post(`/projects/${projectId}/thumbnail`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
return response.data
},
async deleteThumbnail(projectId: number): Promise<void> {
await apiClient.delete(`/projects/${projectId}/thumbnail`)
}
}