Update with new components

This commit is contained in:
2025-09-23 19:41:25 +05:30
parent cfe68a276f
commit bd2f5b95ce
129 changed files with 5849 additions and 1169 deletions

View File

@ -2,7 +2,6 @@ import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AngularEditorConfig } from '@josipv/angular-editor-k2';
import { AuthenticationService } from 'src/app/service/authentication.service';
;
import { BlogService } from 'src/app/service/blog.service';
import { ProfessorService } from 'src/app/service/professor.service';
@ -18,9 +17,14 @@ export class BlogComponent implements OnInit {
blogForm: FormGroup;
editing: boolean = false;
loggedInUser: any;
currentBlog: any = null; // Holds the blog being edited
isShowForm = false; // Controls visibility of form vs. table
currentBlog: any = null;
isShowForm = false;
content = '';
// Image upload properties
selectedImage: File | null = null;
imagePreviewUrl: string | null = null;
uploadingImage: boolean = false;
constructor(
private blogService: BlogService,
@ -32,9 +36,9 @@ export class BlogComponent implements OnInit {
this.blogForm = this.fb.group({
title: ['', Validators.required],
content: ['', Validators.required],
professors: [[], Validators.required], // To hold selected professor IDs
tags: ['', Validators.required], // To hold tags as a comma-separated string
posted: [true], // Initialize checkbox with default value false
professors: [[], Validators.required],
tags: ['', Validators.required],
posted: [true],
});
}
@ -53,9 +57,6 @@ export class BlogComponent implements OnInit {
defaultParagraphSeparator: '',
defaultFontName: '',
defaultFontSize: '',
// headers: [{
// }],
fonts: [
{ class: 'arial', name: 'Arial' },
{ class: 'times-new-roman', name: 'Times New Roman' },
@ -77,111 +78,236 @@ export class BlogComponent implements OnInit {
tag: 'h1',
},
],
// uploadUrl: 'v1/image',
// upload: (file: File) => { ... }
// uploadWithCredentials: false,
sanitize: true,
toolbarPosition: 'top',
toolbarHiddenButtons: [['bold', 'italic'], ['fontSize']],
};
ngOnInit(): void {
this.loggedInUser = this.authService.getUserFromLocalStorage();
this.professorService
.getAllProfessors()
.subscribe((res) => (this.allProfessors = res.content));
ngOnInit(): void {
this.loggedInUser = this.authService.getUserFromLocalStorage();
this.professorService
.getAllProfessors()
.subscribe((res) => (this.allProfessors = res.content));
this.loadBlogs();
// Subscribe to form value changes to update content for preview
this.blogForm.get('content')?.valueChanges.subscribe((value) => {
this.content = value;
});
}
this.loadBlogs();
// Subscribe to form value changes to update content for preview
this.blogForm.get('content')?.valueChanges.subscribe((value) => {
this.content = value;
});
}
showForm() {
this.isShowForm = true;
this.resetForm();
}
showForm() {
this.isShowForm = true;
this.resetForm(); // Ensure form is reset when showing
showTable() {
this.isShowForm = false;
this.resetForm();
}
loadBlogs() {
this.blogService.getBlogs().subscribe(data => {
this.blogs = data;
});
}
createBlog() {
this.showForm();
this.blogForm.reset();
this.selectedBlog = null;
this.editing = false;
}
editBlog(blog: any) {
this.selectedBlog = blog;
this.blogForm.patchValue({
title: blog.title,
content: blog.content,
posted: blog.posted,
professors: blog.professors.map((prof: any) => prof.id),
tags: blog.tags.join(', ')
});
// Set image preview if exists
if (blog.imageUrl) {
this.imagePreviewUrl = blog.imageUrl;
}
showTable() {
this.isShowForm = false;
this.resetForm(); // Ensure form is reset when switching back
}
loadBlogs() {
this.blogService.getBlogs().subscribe(data => {
this.blogs = data;
});
}
createBlog() {
this.showForm(); // Show form to create a new blog
this.blogForm.reset();
this.selectedBlog = null;
this.editing = false;
}
editBlog(blog: any) {
this.selectedBlog = blog;
this.blogForm.patchValue({
title: blog.title,
content: blog.content,
posted: blog.posted,
professors: blog.professors.map((prof: any) => prof.id), // Assuming professors are an array of objects
tags: blog.tags.join(', ') // Convert tags array back to comma-separated string
});
this.editing = true;
this.isShowForm = true;
this.editing = true;
this.isShowForm = true;
}
// Image upload methods
onImageSelected(event: any) {
const file = event.target.files[0];
if (file) {
// Validate file type
if (!file.type.startsWith('image/')) {
alert('Please select a valid image file.');
return;
}
// Validate file size (10MB max)
const maxSize = 10 * 1024 * 1024; // 10MB in bytes
if (file.size > maxSize) {
alert('File size must be less than 10MB.');
return;
}
this.selectedImage = file;
// Create preview URL
const reader = new FileReader();
reader.onload = (e: any) => {
this.imagePreviewUrl = e.target.result;
};
reader.readAsDataURL(file);
}
saveBlog() {
if (this.blogForm.valid) {
const blogData = this.blogForm.value;
// Convert tags to array and professors to array of IDs
blogData.tags = blogData.tags.split(',').map((tag: string) => tag.trim());
blogData.professors = blogData.professors || [];
blogData.author = this.loggedInUser._id; // Associate logged-in user with the blog
if (this.editing && this.selectedBlog) {
this.blogService.updateBlog(this.selectedBlog.id, blogData).subscribe(() => {
this.loadBlogs();
this.resetForm();
this.isShowForm = false; // Hide form after update
});
} else {
this.blogService.createBlog(blogData).subscribe(() => {
this.loadBlogs();
this.resetForm();
this.isShowForm = false; // Hide form after creation
});
}
removeImage() {
this.selectedImage = null;
this.imagePreviewUrl = null;
// Clear the file input
const fileInput = document.getElementById('image') as HTMLInputElement;
if (fileInput) {
fileInput.value = '';
}
}
async uploadImage(): Promise<string | null> {
if (!this.selectedImage) return null;
this.uploadingImage = true;
try {
const response = await this.blogService.uploadImage(this.selectedImage).toPromise();
return response.url;
} catch (error) {
console.error('Error uploading image:', error);
alert('Failed to upload image. Please try again.');
return null;
} finally {
this.uploadingImage = false;
}
}
async saveBlog() {
if (this.blogForm.valid) {
let imageUrl = null;
// Upload image if selected
if (this.selectedImage) {
imageUrl = await this.uploadImage();
if (!imageUrl) {
return; // Stop if image upload failed
}
}
}
deleteBlog(blog: any) {
if (confirm('Are you sure you want to delete this blog?')) {
this.blogService.deleteBlog(blog.id).subscribe(() => {
this.loadBlogs();
});
const blogData = this.blogForm.value;
// Convert tags to array and professors to array of IDs
blogData.tags = blogData.tags.split(',').map((tag: string) => tag.trim());
blogData.professors = blogData.professors || [];
// Add image URL if uploaded, or keep existing image for updates
if (imageUrl) {
blogData.imageUrl = imageUrl;
} else if (this.editing && this.selectedBlog && this.selectedBlog.imageUrl && this.imagePreviewUrl) {
// Keep existing image URL if editing and no new image selected
blogData.imageUrl = this.selectedBlog.imageUrl;
}
blogData.author = this.loggedInUser._id;
if (this.editing && this.selectedBlog) {
this.blogService.updateBlog(this.selectedBlog.id, blogData).subscribe({
next: () => {
this.loadBlogs();
this.resetForm();
this.isShowForm = false;
alert('Blog updated successfully!');
},
error: (error) => {
console.error('Error updating blog:', error);
alert('Failed to update blog. Please try again.');
}
});
} else {
this.blogService.createBlog(blogData).subscribe({
next: () => {
this.loadBlogs();
this.resetForm();
this.isShowForm = false;
alert('Blog created successfully!');
},
error: (error) => {
console.error('Error creating blog:', error);
alert('Failed to create blog. Please try again.');
}
});
}
} else {
// Mark all fields as touched to show validation errors
Object.keys(this.blogForm.controls).forEach(key => {
this.blogForm.get(key)?.markAsTouched();
});
alert('Please fill in all required fields.');
}
resetForm() {
this.blogForm.reset();
this.selectedBlog = null;
this.editing = false;
this.blogForm.patchValue({
professors: [],
tags: ''
}
deleteBlog(blog: any) {
if (confirm('Are you sure you want to delete this blog?')) {
this.blogService.deleteBlog(blog.id).subscribe({
next: () => {
this.loadBlogs();
alert('Blog deleted successfully!');
},
error: (error) => {
console.error('Error deleting blog:', error);
alert('Failed to delete blog. Please try again.');
}
});
}
}
resetForm() {
this.blogForm.reset();
this.selectedBlog = null;
this.editing = false;
this.selectedImage = null;
this.imagePreviewUrl = null;
this.blogForm.patchValue({
professors: [],
tags: '',
posted: true
});
// Clear the file input
const fileInput = document.getElementById('image') as HTMLInputElement;
if (fileInput) {
fileInput.value = '';
}
}
// Utility method to check if form field has error
hasError(fieldName: string): boolean {
const field = this.blogForm.get(fieldName);
return !!(field && field.invalid && field.touched);
}
// Utility method to get error message for a field
getErrorMessage(fieldName: string): string {
const field = this.blogForm.get(fieldName);
if (field && field.errors && field.touched) {
if (field.errors['required']) {
return `${fieldName} is required.`;
}
}
return '';
}
}