Commit 7c84e134 authored by Aravind RK's avatar Aravind RK

feat : CRUD for student

parent 09fd6813
<div class="page-container animate-fade-in">
<div class="page-header" style="display: flex; align-items: center; gap: 16px;">
<button class="icon-btn" (click)="goBack()" style="background: var(--bg-card); border: 1px solid var(--border-color); padding: 8px; border-radius: 12px; cursor: pointer; color: var(--text-primary); transition: all 0.2s; display: flex; align-items: center; justify-content: center;" onmouseover="this.style.background='var(--bg-hover)'" onmouseout="this.style.background='var(--bg-card)'">
<span class="material-symbols-rounded">arrow_back</span>
</button>
<div>
<h1 style="margin: 0; font-size: 24px;">Student Users</h1>
<p style="margin: 4px 0 0;" class="page-subtitle">View and manage registered students</p>
<div class="page-header" style="display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center; gap: 16px;">
<button class="icon-btn" (click)="goBack()" style="background: var(--bg-card); border: 1px solid var(--border-color); padding: 8px; border-radius: 12px; cursor: pointer; color: var(--text-primary); transition: all 0.2s; display: flex; align-items: center; justify-content: center;" onmouseover="this.style.background='var(--bg-hover)'" onmouseout="this.style.background='var(--bg-card)'">
<span class="material-symbols-rounded">arrow_back</span>
</button>
<div>
<h1 style="margin: 0; font-size: 24px;">Student Users</h1>
<p style="margin: 4px 0 0;" class="page-subtitle">View and manage registered students</p>
</div>
</div>
<button class="btn btn-primary" (click)="openCreateModal()">
<span class="material-symbols-rounded">person_add</span> Create Student
</button>
</div>
<div class="filter-tabs">
......@@ -43,7 +48,10 @@
<div class="status-dot" [class.online]="user.isLoggedIn" title="Online Status"></div>
<button class="action-btn text-danger ml-auto" (click)="$event.preventDefault(); $event.stopPropagation(); deleteUser(user._id)" title="Delete Student">
<button class="action-btn text-primary ml-auto" style="margin-right: 8px;" (click)="$event.preventDefault(); $event.stopPropagation(); openEditModal(user)" title="Edit Student">
<span class="material-symbols-rounded">edit</span>
</button>
<button class="action-btn text-danger" (click)="$event.preventDefault(); $event.stopPropagation(); deleteUser(user._id)" title="Delete Student">
<span class="material-symbols-rounded">delete</span>
</button>
......@@ -52,4 +60,50 @@
}
</div>
}
</div>
<!-- ─── Create / Edit Student Modal ───────────────────────────── -->
@if (showUserModal()) {
<div class="student-modal-overlay" (click)="closeModal()">
<div class="student-modal-container" (click)="$event.stopPropagation()">
<div class="student-modal-header">
<h2>{{ isEditMode() ? 'Edit Student' : 'Create Student' }}</h2>
<button class="student-modal-close" (click)="closeModal()">
<span class="material-symbols-rounded">close</span>
</button>
</div>
<div class="student-modal-body">
<div class="form-group">
<label class="form-label">Full Name *</label>
<input class="form-input" [(ngModel)]="userForm.name" placeholder="Enter student's full name">
</div>
<div class="form-group">
<label class="form-label">Email Address *</label>
<input class="form-input" type="email" [(ngModel)]="userForm.email" placeholder="student@example.com">
</div>
<div class="form-group">
<label class="form-label">Password {{ isEditMode() ? '(Optional)' : '*' }}</label>
<input class="form-input" type="password" [(ngModel)]="userForm.password" [placeholder]="isEditMode() ? 'Leave blank to keep current password' : 'Enter initial password'">
@if (isEditMode()) {
<small class="form-hint">Change this only if the student forgot their password.</small>
}
</div>
</div>
<div class="student-modal-footer">
<button class="btn btn-outline" (click)="closeModal()">Cancel</button>
<button class="btn btn-primary" (click)="saveUser()" [disabled]="savingUser()">
@if (savingUser()) {
<div class="spinner spinner-sm"></div> Saving...
} @else {
<span class="material-symbols-rounded">save</span>
{{ isEditMode() ? 'Save Changes' : 'Create Student' }}
}
</button>
</div>
</div>
</div>
}
......@@ -2,13 +2,14 @@ import { Component, OnInit, signal } from '@angular/core';
import { Location } from '@angular/common';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { AuthService } from '../../../services/auth.service';
import { QuizService } from '../../../services/quiz.service';
@Component({
selector: 'app-admin-users',
standalone: true,
imports: [CommonModule, RouterLink],
imports: [CommonModule, RouterLink, FormsModule],
templateUrl: './users.html',
styleUrl: './users.css'
})
......@@ -17,6 +18,18 @@ export class AdminUsersComponent implements OnInit {
loading = signal<boolean>(true);
showAll = signal<boolean>(true);
// Modal State
showUserModal = signal<boolean>(false);
isEditMode = signal<boolean>(false);
savingUser = signal<boolean>(false);
editingUserId = signal<string | null>(null);
userForm = {
name: '',
email: '',
password: ''
};
constructor(public authService: AuthService, private quizService: QuizService, private location: Location) {}
goBack(): void {
......@@ -69,6 +82,72 @@ export class AdminUsersComponent implements OnInit {
}
}
openCreateModal(): void {
this.isEditMode.set(false);
this.editingUserId.set(null);
this.userForm = { name: '', email: '', password: '' };
this.showUserModal.set(true);
}
openEditModal(user: any): void {
this.isEditMode.set(true);
this.editingUserId.set(user._id);
this.userForm = { name: user.name, email: user.email, password: '' };
this.showUserModal.set(true);
}
closeModal(): void {
this.showUserModal.set(false);
}
saveUser(): void {
if (!this.userForm.name || !this.userForm.email) {
alert('Name and email are required');
return;
}
if (!this.isEditMode() && !this.userForm.password) {
alert('Password is required when creating a new student');
return;
}
this.savingUser.set(true);
if (this.isEditMode() && this.editingUserId()) {
// Edit User
const payload: any = { name: this.userForm.name, email: this.userForm.email };
if (this.userForm.password) {
payload.password = this.userForm.password;
}
this.quizService.editUser(this.editingUserId()!, payload).subscribe({
next: () => {
this.savingUser.set(false);
this.closeModal();
this.loadUsers();
},
error: (err) => {
console.error('Failed to update user', err);
alert(err.error?.message || 'Failed to update user');
this.savingUser.set(false);
}
});
} else {
// Create User
this.authService.register(this.userForm.name, this.userForm.email, this.userForm.password).subscribe({
next: () => {
this.savingUser.set(false);
this.closeModal();
this.loadUsers();
},
error: (err) => {
console.error('Failed to create user', err);
alert(err.error?.message || 'Failed to create user');
this.savingUser.set(false);
}
});
}
}
logout(): void {
this.authService.logout();
}
......
This diff is collapsed.
<div class="page-container animate-fade-in">
<div class="page-header">
<h1>Student Users</h1>
<p>View and manage registered students</p>
<div class="page-header" style="display: flex; align-items: center; justify-content: space-between;">
<div>
<h1>Student Users</h1>
<p class="page-subtitle">View and manage registered students</p>
</div>
<button class="btn btn-primary" (click)="openCreateModal()">
<span class="material-symbols-rounded">person_add</span> Create Student
</button>
</div>
<div class="filter-tabs">
......@@ -38,7 +43,10 @@
<div class="status-dot" [class.online]="user.isLoggedIn" title="Online Status"></div>
<button class="action-btn text-danger ml-auto" (click)="$event.preventDefault(); $event.stopPropagation(); deleteUser(user._id)" title="Delete Student">
<button class="action-btn text-primary ml-auto" style="margin-right: 8px;" (click)="$event.preventDefault(); $event.stopPropagation(); openEditModal(user)" title="Edit Student">
<span class="material-symbols-rounded">edit</span>
</button>
<button class="action-btn text-danger" (click)="$event.preventDefault(); $event.stopPropagation(); deleteUser(user._id)" title="Delete Student">
<span class="material-symbols-rounded">delete</span>
</button>
......@@ -48,3 +56,47 @@
</div>
}
</div>
<!-- ─── Create / Edit Student Modal ───────────────────────────── -->
@if (showUserModal()) {
<div class="student-modal-overlay" (click)="closeModal()">
<div class="student-modal-container" (click)="$event.stopPropagation()">
<div class="student-modal-header">
<h2>{{ isEditMode() ? 'Edit Student' : 'Create Student' }}</h2>
<button class="student-modal-close" (click)="closeModal()">
<span class="material-symbols-rounded">close</span>
</button>
</div>
<div class="student-modal-body">
<div class="form-group">
<label class="form-label">Full Name *</label>
<input class="form-input" [(ngModel)]="userForm.name" placeholder="Enter student's full name">
</div>
<div class="form-group">
<label class="form-label">Email Address *</label>
<input class="form-input" type="email" [(ngModel)]="userForm.email" placeholder="student@example.com">
</div>
<div class="form-group">
<label class="form-label">Password {{ isEditMode() ? '(Optional)' : '*' }}</label>
<input class="form-input" type="password" [(ngModel)]="userForm.password" [placeholder]="isEditMode() ? 'Leave blank to keep current password' : 'Enter initial password'">
@if (isEditMode()) {
<small class="form-hint">Change this only if the student forgot their password.</small>
}
</div>
</div>
<div class="student-modal-footer">
<button class="btn btn-outline" (click)="closeModal()">Cancel</button>
<button class="btn btn-primary" (click)="saveUser()" [disabled]="savingUser()">
@if (savingUser()) {
<div class="spinner spinner-sm"></div> Saving...
} @else {
<span class="material-symbols-rounded">save</span>
{{ isEditMode() ? 'Save Changes' : 'Create Student' }}
}
</button>
</div>
</div>
</div>
}
import { Component, OnInit, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { AuthService } from '../../../services/auth.service';
import { QuizService } from '../../../services/quiz.service';
@Component({
selector: 'app-users',
imports: [CommonModule, RouterLink],
imports: [CommonModule, RouterLink, FormsModule],
templateUrl: './users.html',
styleUrl: './users.css',
})
......@@ -15,6 +16,18 @@ export class Users {
loading = signal<boolean>(true);
showAll = signal<boolean>(true);
// Modal State
showUserModal = signal<boolean>(false);
isEditMode = signal<boolean>(false);
savingUser = signal<boolean>(false);
editingUserId = signal<string | null>(null);
userForm = {
name: '',
email: '',
password: ''
};
constructor(public authService: AuthService, private quizService: QuizService) {}
ngOnInit(): void {
......@@ -63,6 +76,72 @@ export class Users {
}
}
openCreateModal(): void {
this.isEditMode.set(false);
this.editingUserId.set(null);
this.userForm = { name: '', email: '', password: '' };
this.showUserModal.set(true);
}
openEditModal(user: any): void {
this.isEditMode.set(true);
this.editingUserId.set(user._id);
this.userForm = { name: user.name, email: user.email, password: '' };
this.showUserModal.set(true);
}
closeModal(): void {
this.showUserModal.set(false);
}
saveUser(): void {
if (!this.userForm.name || !this.userForm.email) {
alert('Name and email are required');
return;
}
if (!this.isEditMode() && !this.userForm.password) {
alert('Password is required when creating a new student');
return;
}
this.savingUser.set(true);
if (this.isEditMode() && this.editingUserId()) {
// Edit User
const payload: any = { name: this.userForm.name, email: this.userForm.email };
if (this.userForm.password) {
payload.password = this.userForm.password;
}
this.quizService.editUser(this.editingUserId()!, payload).subscribe({
next: () => {
this.savingUser.set(false);
this.closeModal();
this.loadUsers();
},
error: (err) => {
console.error('Failed to update user', err);
alert(err.error?.message || 'Failed to update user');
this.savingUser.set(false);
}
});
} else {
// Create User
this.authService.register(this.userForm.name, this.userForm.email, this.userForm.password).subscribe({
next: () => {
this.savingUser.set(false);
this.closeModal();
this.loadUsers();
},
error: (err) => {
console.error('Failed to create user', err);
alert(err.error?.message || 'Failed to create user');
this.savingUser.set(false);
}
});
}
}
logout(): void {
this.authService.logout();
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment