mirror of
https://github.com/a-mayb3/KanbanCloneAngular.git
synced 2026-03-21 09:55:37 +01:00
Started working on project creation form page
This commit is contained in:
parent
2f3f8354a7
commit
773fa7ad6d
4 changed files with 202 additions and 2 deletions
|
|
@ -1,5 +1,8 @@
|
|||
<app-navbar />
|
||||
<main class="main">
|
||||
</main>
|
||||
<main class="main"></main>
|
||||
|
||||
|
||||
<app-footer />
|
||||
|
||||
<router-outlet />
|
||||
|
||||
|
|
|
|||
89
src/app/pages/project-create/project-create.component.css
Normal file
89
src/app/pages/project-create/project-create.component.css
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
.create-project {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f7fa;
|
||||
padding: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
height: fit-content;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 32px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card h1 {
|
||||
margin: 0 0 24px 0;
|
||||
font-size: 28px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group textarea {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
padding: 10px 16px;
|
||||
background-color: #10b981;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-primary:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
padding: 10px 16px;
|
||||
background: none;
|
||||
border: 1px solid #cbd5f0;
|
||||
color: #334155;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.error {
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
background-color: #fee2e2;
|
||||
color: #b91c1c;
|
||||
}
|
||||
49
src/app/pages/project-create/project-create.component.html
Normal file
49
src/app/pages/project-create/project-create.component.html
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<div class="create-project">
|
||||
<div class="card">
|
||||
<h1>Create project</h1>
|
||||
|
||||
@if (errorMessage()) {
|
||||
<div class="error">{{ errorMessage() }}</div>
|
||||
}
|
||||
|
||||
<form (ngSubmit)="onSubmit()" #projectForm="ngForm">
|
||||
<div class="form-group">
|
||||
<label for="name">Project name</label>
|
||||
<input
|
||||
id="name"
|
||||
type="text"
|
||||
name="name"
|
||||
[(ngModel)]="name"
|
||||
placeholder="Enter a project name"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">Description</label>
|
||||
<textarea
|
||||
id="description"
|
||||
name="description"
|
||||
[(ngModel)]="description"
|
||||
rows="4"
|
||||
placeholder="Optional description"
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button type="button" class="btn-secondary" (click)="onCancel()">Cancel</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn-primary"
|
||||
[disabled]="isSaving() || !projectForm.form.valid"
|
||||
>
|
||||
@if (isSaving()) {
|
||||
<span>Creating...</span>
|
||||
} @else {
|
||||
<span>Create project</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
59
src/app/pages/project-create/project-create.component.ts
Normal file
59
src/app/pages/project-create/project-create.component.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { Component, inject, signal } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { CreateProjectRequest, Project } from '../../models/projects.models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-create',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FormsModule],
|
||||
templateUrl: './project-create.component.html',
|
||||
styleUrl: './project-create.component.css'
|
||||
})
|
||||
export class ProjectCreateComponent {
|
||||
private apiService = inject(ApiService);
|
||||
private router = inject(Router);
|
||||
|
||||
name = '';
|
||||
description = '';
|
||||
isSaving = signal(false);
|
||||
errorMessage = signal('');
|
||||
|
||||
onSubmit() {
|
||||
if (!this.name.trim()) {
|
||||
this.errorMessage.set('Project name is required.');
|
||||
return;
|
||||
}
|
||||
|
||||
const payload: CreateProjectRequest = {
|
||||
name: this.name.trim(),
|
||||
description: this.description.trim() || undefined
|
||||
};
|
||||
|
||||
this.isSaving.set(true);
|
||||
this.errorMessage.set('');
|
||||
|
||||
this.apiService.post<Project>('/projects', payload).subscribe({
|
||||
next: (project) => {
|
||||
this.isSaving.set(false);
|
||||
if (project?.id != null) {
|
||||
this.router.navigate(['/projects', project.id]);
|
||||
} else {
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
},
|
||||
error: (error) => {
|
||||
this.isSaving.set(false);
|
||||
this.errorMessage.set(
|
||||
error?.error?.message || 'Failed to create project. Please try again.'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue