From a663cc0079072d9536a0f7ed8d880b8032db4ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96zt=C3=BCrk?= Date: Sun, 22 Jun 2025 14:54:30 +0300 Subject: [PATCH] =?UTF-8?q?Forum=20sistemi=20kald=C4=B1r=C4=B1ld=C4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Forum/ForumCategoryDto.cs | 34 - .../Forum/ForumPostDto.cs | 44 -- .../Forum/ForumTopicDto.cs | 114 --- .../Forum/IForumAppService.cs | 66 -- .../Blog/BlogAutoMapperProfile.cs | 15 + .../Forum/ForumAppService.cs | 648 ------------------ .../PlatformApplicationAutoMapperProfile.cs | 26 - .../Seeds/SeederData.json | 88 --- .../Data/ForumDataSeedContributor.cs | 58 -- .../Forum/ForumCategory.cs | 86 --- .../Kurs.Platform.Domain/Forum/ForumPost.cs | 62 -- .../Forum/ForumPostLike.cs | 31 - .../Kurs.Platform.Domain/Forum/ForumTopic.cs | 117 ---- .../Forum/ForumTopicLike.cs | 31 - .../Forum/ForumTopicTag.cs | 31 - .../EntityFrameworkCore/PlatformDbContext.cs | 108 +-- .../20250620094517_AddBlogForumEntities.cs | 347 ---------- ...0250622112214_AddBlogEntities.Designer.cs} | 419 +---------- .../20250622112214_AddBlogEntities.cs | 116 ++++ .../PlatformDbContextModelSnapshot.cs | 415 ----------- company/src/App.tsx | 73 +- company/src/components/layout/Header.tsx | 153 +---- company/src/pages/Forum.tsx | 284 -------- company/src/pages/ForumCategory.tsx | 278 -------- company/src/pages/Login.tsx | 142 ---- company/src/pages/LoginWithTenant.tsx | 237 ------- company/src/pages/Profile.tsx | 141 ---- company/src/pages/Register.tsx | 222 ------ company/src/services/api/auth.service.ts | 228 ------ company/src/services/api/forum.service.ts | 257 ------- company/src/store/authStore.ts | 112 --- ui/src/configs/routes.config/adminRoutes.tsx | 2 +- ui/src/services/forum.service.ts | 291 -------- ui/src/services/rest.service.ts | 68 -- ui/src/views/blog/BlogManagement.tsx | 4 +- ui/src/views/forum/ForumManagement.tsx | 541 --------------- 36 files changed, 177 insertions(+), 5712 deletions(-) delete mode 100644 api/src/Kurs.Platform.Application.Contracts/Forum/ForumCategoryDto.cs delete mode 100644 api/src/Kurs.Platform.Application.Contracts/Forum/ForumPostDto.cs delete mode 100644 api/src/Kurs.Platform.Application.Contracts/Forum/ForumTopicDto.cs delete mode 100644 api/src/Kurs.Platform.Application.Contracts/Forum/IForumAppService.cs create mode 100644 api/src/Kurs.Platform.Application/Blog/BlogAutoMapperProfile.cs delete mode 100644 api/src/Kurs.Platform.Application/Forum/ForumAppService.cs delete mode 100644 api/src/Kurs.Platform.Application/PlatformApplicationAutoMapperProfile.cs delete mode 100644 api/src/Kurs.Platform.Domain/Data/ForumDataSeedContributor.cs delete mode 100644 api/src/Kurs.Platform.Domain/Forum/ForumCategory.cs delete mode 100644 api/src/Kurs.Platform.Domain/Forum/ForumPost.cs delete mode 100644 api/src/Kurs.Platform.Domain/Forum/ForumPostLike.cs delete mode 100644 api/src/Kurs.Platform.Domain/Forum/ForumTopic.cs delete mode 100644 api/src/Kurs.Platform.Domain/Forum/ForumTopicLike.cs delete mode 100644 api/src/Kurs.Platform.Domain/Forum/ForumTopicTag.cs delete mode 100644 api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.cs rename api/src/Kurs.Platform.EntityFrameworkCore/Migrations/{20250620094517_AddBlogForumEntities.Designer.cs => 20250622112214_AddBlogEntities.Designer.cs} (92%) create mode 100644 api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.cs delete mode 100644 company/src/pages/Forum.tsx delete mode 100644 company/src/pages/ForumCategory.tsx delete mode 100644 company/src/pages/Login.tsx delete mode 100644 company/src/pages/LoginWithTenant.tsx delete mode 100644 company/src/pages/Profile.tsx delete mode 100644 company/src/pages/Register.tsx delete mode 100644 company/src/services/api/auth.service.ts delete mode 100644 company/src/services/api/forum.service.ts delete mode 100644 company/src/store/authStore.ts delete mode 100644 ui/src/services/forum.service.ts delete mode 100644 ui/src/services/rest.service.ts delete mode 100644 ui/src/views/forum/ForumManagement.tsx diff --git a/api/src/Kurs.Platform.Application.Contracts/Forum/ForumCategoryDto.cs b/api/src/Kurs.Platform.Application.Contracts/Forum/ForumCategoryDto.cs deleted file mode 100644 index dda837fe..00000000 --- a/api/src/Kurs.Platform.Application.Contracts/Forum/ForumCategoryDto.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using Volo.Abp.Application.Dtos; - -namespace Kurs.Platform.Forum -{ - public class ForumCategoryDto : FullAuditedEntityDto - { - public string Name { get; set; } - public string Slug { get; set; } - public string Description { get; set; } - public string Icon { get; set; } - public int DisplayOrder { get; set; } - public bool IsActive { get; set; } - public bool IsLocked { get; set; } - - public int TopicCount { get; set; } - public int PostCount { get; set; } - - public Guid? LastPostId { get; set; } - public DateTime? LastPostDate { get; set; } - public string LastPostUserName { get; set; } - } - - public class CreateUpdateForumCategoryDto - { - public string Name { get; set; } - public string Slug { get; set; } - public string Description { get; set; } - public string Icon { get; set; } - public int DisplayOrder { get; set; } - public bool IsActive { get; set; } - public bool IsLocked { get; set; } - } -} diff --git a/api/src/Kurs.Platform.Application.Contracts/Forum/ForumPostDto.cs b/api/src/Kurs.Platform.Application.Contracts/Forum/ForumPostDto.cs deleted file mode 100644 index 5ce2970d..00000000 --- a/api/src/Kurs.Platform.Application.Contracts/Forum/ForumPostDto.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using Volo.Abp.Application.Dtos; - -namespace Kurs.Platform.Forum -{ - public class ForumPostDto : FullAuditedEntityDto - { - public Guid? TopicId { get; set; } - public Guid? CategoryId { get; set; } - public string Title { get; set; } - public string Content { get; set; } - public Guid AuthorId { get; set; } - public AuthorDto Author { get; set; } - public Guid? ParentId { get; set; } - public int LikeCount { get; set; } - public int ViewCount { get; set; } - public int ReplyCount { get; set; } - public bool IsLiked { get; set; } - public bool IsBestAnswer { get; set; } - public bool IsEdited { get; set; } - public DateTime? EditedAt { get; set; } - public List Tags { get; set; } - public LastReplyDto LastReply { get; set; } - public List Replies { get; set; } - } - - public class CreatePostRequest - { - public Guid? TopicId { get; set; } - public Guid? CategoryId { get; set; } - public string Title { get; set; } - public string Content { get; set; } - public Guid? ParentId { get; set; } - public List Tags { get; set; } - } - - public class LastReplyDto - { - public Guid Id { get; set; } - public AuthorDto Author { get; set; } - public DateTime CreationTime { get; set; } - } -} diff --git a/api/src/Kurs.Platform.Application.Contracts/Forum/ForumTopicDto.cs b/api/src/Kurs.Platform.Application.Contracts/Forum/ForumTopicDto.cs deleted file mode 100644 index 54144414..00000000 --- a/api/src/Kurs.Platform.Application.Contracts/Forum/ForumTopicDto.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using Volo.Abp.Application.Dtos; - -namespace Kurs.Platform.Forum -{ - public class ForumTopicDto : FullAuditedEntityDto - { - public string Title { get; set; } - public string Content { get; set; } - - public Guid CategoryId { get; set; } - public ForumCategoryDto Category { get; set; } - - public AuthorDto Author { get; set; } - - public int ViewCount { get; set; } - public int ReplyCount { get; set; } - public int LikeCount { get; set; } - - public bool IsPinned { get; set; } - public bool IsLocked { get; set; } - public bool IsSolved { get; set; } - - public Guid? LastPostId { get; set; } - public DateTime? LastPostDate { get; set; } - public string LastPostUserName { get; set; } - - public List Tags { get; set; } - public bool IsLiked { get; set; } - - public ForumTopicDto() - { - Tags = new List(); - } - } - - public class AuthorDto - { - public Guid Id { get; set; } - public string Name { get; set; } - public string Avatar { get; set; } - } - - public class CreateForumTopicDto - { - public string Title { get; set; } - public string Content { get; set; } - public Guid CategoryId { get; set; } - public List Tags { get; set; } - - public CreateForumTopicDto() - { - Tags = new List(); - } - } - - public class UpdateForumTopicDto - { - public string Title { get; set; } - public string Content { get; set; } - public List Tags { get; set; } - - public UpdateForumTopicDto() - { - Tags = new List(); - } - } - - public class ForumTopicListDto : EntityDto - { - public string Title { get; set; } - public Guid CategoryId { get; set; } - public string CategoryName { get; set; } - - public AuthorDto Author { get; set; } - - public int ViewCount { get; set; } - public int ReplyCount { get; set; } - public int LikeCount { get; set; } - - public bool IsPinned { get; set; } - public bool IsLocked { get; set; } - public bool IsSolved { get; set; } - - public DateTime? LastPostDate { get; set; } - public string LastPostUserName { get; set; } - - public DateTime CreatedAt { get; set; } - - public List Tags { get; set; } - - public ForumTopicListDto() - { - Tags = new List(); - } - } - - public class ForumStatsDto - { - public int TotalCategories { get; set; } - public int TotalTopics { get; set; } - public int TotalPosts { get; set; } - public int TotalUsers { get; set; } - public int OnlineUsers { get; set; } - public ForumTopicListDto LatestTopic { get; set; } - public List PopularTags { get; set; } - - public ForumStatsDto() - { - PopularTags = new List(); - } - } -} diff --git a/api/src/Kurs.Platform.Application.Contracts/Forum/IForumAppService.cs b/api/src/Kurs.Platform.Application.Contracts/Forum/IForumAppService.cs deleted file mode 100644 index 0882cd92..00000000 --- a/api/src/Kurs.Platform.Application.Contracts/Forum/IForumAppService.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; - -namespace Kurs.Platform.Forum -{ - public interface IForumAppService : IApplicationService - { - // Category methods - Task> GetCategoriesAsync(); - Task GetCategoryAsync(Guid id); - Task GetCategoryBySlugAsync(string slug); - Task> GetPostsByCategoryAsync(Guid categoryId, int page = 1, int pageSize = 20); - Task CreateCategoryAsync(CreateUpdateForumCategoryDto input); - Task UpdateCategoryAsync(Guid id, CreateUpdateForumCategoryDto input); - Task DeleteCategoryAsync(Guid id); - - // Topic methods - Task> GetTopicsAsync(GetForumTopicsInput input); - Task GetTopicAsync(Guid id); - Task CreateTopicAsync(CreateForumTopicDto input); - Task UpdateTopicAsync(Guid id, UpdateForumTopicDto input); - Task DeleteTopicAsync(Guid id); - - // Topic actions - Task PinTopicAsync(Guid id); - Task UnpinTopicAsync(Guid id); - Task LockTopicAsync(Guid id); - Task UnlockTopicAsync(Guid id); - Task MarkAsSolvedAsync(Guid id); - Task MarkAsUnsolvedAsync(Guid id); - Task LikeTopicAsync(Guid id); - Task UnlikeTopicAsync(Guid id); - Task IncrementViewCountAsync(Guid id); - - // Search and filters - Task> SearchTopicsAsync(SearchForumTopicsInput input); - Task> GetMyTopicsAsync(PagedAndSortedResultRequestDto input); - Task> GetTopicsByTagAsync(string tag, PagedAndSortedResultRequestDto input); - - // Stats - Task GetStatsAsync(); - Task> GetPopularTagsAsync(int count = 20); - } - - public class GetForumTopicsInput : PagedAndSortedResultRequestDto - { - public Guid? CategoryId { get; set; } - public string Filter { get; set; } - public bool? IsPinned { get; set; } - public bool? IsLocked { get; set; } - public bool? IsSolved { get; set; } - public string SortBy { get; set; } = "latest"; // latest, popular, mostviewed - } - - public class SearchForumTopicsInput : PagedAndSortedResultRequestDto - { - public string Query { get; set; } - public Guid? CategoryId { get; set; } - public string Tag { get; set; } - public Guid? AuthorId { get; set; } - public bool? IsSolved { get; set; } - } -} diff --git a/api/src/Kurs.Platform.Application/Blog/BlogAutoMapperProfile.cs b/api/src/Kurs.Platform.Application/Blog/BlogAutoMapperProfile.cs new file mode 100644 index 00000000..45f8a95a --- /dev/null +++ b/api/src/Kurs.Platform.Application/Blog/BlogAutoMapperProfile.cs @@ -0,0 +1,15 @@ +using AutoMapper; +using Kurs.Platform.Blog; + +namespace Kurs.Platform; + +public class BlogAutoMapperProfile : Profile +{ + public BlogAutoMapperProfile() + { + // Blog mappings + CreateMap(); + CreateMap(); + CreateMap(); + } +} diff --git a/api/src/Kurs.Platform.Application/Forum/ForumAppService.cs b/api/src/Kurs.Platform.Application/Forum/ForumAppService.cs deleted file mode 100644 index 0037c193..00000000 --- a/api/src/Kurs.Platform.Application/Forum/ForumAppService.cs +++ /dev/null @@ -1,648 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Volo.Abp; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Domain.Repositories; -using Volo.Abp.Users; - -namespace Kurs.Platform.Forum -{ - [Authorize] - public class ForumAppService : PlatformAppService, IForumAppService - { - private readonly IRepository _categoryRepository; - private readonly IRepository _topicRepository; - private readonly IRepository _postRepository; - private readonly IRepository _tagRepository; - private readonly IRepository _topicLikeRepository; - private readonly ICurrentUser _currentUser; - - public ForumAppService( - IRepository categoryRepository, - IRepository topicRepository, - IRepository postRepository, - IRepository tagRepository, - IRepository topicLikeRepository, - ICurrentUser currentUser) - { - _categoryRepository = categoryRepository; - _topicRepository = topicRepository; - _postRepository = postRepository; - _tagRepository = tagRepository; - _topicLikeRepository = topicLikeRepository; - _currentUser = currentUser; - } - - // Category methods - public async Task> GetCategoriesAsync() - { - var categories = await _categoryRepository.GetListAsync(x => x.IsActive); - - return ObjectMapper.Map, List>(categories); - } - - public async Task GetCategoryAsync(Guid id) - { - var category = await _categoryRepository.GetAsync(id); - return ObjectMapper.Map(category); - } - - public async Task GetCategoryBySlugAsync(string slug) - { - var category = await _categoryRepository.FirstOrDefaultAsync(x => x.Slug == slug); - if (category == null) - { - throw new Volo.Abp.Domain.Entities.EntityNotFoundException(typeof(ForumCategory), slug); - } - return ObjectMapper.Map(category); - } - - public async Task> GetPostsByCategoryAsync(Guid categoryId, int page = 1, int pageSize = 20) - { - var topics = await _topicRepository.GetListAsync(x => x.CategoryId == categoryId); - var posts = new List(); - - foreach (var topic in topics.Skip((page - 1) * pageSize).Take(pageSize)) - { - var post = new ForumPostDto - { - Id = topic.Id, - CategoryId = topic.CategoryId, - Title = topic.Title, - Content = topic.Content, - ViewCount = topic.ViewCount, - ReplyCount = topic.ReplyCount, - LikeCount = topic.LikeCount, - CreationTime = topic.CreationTime - }; - - // Get author info - post.Author = new AuthorDto - { - Id = topic.AuthorId, - Name = "User" - }; - - // Get tags - var tags = await _tagRepository.GetListAsync(x => x.TopicId == topic.Id); - post.Tags = tags.Select(x => x.Tag).ToList(); - - // Get last reply - var lastPost = await _postRepository - .GetListAsync(x => x.TopicId == topic.Id) - .ContinueWith(t => t.Result.OrderByDescending(x => x.CreationTime).FirstOrDefault()); - - if (lastPost != null) - { - post.LastReply = new LastReplyDto - { - Id = lastPost.Id, - Author = new AuthorDto - { - Id = lastPost.AuthorId, - Name = "User" - }, - CreationTime = lastPost.CreationTime - }; - } - - posts.Add(post); - } - - return posts; - } - - public async Task CreateCategoryAsync(CreateUpdateForumCategoryDto input) - { - var category = new ForumCategory( - GuidGenerator.Create(), - input.Name, - input.Slug, - input.Description, - input.Icon, - input.DisplayOrder, - CurrentTenant.Id - ); - - category.IsActive = input.IsActive; - category.IsLocked = input.IsLocked; - - await _categoryRepository.InsertAsync(category); - - return ObjectMapper.Map(category); - } - - public async Task UpdateCategoryAsync(Guid id, CreateUpdateForumCategoryDto input) - { - var category = await _categoryRepository.GetAsync(id); - - category.Name = input.Name; - category.Slug = input.Slug; - category.Description = input.Description; - category.Icon = input.Icon; - category.DisplayOrder = input.DisplayOrder; - category.IsActive = input.IsActive; - category.IsLocked = input.IsLocked; - - await _categoryRepository.UpdateAsync(category); - - return ObjectMapper.Map(category); - } - - public async Task DeleteCategoryAsync(Guid id) - { - await _categoryRepository.DeleteAsync(id); - } - - // Topic methods - public async Task> GetTopicsAsync(GetForumTopicsInput input) - { - var query = await _topicRepository.GetQueryableAsync(); - - if (input.CategoryId.HasValue) - { - query = query.Where(x => x.CategoryId == input.CategoryId.Value); - } - - if (!string.IsNullOrWhiteSpace(input.Filter)) - { - query = query.Where(x => x.Title.Contains(input.Filter)); - } - - if (input.IsPinned.HasValue) - { - query = query.Where(x => x.IsPinned == input.IsPinned.Value); - } - - if (input.IsLocked.HasValue) - { - query = query.Where(x => x.IsLocked == input.IsLocked.Value); - } - - if (input.IsSolved.HasValue) - { - query = query.Where(x => x.IsSolved == input.IsSolved.Value); - } - - // Sorting - if (input.SortBy == "popular") - { - query = query.OrderByDescending(x => x.LikeCount); - } - else if (input.SortBy == "mostviewed") - { - query = query.OrderByDescending(x => x.ViewCount); - } - else // latest - { - query = query.OrderByDescending(x => x.CreationTime); - } - - var totalCount = await AsyncExecuter.CountAsync(query); - var topics = await AsyncExecuter.ToListAsync( - query.Skip(input.SkipCount).Take(input.MaxResultCount) - ); - - var topicDtos = new List(); - foreach (var topic in topics) - { - var dto = ObjectMapper.Map(topic); - - // Get category name - var category = await _categoryRepository.GetAsync(topic.CategoryId); - dto.CategoryName = category.Name; - - // Get author info - dto.Author = new AuthorDto - { - Id = topic.AuthorId, - Name = "User" - }; - - // Get tags - var tags = await _tagRepository.GetListAsync(x => x.TopicId == topic.Id); - dto.Tags = tags.Select(x => x.Tag).ToList(); - - topicDtos.Add(dto); - } - - return new PagedResultDto(totalCount, topicDtos); - } - - public async Task GetTopicAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - var dto = ObjectMapper.Map(topic); - - // Get category - dto.Category = ObjectMapper.Map( - await _categoryRepository.GetAsync(topic.CategoryId) - ); - - // Get author info - dto.Author = new AuthorDto - { - Id = topic.AuthorId, - Name = "User" - }; - - // Get tags - var tags = await _tagRepository.GetListAsync(x => x.TopicId == topic.Id); - dto.Tags = tags.Select(x => x.Tag).ToList(); - - // Check if current user liked this topic - if (_currentUser.IsAuthenticated) - { - dto.IsLiked = await _topicLikeRepository.AnyAsync( - x => x.TopicId == id && x.UserId == _currentUser.Id.Value - ); - } - - return dto; - } - - public async Task CreateTopicAsync(CreateForumTopicDto input) - { - var topic = new ForumTopic( - GuidGenerator.Create(), - input.Title, - input.Content, - input.CategoryId, - _currentUser.Id.Value, - CurrentTenant.Id - ); - - await _topicRepository.InsertAsync(topic); - - // Add tags - foreach (var tag in input.Tags) - { - await _tagRepository.InsertAsync(new ForumTopicTag( - GuidGenerator.Create(), - topic.Id, - tag, - CurrentTenant.Id - )); - } - - // Update category counts - var category = await _categoryRepository.GetAsync(input.CategoryId); - category.IncrementTopicCount(); - await _categoryRepository.UpdateAsync(category); - - return await GetTopicAsync(topic.Id); - } - - public async Task UpdateTopicAsync(Guid id, UpdateForumTopicDto input) - { - var topic = await _topicRepository.GetAsync(id); - - // Check if user is author or has permission - if (topic.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("Forum.Topics.Update")) - { - throw new Volo.Abp.Authorization.AbpAuthorizationException(); - } - - topic.Title = input.Title; - topic.Content = input.Content; - - await _topicRepository.UpdateAsync(topic); - - // Update tags - await _tagRepository.DeleteAsync(x => x.TopicId == id); - foreach (var tag in input.Tags) - { - await _tagRepository.InsertAsync(new ForumTopicTag( - GuidGenerator.Create(), - topic.Id, - tag, - CurrentTenant.Id - )); - } - - return await GetTopicAsync(topic.Id); - } - - public async Task DeleteTopicAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - - // Check if user is author or has permission - if (topic.AuthorId != _currentUser.Id && !await AuthorizationService.IsGrantedAsync("Forum.Topics.Delete")) - { - throw new Volo.Abp.Authorization.AbpAuthorizationException(); - } - - // Update category counts - var category = await _categoryRepository.GetAsync(topic.CategoryId); - category.DecrementTopicCount(); - await _categoryRepository.UpdateAsync(category); - - await _topicRepository.DeleteAsync(id); - } - - // Topic actions - public async Task PinTopicAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - topic.Pin(); - await _topicRepository.UpdateAsync(topic); - return await GetTopicAsync(id); - } - - public async Task UnpinTopicAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - topic.Unpin(); - await _topicRepository.UpdateAsync(topic); - return await GetTopicAsync(id); - } - - public async Task LockTopicAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - topic.Lock(); - await _topicRepository.UpdateAsync(topic); - return await GetTopicAsync(id); - } - - public async Task UnlockTopicAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - topic.Unlock(); - await _topicRepository.UpdateAsync(topic); - return await GetTopicAsync(id); - } - - public async Task MarkAsSolvedAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - - // Only author can mark as solved - if (topic.AuthorId != _currentUser.Id) - { - throw new Volo.Abp.Authorization.AbpAuthorizationException(); - } - - topic.MarkAsSolved(); - await _topicRepository.UpdateAsync(topic); - return await GetTopicAsync(id); - } - - public async Task MarkAsUnsolvedAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - - // Only author can mark as unsolved - if (topic.AuthorId != _currentUser.Id) - { - throw new Volo.Abp.Authorization.AbpAuthorizationException(); - } - - topic.MarkAsUnsolved(); - await _topicRepository.UpdateAsync(topic); - return await GetTopicAsync(id); - } - - public async Task LikeTopicAsync(Guid id) - { - var existingLike = await _topicLikeRepository.FirstOrDefaultAsync( - x => x.TopicId == id && x.UserId == _currentUser.Id.Value - ); - - if (existingLike == null) - { - await _topicLikeRepository.InsertAsync(new ForumTopicLike( - GuidGenerator.Create(), - id, - _currentUser.Id.Value, - CurrentTenant.Id - )); - - // Update like count - var topic = await _topicRepository.GetAsync(id); - var likeCount = await _topicLikeRepository.CountAsync(x => x.TopicId == id); - topic.UpdateLikeCount((int)likeCount); - await _topicRepository.UpdateAsync(topic); - } - } - - public async Task UnlikeTopicAsync(Guid id) - { - var existingLike = await _topicLikeRepository.FirstOrDefaultAsync( - x => x.TopicId == id && x.UserId == _currentUser.Id.Value - ); - - if (existingLike != null) - { - await _topicLikeRepository.DeleteAsync(existingLike); - - // Update like count - var topic = await _topicRepository.GetAsync(id); - var likeCount = await _topicLikeRepository.CountAsync(x => x.TopicId == id); - topic.UpdateLikeCount((int)likeCount); - await _topicRepository.UpdateAsync(topic); - } - } - - [AllowAnonymous] - public async Task IncrementViewCountAsync(Guid id) - { - var topic = await _topicRepository.GetAsync(id); - topic.IncrementViewCount(); - await _topicRepository.UpdateAsync(topic); - } - - // Search and filters - public async Task> SearchTopicsAsync(SearchForumTopicsInput input) - { - var query = await _topicRepository.GetQueryableAsync(); - - if (!string.IsNullOrWhiteSpace(input.Query)) - { - query = query.Where(x => - x.Title.Contains(input.Query) || - x.Content.Contains(input.Query) - ); - } - - if (input.CategoryId.HasValue) - { - query = query.Where(x => x.CategoryId == input.CategoryId.Value); - } - - if (input.AuthorId.HasValue) - { - query = query.Where(x => x.AuthorId == input.AuthorId.Value); - } - - if (input.IsSolved.HasValue) - { - query = query.Where(x => x.IsSolved == input.IsSolved.Value); - } - - // Search by tag - if (!string.IsNullOrWhiteSpace(input.Tag)) - { - var topicIds = await _tagRepository - .GetListAsync(x => x.Tag == input.Tag) - .ContinueWith(t => t.Result.Select(x => x.TopicId).ToList()); - - query = query.Where(x => topicIds.Contains(x.Id)); - } - - var totalCount = await AsyncExecuter.CountAsync(query); - var topics = await AsyncExecuter.ToListAsync( - query.OrderByDescending(x => x.CreationTime) - .Skip(input.SkipCount) - .Take(input.MaxResultCount) - ); - - var topicDtos = new List(); - foreach (var topic in topics) - { - var dto = ObjectMapper.Map(topic); - - // Get category name - var category = await _categoryRepository.GetAsync(topic.CategoryId); - dto.CategoryName = category.Name; - - // Get author info - dto.Author = new AuthorDto - { - Id = topic.AuthorId, - Name = "User" - }; - - // Get tags - var tags = await _tagRepository.GetListAsync(x => x.TopicId == topic.Id); - dto.Tags = tags.Select(x => x.Tag).ToList(); - - topicDtos.Add(dto); - } - - return new PagedResultDto(totalCount, topicDtos); - } - - public async Task> GetMyTopicsAsync(PagedAndSortedResultRequestDto input) - { - var searchInput = new GetForumTopicsInput - { - MaxResultCount = input.MaxResultCount, - SkipCount = input.SkipCount, - Sorting = input.Sorting - }; - - var query = await _topicRepository.GetQueryableAsync(); - query = query.Where(x => x.AuthorId == _currentUser.Id.Value); - - var totalCount = await AsyncExecuter.CountAsync(query); - var topics = await AsyncExecuter.ToListAsync( - query.OrderByDescending(x => x.CreationTime) - .Skip(input.SkipCount) - .Take(input.MaxResultCount) - ); - - var topicDtos = new List(); - foreach (var topic in topics) - { - var dto = ObjectMapper.Map(topic); - - // Get category name - var category = await _categoryRepository.GetAsync(topic.CategoryId); - dto.CategoryName = category.Name; - - // Get author info - dto.Author = new AuthorDto - { - Id = topic.AuthorId, - Name = _currentUser.Name ?? _currentUser.UserName - }; - - // Get tags - var tags = await _tagRepository.GetListAsync(x => x.TopicId == topic.Id); - dto.Tags = tags.Select(x => x.Tag).ToList(); - - topicDtos.Add(dto); - } - - return new PagedResultDto(totalCount, topicDtos); - } - - public async Task> GetTopicsByTagAsync(string tag, PagedAndSortedResultRequestDto input) - { - var searchInput = new SearchForumTopicsInput - { - Tag = tag, - MaxResultCount = input.MaxResultCount, - SkipCount = input.SkipCount, - Sorting = input.Sorting - }; - - return await SearchTopicsAsync(searchInput); - } - - // Stats - [AllowAnonymous] - public async Task GetStatsAsync() - { - var stats = new ForumStatsDto - { - TotalCategories = (int)await _categoryRepository.CountAsync(x => x.IsActive), - TotalTopics = (int)await _topicRepository.CountAsync(), - TotalPosts = (int)await _postRepository.CountAsync(), - TotalUsers = 100, // You should get this from identity service - OnlineUsers = 10, // You should implement online user tracking - PopularTags = await GetPopularTagsAsync(10) - }; - - // Get latest topic - var latestTopic = await _topicRepository - .GetQueryableAsync() - .ContinueWith(async t => - { - var query = await t; - return await AsyncExecuter.FirstOrDefaultAsync( - query.OrderByDescending(x => x.CreationTime) - ); - }) - .Unwrap(); - - if (latestTopic != null) - { - var dto = ObjectMapper.Map(latestTopic); - - // Get category name - var category = await _categoryRepository.GetAsync(latestTopic.CategoryId); - dto.CategoryName = category.Name; - - // Get author info - dto.Author = new AuthorDto - { - Id = latestTopic.AuthorId, - Name = "User" - }; - - stats.LatestTopic = dto; - } - - return stats; - } - - [AllowAnonymous] - public async Task> GetPopularTagsAsync(int count = 20) - { - var tags = await _tagRepository.GetListAsync(); - - return tags - .GroupBy(x => x.Tag) - .OrderByDescending(g => g.Count()) - .Take(count) - .Select(g => g.Key) - .ToList(); - } - } -} diff --git a/api/src/Kurs.Platform.Application/PlatformApplicationAutoMapperProfile.cs b/api/src/Kurs.Platform.Application/PlatformApplicationAutoMapperProfile.cs deleted file mode 100644 index e6b73c00..00000000 --- a/api/src/Kurs.Platform.Application/PlatformApplicationAutoMapperProfile.cs +++ /dev/null @@ -1,26 +0,0 @@ -using AutoMapper; -using Kurs.Platform.Blog; -using Kurs.Platform.Forum; - -namespace Kurs.Platform; - -public class PlatformApplicationAutoMapperProfile : Profile -{ - public PlatformApplicationAutoMapperProfile() - { - /* You can configure your AutoMapper mapping configuration here. - * Alternatively, you can split your mapping configurations - * into multiple profile classes for a better organization. */ - - // Blog mappings - CreateMap(); - CreateMap(); - CreateMap(); - - // Forum mappings - CreateMap(); - CreateMap(); - CreateMap() - .ForMember(dest => dest.CreatedAt, opt => opt.MapFrom(src => src.CreationTime)); - } -} diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json index eed6f5ab..d93a16ca 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json @@ -6354,16 +6354,6 @@ "RequiredPermissionName": "App.Blog", "IsDisabled": false }, - { - "ParentCode": "App.Saas", - "Code": "App.Forum", - "DisplayName": "App.Forum", - "Order": 11, - "Url": "/admin/forum", - "Icon": "FcReading", - "RequiredPermissionName": "App.Forum", - "IsDisabled": false - }, { "ParentCode": "App.Administration", "Code": "Abp.Identity", @@ -6525,10 +6515,6 @@ { "Name": "App.Blog", "DisplayName": "App.Blog" - }, - { - "Name": "App.Forum", - "DisplayName": "App.Forum" } ], "PermissionDefinitionRecords": [ @@ -6732,14 +6718,6 @@ "IsEnabled": true, "MultiTenancySide": 2 }, - { - "GroupName": "App.Forum", - "Name": "App.Forum", - "ParentName": null, - "DisplayName": "App.Forum", - "IsEnabled": true, - "MultiTenancySide": 2 - }, { "GroupName": "App.Setting", "Name": "Abp.Account", @@ -7779,38 +7757,6 @@ "DisplayName": "Update", "IsEnabled": true, "MultiTenancySide": 2 - }, - { - "GroupName": "App.Forum", - "Name": "App.Forum.Create", - "ParentName": "App.Forum", - "DisplayName": "Create", - "IsEnabled": true, - "MultiTenancySide": 2 - }, - { - "GroupName": "App.Forum", - "Name": "App.Forum.Delete", - "ParentName": "App.Forum", - "DisplayName": "Delete", - "IsEnabled": true, - "MultiTenancySide": 2 - }, - { - "GroupName": "App.Forum", - "Name": "App.Forum.Export", - "ParentName": "App.Forum", - "DisplayName": "Export", - "IsEnabled": true, - "MultiTenancySide": 2 - }, - { - "GroupName": "App.Forum", - "Name": "App.Forum.Update", - "ParentName": "App.Forum", - "DisplayName": "Update", - "IsEnabled": true, - "MultiTenancySide": 2 } ], "Sectors": [ @@ -20210,40 +20156,6 @@ "Abbreviation": "Prof." } ], - "ForumCategories": [ - { - "Name": "Genel Tartışma", - "Slug": "genel-tartisma", - "Description": "Her türlü konunun tartışılabileceği genel forum alanı", - "Icon": "💬", - "Order": 1, - "IsActive": true - }, - { - "Name": "Teknik Destek", - "Slug": "teknik-destek", - "Description": "Teknik sorunlar ve çözümler için destek forumu", - "Icon": "🔧", - "Order": 2, - "IsActive": true - }, - { - "Name": "Öneriler", - "Slug": "oneriler", - "Description": "Platform geliştirmeleri için öneri ve istekler", - "Icon": "💡", - "Order": 3, - "IsActive": true - }, - { - "Name": "Duyurular", - "Slug": "duyurular", - "Description": "Platform duyuruları ve güncellemeler", - "Icon": "📢", - "Order": 4, - "IsActive": true - } - ], "BlogCategories": [ { "Id": "1e97bf2c-dec8-50bb-af20-70e71d752871", diff --git a/api/src/Kurs.Platform.Domain/Data/ForumDataSeedContributor.cs b/api/src/Kurs.Platform.Domain/Data/ForumDataSeedContributor.cs deleted file mode 100644 index 9915e85e..00000000 --- a/api/src/Kurs.Platform.Domain/Data/ForumDataSeedContributor.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Threading.Tasks; -using Kurs.Platform.Forum; -using Volo.Abp.Data; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Domain.Repositories; -using Volo.Abp.Guids; - -namespace Kurs.Platform.Data -{ - public class ForumDataSeedContributor : IDataSeedContributor, ITransientDependency - { - private readonly IRepository _categoryRepository; - private readonly IGuidGenerator _guidGenerator; - - public ForumDataSeedContributor( - IRepository categoryRepository, - IGuidGenerator guidGenerator) - { - _categoryRepository = categoryRepository; - _guidGenerator = guidGenerator; - } - - public async Task SeedAsync(DataSeedContext context) - { - if (await _categoryRepository.AnyAsync()) - { - return; - } - - var categories = new[] - { - new { Name = "Genel Tartışma", Slug = "genel-tartisma", Description = "Her türlü konunun tartışılabileceği genel forum", Icon = "message-circle", DisplayOrder = 1 }, - new { Name = "Duyurular", Slug = "duyurular", Description = "Sistem duyuruları ve haberler", Icon = "megaphone", DisplayOrder = 2 }, - new { Name = "Teknik Destek", Slug = "teknik-destek", Description = "Teknik sorunlar ve çözümler", Icon = "wrench", DisplayOrder = 3 }, - new { Name = "Öneriler", Slug = "oneriler", Description = "Sistem için öneri ve istekler", Icon = "lightbulb", DisplayOrder = 4 }, - new { Name = "Eğitim", Slug = "egitim", Description = "Eğitim materyalleri ve kaynaklar", Icon = "book", DisplayOrder = 5 } - }; - - foreach (var cat in categories) - { - await _categoryRepository.InsertAsync( - new ForumCategory( - _guidGenerator.Create(), - cat.Name, - cat.Slug, - cat.Description, - cat.Icon, - cat.DisplayOrder, - context.TenantId - ), - autoSave: true - ); - } - } - - } -} diff --git a/api/src/Kurs.Platform.Domain/Forum/ForumCategory.cs b/api/src/Kurs.Platform.Domain/Forum/ForumCategory.cs deleted file mode 100644 index 5b5c9677..00000000 --- a/api/src/Kurs.Platform.Domain/Forum/ForumCategory.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace Kurs.Platform.Forum -{ - public class ForumCategory : FullAuditedEntity, IMultiTenant - { - public Guid? TenantId { get; set; } - - public string Name { get; set; } - public string Slug { get; set; } - public string Description { get; set; } - public string Icon { get; set; } - public int DisplayOrder { get; set; } - public bool IsActive { get; set; } - public bool IsLocked { get; set; } - - public int TopicCount { get; set; } - public int PostCount { get; set; } - - public Guid? LastPostId { get; set; } - public DateTime? LastPostDate { get; set; } - public Guid? LastPostUserId { get; set; } - - public virtual ICollection Topics { get; set; } - - protected ForumCategory() - { - Topics = new HashSet(); - } - - public ForumCategory( - Guid id, - string name, - string slug, - string description, - string icon = null, - int displayOrder = 0, - Guid? tenantId = null) : base(id) - { - Name = name; - Slug = slug; - Description = description; - Icon = icon; - DisplayOrder = displayOrder; - TenantId = tenantId; - IsActive = true; - IsLocked = false; - TopicCount = 0; - PostCount = 0; - - Topics = new HashSet(); - } - - public void UpdateLastPost(Guid postId, Guid userId) - { - LastPostId = postId; - LastPostDate = DateTime.UtcNow; - LastPostUserId = userId; - } - - public void IncrementTopicCount() - { - TopicCount++; - } - - public void DecrementTopicCount() - { - if (TopicCount > 0) - TopicCount--; - } - - public void IncrementPostCount() - { - PostCount++; - } - - public void DecrementPostCount() - { - if (PostCount > 0) - PostCount--; - } - } -} diff --git a/api/src/Kurs.Platform.Domain/Forum/ForumPost.cs b/api/src/Kurs.Platform.Domain/Forum/ForumPost.cs deleted file mode 100644 index f8fa63d8..00000000 --- a/api/src/Kurs.Platform.Domain/Forum/ForumPost.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace Kurs.Platform.Forum -{ - public class ForumPost : FullAuditedEntity, IMultiTenant - { - public Guid? TenantId { get; set; } - - public Guid TopicId { get; set; } - public virtual ForumTopic Topic { get; set; } - - public string Content { get; set; } - - public Guid AuthorId { get; set; } - - public int LikeCount { get; set; } - - public bool IsAcceptedAnswer { get; set; } - - public virtual ICollection Likes { get; set; } - - protected ForumPost() - { - Likes = new HashSet(); - } - - public ForumPost( - Guid id, - Guid topicId, - string content, - Guid authorId, - Guid? tenantId = null) : base(id) - { - TopicId = topicId; - Content = content; - AuthorId = authorId; - TenantId = tenantId; - LikeCount = 0; - IsAcceptedAnswer = false; - - Likes = new HashSet(); - } - - public void UpdateLikeCount(int count) - { - LikeCount = count; - } - - public void MarkAsAcceptedAnswer() - { - IsAcceptedAnswer = true; - } - - public void UnmarkAsAcceptedAnswer() - { - IsAcceptedAnswer = false; - } - } -} diff --git a/api/src/Kurs.Platform.Domain/Forum/ForumPostLike.cs b/api/src/Kurs.Platform.Domain/Forum/ForumPostLike.cs deleted file mode 100644 index c6494e25..00000000 --- a/api/src/Kurs.Platform.Domain/Forum/ForumPostLike.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace Kurs.Platform.Forum -{ - public class ForumPostLike : CreationAuditedEntity, IMultiTenant - { - public Guid? TenantId { get; set; } - - public Guid PostId { get; set; } - public virtual ForumPost Post { get; set; } - - public Guid UserId { get; set; } - - protected ForumPostLike() - { - } - - public ForumPostLike( - Guid id, - Guid postId, - Guid userId, - Guid? tenantId = null) : base(id) - { - PostId = postId; - UserId = userId; - TenantId = tenantId; - } - } -} diff --git a/api/src/Kurs.Platform.Domain/Forum/ForumTopic.cs b/api/src/Kurs.Platform.Domain/Forum/ForumTopic.cs deleted file mode 100644 index cc5fef10..00000000 --- a/api/src/Kurs.Platform.Domain/Forum/ForumTopic.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace Kurs.Platform.Forum -{ - public class ForumTopic : FullAuditedAggregateRoot, IMultiTenant - { - public Guid? TenantId { get; set; } - - public string Title { get; set; } - public string Content { get; set; } - - public Guid CategoryId { get; set; } - public virtual ForumCategory Category { get; set; } - - public Guid AuthorId { get; set; } - - public int ViewCount { get; set; } - public int ReplyCount { get; set; } - public int LikeCount { get; set; } - - public bool IsPinned { get; set; } - public bool IsLocked { get; set; } - public bool IsSolved { get; set; } - - public Guid? LastPostId { get; set; } - public DateTime? LastPostDate { get; set; } - public Guid? LastPostUserId { get; set; } - - public virtual ICollection Posts { get; set; } - public virtual ICollection Tags { get; set; } - public virtual ICollection Likes { get; set; } - - protected ForumTopic() - { - Posts = new HashSet(); - Tags = new HashSet(); - Likes = new HashSet(); - } - - public ForumTopic( - Guid id, - string title, - string content, - Guid categoryId, - Guid authorId, - Guid? tenantId = null) : base(id) - { - Title = title; - Content = content; - CategoryId = categoryId; - AuthorId = authorId; - TenantId = tenantId; - - ViewCount = 0; - ReplyCount = 0; - LikeCount = 0; - IsPinned = false; - IsLocked = false; - IsSolved = false; - - Posts = new HashSet(); - Tags = new HashSet(); - Likes = new HashSet(); - } - - public void IncrementViewCount() - { - ViewCount++; - } - - public void UpdateLastPost(Guid postId, Guid userId) - { - LastPostId = postId; - LastPostDate = DateTime.UtcNow; - LastPostUserId = userId; - ReplyCount++; - } - - public void UpdateLikeCount(int count) - { - LikeCount = count; - } - - public void Pin() - { - IsPinned = true; - } - - public void Unpin() - { - IsPinned = false; - } - - public void Lock() - { - IsLocked = true; - } - - public void Unlock() - { - IsLocked = false; - } - - public void MarkAsSolved() - { - IsSolved = true; - } - - public void MarkAsUnsolved() - { - IsSolved = false; - } - } -} diff --git a/api/src/Kurs.Platform.Domain/Forum/ForumTopicLike.cs b/api/src/Kurs.Platform.Domain/Forum/ForumTopicLike.cs deleted file mode 100644 index 4ec46e15..00000000 --- a/api/src/Kurs.Platform.Domain/Forum/ForumTopicLike.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Volo.Abp.Domain.Entities.Auditing; -using Volo.Abp.MultiTenancy; - -namespace Kurs.Platform.Forum -{ - public class ForumTopicLike : CreationAuditedEntity, IMultiTenant - { - public Guid? TenantId { get; set; } - - public Guid TopicId { get; set; } - public virtual ForumTopic Topic { get; set; } - - public Guid UserId { get; set; } - - protected ForumTopicLike() - { - } - - public ForumTopicLike( - Guid id, - Guid topicId, - Guid userId, - Guid? tenantId = null) : base(id) - { - TopicId = topicId; - UserId = userId; - TenantId = tenantId; - } - } -} diff --git a/api/src/Kurs.Platform.Domain/Forum/ForumTopicTag.cs b/api/src/Kurs.Platform.Domain/Forum/ForumTopicTag.cs deleted file mode 100644 index 6e48beae..00000000 --- a/api/src/Kurs.Platform.Domain/Forum/ForumTopicTag.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Volo.Abp.Domain.Entities; -using Volo.Abp.MultiTenancy; - -namespace Kurs.Platform.Forum -{ - public class ForumTopicTag : Entity, IMultiTenant - { - public Guid? TenantId { get; set; } - - public Guid TopicId { get; set; } - public virtual ForumTopic Topic { get; set; } - - public string Tag { get; set; } - - protected ForumTopicTag() - { - } - - public ForumTopicTag( - Guid id, - Guid topicId, - string tag, - Guid? tenantId = null) : base(id) - { - TopicId = topicId; - Tag = tag; - TenantId = tenantId; - } - } -} diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs b/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs index c0a159fa..567fc922 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/EntityFrameworkCore/PlatformDbContext.cs @@ -1,7 +1,6 @@ using Kurs.Languages.EntityFrameworkCore; using Kurs.Platform.Entities; using Kurs.Platform.Blog; -using Kurs.Platform.Forum; using Kurs.Settings.EntityFrameworkCore; using Kurs.MailQueue.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; @@ -61,14 +60,6 @@ public class PlatformDbContext : public DbSet BlogPosts { get; set; } public DbSet BlogCategories { get; set; } - // Forum Entities - public DbSet ForumCategories { get; set; } - public DbSet ForumTopics { get; set; } - public DbSet ForumPosts { get; set; } - public DbSet ForumTopicTags { get; set; } - public DbSet ForumTopicLikes { get; set; } - public DbSet ForumPostLikes { get; set; } - #region Entities from the modules /* Notice: We only implemented IIdentityDbContext and ITenantManagementDbContext @@ -408,11 +399,11 @@ public class PlatformDbContext : { b.ToTable(PlatformConsts.DbTablePrefix + "BlogCategories", PlatformConsts.DbSchema); b.ConfigureByConvention(); - + b.Property(x => x.Name).IsRequired().HasMaxLength(128); b.Property(x => x.Slug).IsRequired().HasMaxLength(128); b.Property(x => x.Description).HasMaxLength(512); - + b.HasIndex(x => x.Slug); }); @@ -420,110 +411,21 @@ public class PlatformDbContext : { b.ToTable(PlatformConsts.DbTablePrefix + "BlogPosts", PlatformConsts.DbSchema); b.ConfigureByConvention(); - + b.Property(x => x.Title).IsRequired().HasMaxLength(256); b.Property(x => x.Slug).IsRequired().HasMaxLength(256); b.Property(x => x.Summary).IsRequired().HasMaxLength(512); b.Property(x => x.Content).IsRequired(); b.Property(x => x.CoverImage).HasMaxLength(512); - + b.HasIndex(x => x.Slug); b.HasIndex(x => x.IsPublished); b.HasIndex(x => x.PublishedAt); - + b.HasOne(x => x.Category) .WithMany(x => x.Posts) .HasForeignKey(x => x.CategoryId) .OnDelete(DeleteBehavior.Restrict); }); - - // Forum Entity Configurations - builder.Entity(b => - { - b.ToTable(PlatformConsts.DbTablePrefix + "ForumCategories", PlatformConsts.DbSchema); - b.ConfigureByConvention(); - - b.Property(x => x.Name).IsRequired().HasMaxLength(128); - b.Property(x => x.Description).HasMaxLength(512); - b.Property(x => x.Icon).HasMaxLength(64); - - b.HasIndex(x => x.DisplayOrder); - }); - - builder.Entity(b => - { - b.ToTable(PlatformConsts.DbTablePrefix + "ForumTopics", PlatformConsts.DbSchema); - b.ConfigureByConvention(); - - b.Property(x => x.Title).IsRequired().HasMaxLength(256); - b.Property(x => x.Content).IsRequired(); - - b.HasIndex(x => x.CategoryId); - b.HasIndex(x => x.IsPinned); - b.HasIndex(x => x.LastPostDate); - - b.HasOne(x => x.Category) - .WithMany(x => x.Topics) - .HasForeignKey(x => x.CategoryId) - .OnDelete(DeleteBehavior.Restrict); - }); - - builder.Entity(b => - { - b.ToTable(PlatformConsts.DbTablePrefix + "ForumPosts", PlatformConsts.DbSchema); - b.ConfigureByConvention(); - - b.Property(x => x.Content).IsRequired(); - - b.HasIndex(x => x.TopicId); - - b.HasOne(x => x.Topic) - .WithMany(x => x.Posts) - .HasForeignKey(x => x.TopicId) - .OnDelete(DeleteBehavior.Cascade); - }); - - builder.Entity(b => - { - b.ToTable(PlatformConsts.DbTablePrefix + "ForumTopicTags", PlatformConsts.DbSchema); - b.ConfigureByConvention(); - - b.Property(x => x.Tag).IsRequired().HasMaxLength(64); - - b.HasIndex(x => new { x.TopicId, x.Tag }).IsUnique(); - b.HasIndex(x => x.Tag); - - b.HasOne(x => x.Topic) - .WithMany(x => x.Tags) - .HasForeignKey(x => x.TopicId) - .OnDelete(DeleteBehavior.Cascade); - }); - - builder.Entity(b => - { - b.ToTable(PlatformConsts.DbTablePrefix + "ForumTopicLikes", PlatformConsts.DbSchema); - b.ConfigureByConvention(); - - b.HasIndex(x => new { x.TopicId, x.UserId }).IsUnique(); - - b.HasOne(x => x.Topic) - .WithMany(x => x.Likes) - .HasForeignKey(x => x.TopicId) - .OnDelete(DeleteBehavior.Cascade); - }); - - builder.Entity(b => - { - b.ToTable(PlatformConsts.DbTablePrefix + "ForumPostLikes", PlatformConsts.DbSchema); - b.ConfigureByConvention(); - - b.HasIndex(x => new { x.PostId, x.UserId }).IsUnique(); - - b.HasOne(x => x.Post) - .WithMany(x => x.Likes) - .HasForeignKey(x => x.PostId) - .OnDelete(DeleteBehavior.Cascade); - }); - } } diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.cs deleted file mode 100644 index 92a84e87..00000000 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.cs +++ /dev/null @@ -1,347 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Kurs.Platform.Migrations -{ - /// - public partial class AddBlogForumEntities : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "PBlogCategories", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Slug = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Description = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - Icon = table.Column(type: "nvarchar(max)", nullable: true), - DisplayOrder = table.Column(type: "int", nullable: false), - IsActive = table.Column(type: "bit", nullable: false), - PostCount = table.Column(type: "int", nullable: false), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PBlogCategories", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "PForumCategories", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Slug = table.Column(type: "nvarchar(max)", nullable: true), - Description = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - Icon = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - DisplayOrder = table.Column(type: "int", nullable: false), - IsActive = table.Column(type: "bit", nullable: false), - IsLocked = table.Column(type: "bit", nullable: false), - TopicCount = table.Column(type: "int", nullable: false), - PostCount = table.Column(type: "int", nullable: false), - LastPostId = table.Column(type: "uniqueidentifier", nullable: true), - LastPostDate = table.Column(type: "datetime2", nullable: true), - LastPostUserId = table.Column(type: "uniqueidentifier", nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PForumCategories", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "PBlogPosts", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Title = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Slug = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Content = table.Column(type: "nvarchar(max)", nullable: false), - Summary = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), - CoverImage = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - ReadTime = table.Column(type: "nvarchar(max)", nullable: true), - CategoryId = table.Column(type: "uniqueidentifier", nullable: false), - AuthorId = table.Column(type: "uniqueidentifier", nullable: false), - ViewCount = table.Column(type: "int", nullable: false), - LikeCount = table.Column(type: "int", nullable: false), - CommentCount = table.Column(type: "int", nullable: false), - IsPublished = table.Column(type: "bit", nullable: false), - PublishedAt = table.Column(type: "datetime2", nullable: true), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PBlogPosts", x => x.Id); - table.ForeignKey( - name: "FK_PBlogPosts_PBlogCategories_CategoryId", - column: x => x.CategoryId, - principalTable: "PBlogCategories", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "PForumTopics", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Title = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Content = table.Column(type: "nvarchar(max)", nullable: false), - CategoryId = table.Column(type: "uniqueidentifier", nullable: false), - AuthorId = table.Column(type: "uniqueidentifier", nullable: false), - ViewCount = table.Column(type: "int", nullable: false), - ReplyCount = table.Column(type: "int", nullable: false), - LikeCount = table.Column(type: "int", nullable: false), - IsPinned = table.Column(type: "bit", nullable: false), - IsLocked = table.Column(type: "bit", nullable: false), - IsSolved = table.Column(type: "bit", nullable: false), - LastPostId = table.Column(type: "uniqueidentifier", nullable: true), - LastPostDate = table.Column(type: "datetime2", nullable: true), - LastPostUserId = table.Column(type: "uniqueidentifier", nullable: true), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PForumTopics", x => x.Id); - table.ForeignKey( - name: "FK_PForumTopics_PForumCategories_CategoryId", - column: x => x.CategoryId, - principalTable: "PForumCategories", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "PForumPosts", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - TopicId = table.Column(type: "uniqueidentifier", nullable: false), - Content = table.Column(type: "nvarchar(max)", nullable: false), - AuthorId = table.Column(type: "uniqueidentifier", nullable: false), - LikeCount = table.Column(type: "int", nullable: false), - IsAcceptedAnswer = table.Column(type: "bit", nullable: false), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PForumPosts", x => x.Id); - table.ForeignKey( - name: "FK_PForumPosts_PForumTopics_TopicId", - column: x => x.TopicId, - principalTable: "PForumTopics", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PForumTopicLikes", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - TopicId = table.Column(type: "uniqueidentifier", nullable: false), - UserId = table.Column(type: "uniqueidentifier", nullable: false), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PForumTopicLikes", x => x.Id); - table.ForeignKey( - name: "FK_PForumTopicLikes_PForumTopics_TopicId", - column: x => x.TopicId, - principalTable: "PForumTopics", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PForumTopicTags", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - TopicId = table.Column(type: "uniqueidentifier", nullable: false), - Tag = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_PForumTopicTags", x => x.Id); - table.ForeignKey( - name: "FK_PForumTopicTags_PForumTopics_TopicId", - column: x => x.TopicId, - principalTable: "PForumTopics", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PForumPostLikes", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - PostId = table.Column(type: "uniqueidentifier", nullable: false), - UserId = table.Column(type: "uniqueidentifier", nullable: false), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PForumPostLikes", x => x.Id); - table.ForeignKey( - name: "FK_PForumPostLikes_PForumPosts_PostId", - column: x => x.PostId, - principalTable: "PForumPosts", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_PBlogCategories_Slug", - table: "PBlogCategories", - column: "Slug"); - - migrationBuilder.CreateIndex( - name: "IX_PBlogPosts_CategoryId", - table: "PBlogPosts", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_PBlogPosts_IsPublished", - table: "PBlogPosts", - column: "IsPublished"); - - migrationBuilder.CreateIndex( - name: "IX_PBlogPosts_PublishedAt", - table: "PBlogPosts", - column: "PublishedAt"); - - migrationBuilder.CreateIndex( - name: "IX_PBlogPosts_Slug", - table: "PBlogPosts", - column: "Slug"); - - migrationBuilder.CreateIndex( - name: "IX_PForumCategories_DisplayOrder", - table: "PForumCategories", - column: "DisplayOrder"); - - migrationBuilder.CreateIndex( - name: "IX_PForumPostLikes_PostId_UserId", - table: "PForumPostLikes", - columns: new[] { "PostId", "UserId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_PForumPosts_TopicId", - table: "PForumPosts", - column: "TopicId"); - - migrationBuilder.CreateIndex( - name: "IX_PForumTopicLikes_TopicId_UserId", - table: "PForumTopicLikes", - columns: new[] { "TopicId", "UserId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_PForumTopics_CategoryId", - table: "PForumTopics", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_PForumTopics_IsPinned", - table: "PForumTopics", - column: "IsPinned"); - - migrationBuilder.CreateIndex( - name: "IX_PForumTopics_LastPostDate", - table: "PForumTopics", - column: "LastPostDate"); - - migrationBuilder.CreateIndex( - name: "IX_PForumTopicTags_Tag", - table: "PForumTopicTags", - column: "Tag"); - - migrationBuilder.CreateIndex( - name: "IX_PForumTopicTags_TopicId_Tag", - table: "PForumTopicTags", - columns: new[] { "TopicId", "Tag" }, - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "PBlogPosts"); - - migrationBuilder.DropTable( - name: "PForumPostLikes"); - - migrationBuilder.DropTable( - name: "PForumTopicLikes"); - - migrationBuilder.DropTable( - name: "PForumTopicTags"); - - migrationBuilder.DropTable( - name: "PBlogCategories"); - - migrationBuilder.DropTable( - name: "PForumPosts"); - - migrationBuilder.DropTable( - name: "PForumTopics"); - - migrationBuilder.DropTable( - name: "PForumCategories"); - } - } -} diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.Designer.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.Designer.cs similarity index 92% rename from api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.Designer.cs rename to api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.Designer.cs index 454202aa..590bcb03 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250620094517_AddBlogForumEntities.Designer.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.Designer.cs @@ -13,8 +13,8 @@ using Volo.Abp.EntityFrameworkCore; namespace Kurs.Platform.Migrations { [DbContext(typeof(PlatformDbContext))] - [Migration("20250620094517_AddBlogForumEntities")] - partial class AddBlogForumEntities + [Migration("20250622112214_AddBlogEntities")] + partial class AddBlogEntities { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -2435,347 +2435,6 @@ namespace Kurs.Platform.Migrations b.ToTable("PUomCategory", (string)null); }); - modelBuilder.Entity("Kurs.Platform.Forum.ForumCategory", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("DeleterId") - .HasColumnType("uniqueidentifier") - .HasColumnName("DeleterId"); - - b.Property("DeletionTime") - .HasColumnType("datetime2") - .HasColumnName("DeletionTime"); - - b.Property("Description") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DisplayOrder") - .HasColumnType("int"); - - b.Property("Icon") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsActive") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false) - .HasColumnName("IsDeleted"); - - b.Property("IsLocked") - .HasColumnType("bit"); - - b.Property("LastModificationTime") - .HasColumnType("datetime2") - .HasColumnName("LastModificationTime"); - - b.Property("LastModifierId") - .HasColumnType("uniqueidentifier") - .HasColumnName("LastModifierId"); - - b.Property("LastPostDate") - .HasColumnType("datetime2"); - - b.Property("LastPostId") - .HasColumnType("uniqueidentifier"); - - b.Property("LastPostUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PostCount") - .HasColumnType("int"); - - b.Property("Slug") - .HasColumnType("nvarchar(max)"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicCount") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("DisplayOrder"); - - b.ToTable("PForumCategories", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPost", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("AuthorId") - .HasColumnType("uniqueidentifier"); - - b.Property("Content") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("DeleterId") - .HasColumnType("uniqueidentifier") - .HasColumnName("DeleterId"); - - b.Property("DeletionTime") - .HasColumnType("datetime2") - .HasColumnName("DeletionTime"); - - b.Property("IsAcceptedAnswer") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false) - .HasColumnName("IsDeleted"); - - b.Property("LastModificationTime") - .HasColumnType("datetime2") - .HasColumnName("LastModificationTime"); - - b.Property("LastModifierId") - .HasColumnType("uniqueidentifier") - .HasColumnName("LastModifierId"); - - b.Property("LikeCount") - .HasColumnType("int"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("TopicId"); - - b.ToTable("PForumPosts", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPostLike", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("PostId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("PostId", "UserId") - .IsUnique(); - - b.ToTable("PForumPostLikes", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopic", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("AuthorId") - .HasColumnType("uniqueidentifier"); - - b.Property("CategoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .IsRequired() - .HasMaxLength(40) - .HasColumnType("nvarchar(40)") - .HasColumnName("ConcurrencyStamp"); - - b.Property("Content") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("DeleterId") - .HasColumnType("uniqueidentifier") - .HasColumnName("DeleterId"); - - b.Property("DeletionTime") - .HasColumnType("datetime2") - .HasColumnName("DeletionTime"); - - b.Property("ExtraProperties") - .IsRequired() - .HasColumnType("nvarchar(max)") - .HasColumnName("ExtraProperties"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false) - .HasColumnName("IsDeleted"); - - b.Property("IsLocked") - .HasColumnType("bit"); - - b.Property("IsPinned") - .HasColumnType("bit"); - - b.Property("IsSolved") - .HasColumnType("bit"); - - b.Property("LastModificationTime") - .HasColumnType("datetime2") - .HasColumnName("LastModificationTime"); - - b.Property("LastModifierId") - .HasColumnType("uniqueidentifier") - .HasColumnName("LastModifierId"); - - b.Property("LastPostDate") - .HasColumnType("datetime2"); - - b.Property("LastPostId") - .HasColumnType("uniqueidentifier"); - - b.Property("LastPostUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("LikeCount") - .HasColumnType("int"); - - b.Property("ReplyCount") - .HasColumnType("int"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ViewCount") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("IsPinned"); - - b.HasIndex("LastPostDate"); - - b.ToTable("PForumTopics", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicLike", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicId") - .HasColumnType("uniqueidentifier"); - - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("TopicId", "UserId") - .IsUnique(); - - b.ToTable("PForumTopicLikes", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicTag", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("Tag") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("Tag"); - - b.HasIndex("TopicId", "Tag") - .IsUnique(); - - b.ToTable("PForumTopicTags", (string)null); - }); - modelBuilder.Entity("Kurs.Settings.Entities.SettingDefinition", b => { b.Property("Id") @@ -4929,61 +4588,6 @@ namespace Kurs.Platform.Migrations b.Navigation("UomCategory"); }); - modelBuilder.Entity("Kurs.Platform.Forum.ForumPost", b => - { - b.HasOne("Kurs.Platform.Forum.ForumTopic", "Topic") - .WithMany("Posts") - .HasForeignKey("TopicId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Topic"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPostLike", b => - { - b.HasOne("Kurs.Platform.Forum.ForumPost", "Post") - .WithMany("Likes") - .HasForeignKey("PostId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Post"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopic", b => - { - b.HasOne("Kurs.Platform.Forum.ForumCategory", "Category") - .WithMany("Topics") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicLike", b => - { - b.HasOne("Kurs.Platform.Forum.ForumTopic", "Topic") - .WithMany("Likes") - .HasForeignKey("TopicId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Topic"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicTag", b => - { - b.HasOne("Kurs.Platform.Forum.ForumTopic", "Topic") - .WithMany("Tags") - .HasForeignKey("TopicId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Topic"); - }); - modelBuilder.Entity("Skill", b => { b.HasOne("SkillType", null) @@ -5160,25 +4764,6 @@ namespace Kurs.Platform.Migrations b.Navigation("Units"); }); - modelBuilder.Entity("Kurs.Platform.Forum.ForumCategory", b => - { - b.Navigation("Topics"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPost", b => - { - b.Navigation("Likes"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopic", b => - { - b.Navigation("Likes"); - - b.Navigation("Posts"); - - b.Navigation("Tags"); - }); - modelBuilder.Entity("SkillType", b => { b.Navigation("Levels"); diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.cs new file mode 100644 index 00000000..19b9af71 --- /dev/null +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20250622112214_AddBlogEntities.cs @@ -0,0 +1,116 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Kurs.Platform.Migrations +{ + /// + public partial class AddBlogEntities : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "PBlogCategories", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Slug = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Description = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + Icon = table.Column(type: "nvarchar(max)", nullable: true), + DisplayOrder = table.Column(type: "int", nullable: false), + IsActive = table.Column(type: "bit", nullable: false), + PostCount = table.Column(type: "int", nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PBlogCategories", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "PBlogPosts", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Title = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Slug = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Content = table.Column(type: "nvarchar(max)", nullable: false), + Summary = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + CoverImage = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + ReadTime = table.Column(type: "nvarchar(max)", nullable: true), + CategoryId = table.Column(type: "uniqueidentifier", nullable: false), + AuthorId = table.Column(type: "uniqueidentifier", nullable: false), + ViewCount = table.Column(type: "int", nullable: false), + LikeCount = table.Column(type: "int", nullable: false), + CommentCount = table.Column(type: "int", nullable: false), + IsPublished = table.Column(type: "bit", nullable: false), + PublishedAt = table.Column(type: "datetime2", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: false), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: false), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PBlogPosts", x => x.Id); + table.ForeignKey( + name: "FK_PBlogPosts_PBlogCategories_CategoryId", + column: x => x.CategoryId, + principalTable: "PBlogCategories", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_PBlogCategories_Slug", + table: "PBlogCategories", + column: "Slug"); + + migrationBuilder.CreateIndex( + name: "IX_PBlogPosts_CategoryId", + table: "PBlogPosts", + column: "CategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_PBlogPosts_IsPublished", + table: "PBlogPosts", + column: "IsPublished"); + + migrationBuilder.CreateIndex( + name: "IX_PBlogPosts_PublishedAt", + table: "PBlogPosts", + column: "PublishedAt"); + + migrationBuilder.CreateIndex( + name: "IX_PBlogPosts_Slug", + table: "PBlogPosts", + column: "Slug"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PBlogPosts"); + + migrationBuilder.DropTable( + name: "PBlogCategories"); + } + } +} diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs index 78bdd42b..1bc826a3 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/PlatformDbContextModelSnapshot.cs @@ -2432,347 +2432,6 @@ namespace Kurs.Platform.Migrations b.ToTable("PUomCategory", (string)null); }); - modelBuilder.Entity("Kurs.Platform.Forum.ForumCategory", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("DeleterId") - .HasColumnType("uniqueidentifier") - .HasColumnName("DeleterId"); - - b.Property("DeletionTime") - .HasColumnType("datetime2") - .HasColumnName("DeletionTime"); - - b.Property("Description") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("DisplayOrder") - .HasColumnType("int"); - - b.Property("Icon") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("IsActive") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false) - .HasColumnName("IsDeleted"); - - b.Property("IsLocked") - .HasColumnType("bit"); - - b.Property("LastModificationTime") - .HasColumnType("datetime2") - .HasColumnName("LastModificationTime"); - - b.Property("LastModifierId") - .HasColumnType("uniqueidentifier") - .HasColumnName("LastModifierId"); - - b.Property("LastPostDate") - .HasColumnType("datetime2"); - - b.Property("LastPostId") - .HasColumnType("uniqueidentifier"); - - b.Property("LastPostUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("PostCount") - .HasColumnType("int"); - - b.Property("Slug") - .HasColumnType("nvarchar(max)"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicCount") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("DisplayOrder"); - - b.ToTable("PForumCategories", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPost", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("AuthorId") - .HasColumnType("uniqueidentifier"); - - b.Property("Content") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("DeleterId") - .HasColumnType("uniqueidentifier") - .HasColumnName("DeleterId"); - - b.Property("DeletionTime") - .HasColumnType("datetime2") - .HasColumnName("DeletionTime"); - - b.Property("IsAcceptedAnswer") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false) - .HasColumnName("IsDeleted"); - - b.Property("LastModificationTime") - .HasColumnType("datetime2") - .HasColumnName("LastModificationTime"); - - b.Property("LastModifierId") - .HasColumnType("uniqueidentifier") - .HasColumnName("LastModifierId"); - - b.Property("LikeCount") - .HasColumnType("int"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("TopicId"); - - b.ToTable("PForumPosts", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPostLike", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("PostId") - .HasColumnType("uniqueidentifier"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("PostId", "UserId") - .IsUnique(); - - b.ToTable("PForumPostLikes", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopic", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("AuthorId") - .HasColumnType("uniqueidentifier"); - - b.Property("CategoryId") - .HasColumnType("uniqueidentifier"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .IsRequired() - .HasMaxLength(40) - .HasColumnType("nvarchar(40)") - .HasColumnName("ConcurrencyStamp"); - - b.Property("Content") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("DeleterId") - .HasColumnType("uniqueidentifier") - .HasColumnName("DeleterId"); - - b.Property("DeletionTime") - .HasColumnType("datetime2") - .HasColumnName("DeletionTime"); - - b.Property("ExtraProperties") - .IsRequired() - .HasColumnType("nvarchar(max)") - .HasColumnName("ExtraProperties"); - - b.Property("IsDeleted") - .ValueGeneratedOnAdd() - .HasColumnType("bit") - .HasDefaultValue(false) - .HasColumnName("IsDeleted"); - - b.Property("IsLocked") - .HasColumnType("bit"); - - b.Property("IsPinned") - .HasColumnType("bit"); - - b.Property("IsSolved") - .HasColumnType("bit"); - - b.Property("LastModificationTime") - .HasColumnType("datetime2") - .HasColumnName("LastModificationTime"); - - b.Property("LastModifierId") - .HasColumnType("uniqueidentifier") - .HasColumnName("LastModifierId"); - - b.Property("LastPostDate") - .HasColumnType("datetime2"); - - b.Property("LastPostId") - .HasColumnType("uniqueidentifier"); - - b.Property("LastPostUserId") - .HasColumnType("uniqueidentifier"); - - b.Property("LikeCount") - .HasColumnType("int"); - - b.Property("ReplyCount") - .HasColumnType("int"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ViewCount") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CategoryId"); - - b.HasIndex("IsPinned"); - - b.HasIndex("LastPostDate"); - - b.ToTable("PForumTopics", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicLike", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("CreationTime") - .HasColumnType("datetime2") - .HasColumnName("CreationTime"); - - b.Property("CreatorId") - .HasColumnType("uniqueidentifier") - .HasColumnName("CreatorId"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicId") - .HasColumnType("uniqueidentifier"); - - b.Property("UserId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("TopicId", "UserId") - .IsUnique(); - - b.ToTable("PForumTopicLikes", (string)null); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicTag", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("Tag") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("TenantId") - .HasColumnType("uniqueidentifier") - .HasColumnName("TenantId"); - - b.Property("TopicId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("Id"); - - b.HasIndex("Tag"); - - b.HasIndex("TopicId", "Tag") - .IsUnique(); - - b.ToTable("PForumTopicTags", (string)null); - }); - modelBuilder.Entity("Kurs.Settings.Entities.SettingDefinition", b => { b.Property("Id") @@ -4926,61 +4585,6 @@ namespace Kurs.Platform.Migrations b.Navigation("UomCategory"); }); - modelBuilder.Entity("Kurs.Platform.Forum.ForumPost", b => - { - b.HasOne("Kurs.Platform.Forum.ForumTopic", "Topic") - .WithMany("Posts") - .HasForeignKey("TopicId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Topic"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPostLike", b => - { - b.HasOne("Kurs.Platform.Forum.ForumPost", "Post") - .WithMany("Likes") - .HasForeignKey("PostId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Post"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopic", b => - { - b.HasOne("Kurs.Platform.Forum.ForumCategory", "Category") - .WithMany("Topics") - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicLike", b => - { - b.HasOne("Kurs.Platform.Forum.ForumTopic", "Topic") - .WithMany("Likes") - .HasForeignKey("TopicId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Topic"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopicTag", b => - { - b.HasOne("Kurs.Platform.Forum.ForumTopic", "Topic") - .WithMany("Tags") - .HasForeignKey("TopicId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Topic"); - }); - modelBuilder.Entity("Skill", b => { b.HasOne("SkillType", null) @@ -5157,25 +4761,6 @@ namespace Kurs.Platform.Migrations b.Navigation("Units"); }); - modelBuilder.Entity("Kurs.Platform.Forum.ForumCategory", b => - { - b.Navigation("Topics"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumPost", b => - { - b.Navigation("Likes"); - }); - - modelBuilder.Entity("Kurs.Platform.Forum.ForumTopic", b => - { - b.Navigation("Likes"); - - b.Navigation("Posts"); - - b.Navigation("Tags"); - }); - modelBuilder.Entity("SkillType", b => { b.Navigation("Levels"); diff --git a/company/src/App.tsx b/company/src/App.tsx index a0cea046..99e837ae 100644 --- a/company/src/App.tsx +++ b/company/src/App.tsx @@ -1,5 +1,4 @@ -import React, { useEffect } from 'react'; -import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; +import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { Toaster } from 'react-hot-toast'; import Layout from './components/layout/Layout'; @@ -10,14 +9,8 @@ import About from './pages/About'; import Blog from './pages/Blog'; import Contact from './pages/Contact'; import BlogDetail from './pages/BlogDetail'; -import LoginWithTenant from './pages/LoginWithTenant'; -import Register from './pages/Register'; -import Forum from './pages/Forum'; -import ForumCategory from './pages/ForumCategory'; -import Profile from './pages/Profile'; import NotFound from './pages/NotFound'; import { LanguageProvider } from './context/LanguageContext'; -import { useAuthStore } from './store/authStore'; // Create a client const queryClient = new QueryClient({ @@ -29,24 +22,7 @@ const queryClient = new QueryClient({ }, }); -// Protected Route Component -const ProtectedRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => { - const { isAuthenticated } = useAuthStore(); - - if (!isAuthenticated) { - return ; - } - - return <>{children}; -}; - function App() { - const { checkAuth } = useAuthStore(); - - useEffect(() => { - checkAuth(); - }, [checkAuth]); - return ( @@ -60,53 +36,6 @@ function App() { } /> } /> } /> - } /> - } /> - - {/* Protected Routes */} - - - - } /> - - {/* Forum Routes */} - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - - - - } /> - } /> diff --git a/company/src/components/layout/Header.tsx b/company/src/components/layout/Header.tsx index 1fbfc8b5..040cb8cd 100644 --- a/company/src/components/layout/Header.tsx +++ b/company/src/components/layout/Header.tsx @@ -1,15 +1,23 @@ import React, { useState, useEffect } from "react"; -import { Menu, X, Globe, LogIn, LogOut, User, MessageSquare, Home, Info, Package, Briefcase, BookOpen, Phone } from "lucide-react"; +import { + Menu, + X, + Globe, + Home, + Info, + Package, + Briefcase, + BookOpen, + Phone, +} from "lucide-react"; import Logo from "./Logo"; import { Link, useNavigate } from "react-router-dom"; import { useLanguage } from "../../context/LanguageContext"; -import { useAuthStore } from "../../store/authStore"; const Header: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const [scrolled, setScrolled] = useState(false); const { language, setLanguage, t } = useLanguage(); - const { isAuthenticated, user, logout } = useAuthStore(); const navigate = useNavigate(); useEffect(() => { @@ -27,19 +35,14 @@ const Header: React.FC = () => { const toggleMenu = () => setIsOpen(!isOpen); const toggleLanguage = () => setLanguage(language === "en" ? "tr" : "en"); - const handleLogout = () => { - logout(); - navigate('/'); - }; - const navLinks = [ { name: t("nav.home"), path: "/", icon: Home }, { name: t("nav.about"), path: "/about", icon: Info }, { name: t("nav.products"), path: "/products", icon: Package }, { name: t("nav.services"), path: "/services", icon: Briefcase }, { name: t("nav.blog"), path: "/blog", icon: BookOpen }, - { name: t("nav.forum"), path: "/forum", icon: MessageSquare, protected: true }, { name: t("nav.contact"), path: "/contact", icon: Phone }, + { name: t("nav.demo"), path: import.meta.env.VITE_KURS_URL }, ]; return ( @@ -57,20 +60,17 @@ const Header: React.FC = () => { {/* Desktop Navigation */} {/* Mobile Menu Button */} @@ -132,21 +96,18 @@ const Header: React.FC = () => {
diff --git a/company/src/pages/Forum.tsx b/company/src/pages/Forum.tsx deleted file mode 100644 index cf052f85..00000000 --- a/company/src/pages/Forum.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Link, useNavigate } from 'react-router-dom'; -import { forumService, ForumCategory, ForumStats } from '../services/api/forum.service'; -import { MessageSquare, TrendingUp, Lock, Search, Plus, User } from 'lucide-react'; -import { useLanguage } from '../context/LanguageContext'; -import { useAuthStore } from '../store/authStore'; - -const Forum: React.FC = () => { - const { t } = useLanguage(); - const navigate = useNavigate(); - const { isAuthenticated } = useAuthStore(); - const [categories, setCategories] = useState([]); - const [stats, setStats] = useState(null); - const [loading, setLoading] = useState(true); - const [searchQuery, setSearchQuery] = useState(''); - const [showSearchModal, setShowSearchModal] = useState(false); - - useEffect(() => { - loadForumData(); - }, []); - - const loadForumData = async () => { - try { - const [categoriesData, statsData] = await Promise.all([ - forumService.getCategories(), - forumService.getStats(), - ]); - setCategories(categoriesData); - setStats(statsData); - } catch (error) { - console.error('Forum verileri yüklenemedi:', error); - } finally { - setLoading(false); - } - }; - - if (loading) { - return ( -
-
-
-

Forum yükleniyor...

-
-
- ); - } - - return ( -
- {/* Hero Section */} -
-
-
-

{t("forum.title")}

-

{t("forum.subtitle")}

-
-
- - {/* Stats Section */} - {stats && ( -
-
-
-
-
{stats.totalTopics}
-
Konu
-
-
-
{stats.totalPosts}
-
Mesaj
-
-
-
{stats.totalUsers}
-
Üye
-
-
-
{stats.onlineUsers}
-
Çevrimiçi
-
-
- {stats.latestMember && ( -
- En yeni üyemiz: {stats.latestMember.name} -
- )} -
-
- )} - - {/* Categories */} -
-

Kategoriler

- - {categories.length === 0 ? ( -
-

Henüz kategori bulunmuyor.

-
- ) : ( -
- {categories.map((category) => ( -
-
-
-
- {category.icon && ( - {category.icon} - )} -
-

- {category.name} -

- {category.isLocked && ( - - - Kilitli - - )} -
-
-
- -

- {category.description || 'Bu kategori için açıklama bulunmuyor.'} -

- -
-
- - - {category.topicCount || 0} - - - - {category.postCount || 0} - -
- - Görüntüle → - -
-
- - {category.lastPost && ( -
-

Son mesaj:

-

- {category.lastPost.title} -

-
- )} -
- ))} -
- )} - - {/* Quick Actions */} -
-

Hızlı İşlemler

-
- - - -
-
- - {/* Popular Tags */} -
-

Popüler Etiketler

-
- {['react', 'javascript', 'api', 'authentication', 'devexpress', 'abp-framework', 'ddd'].map((tag) => ( - - #{tag} - - ))} -
-
-
- - {/* Search Modal */} - {showSearchModal && ( -
-
-
-

Forum'da Ara

-
- -
-
- setSearchQuery(e.target.value)} - onKeyPress={(e) => { - if (e.key === 'Enter' && searchQuery.trim()) { - navigate(`/forum/search?q=${encodeURIComponent(searchQuery)}`); - setShowSearchModal(false); - } - }} - className="w-full px-4 py-3 pr-12 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" - placeholder="Arama yapmak için bir şeyler yazın..." - autoFocus - /> - -
- -
-

İpucu: Başlık, içerik veya etiketlerde arama yapabilirsiniz.

-
-
- -
- -
-
-
- )} -
- ); -}; - -export default Forum; diff --git a/company/src/pages/ForumCategory.tsx b/company/src/pages/ForumCategory.tsx deleted file mode 100644 index 7868bc5f..00000000 --- a/company/src/pages/ForumCategory.tsx +++ /dev/null @@ -1,278 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { useParams, Link, useNavigate } from 'react-router-dom'; -import { forumService, ForumCategory, ForumPost } from '../services/api/forum.service'; -import { ArrowLeft, MessageSquare, User, Calendar, Eye, Heart, Reply, Plus } from 'lucide-react'; -import { useLanguage } from '../context/LanguageContext'; -import { formatDistanceToNow } from 'date-fns'; -import { tr } from 'date-fns/locale'; - -const ForumCategoryPage: React.FC = () => { - const { slug } = useParams<{ slug: string }>(); - const navigate = useNavigate(); - const { t } = useLanguage(); - const [category, setCategory] = useState(null); - const [posts, setPosts] = useState([]); - const [loading, setLoading] = useState(true); - const [showNewPostModal, setShowNewPostModal] = useState(false); - const [newPost, setNewPost] = useState({ title: '', content: '' }); - const [submitting, setSubmitting] = useState(false); - - useEffect(() => { - if (slug) { - loadCategoryData(); - } - }, [slug]); - - const loadCategoryData = async () => { - try { - setLoading(true); - const categoryData = await forumService.getCategoryBySlug(slug!); - setCategory(categoryData); - - const postsData = await forumService.getPostsByCategory(categoryData.id); - setPosts(postsData); - } catch (error) { - console.error('Kategori verileri yüklenemedi:', error); - } finally { - setLoading(false); - } - }; - - const handleCreatePost = async () => { - if (!newPost.title.trim() || !newPost.content.trim()) { - alert('Lütfen başlık ve içerik alanlarını doldurun.'); - return; - } - - try { - setSubmitting(true); - await forumService.createPost({ - categoryId: category!.id, - title: newPost.title, - content: newPost.content - }); - - setShowNewPostModal(false); - setNewPost({ title: '', content: '' }); - loadCategoryData(); // Yeni post eklendiğinde listeyi yenile - } catch (error) { - console.error('Post oluşturulamadı:', error); - alert('Post oluşturulurken bir hata oluştu.'); - } finally { - setSubmitting(false); - } - }; - - if (loading) { - return ( -
-
-
-

Yükleniyor...

-
-
- ); - } - - if (!category) { - return ( -
-
-

Kategori bulunamadı.

- - Forum'a Dön - -
-
- ); - } - - return ( -
- {/* Header */} -
-
-
-
- -
-

- {category.icon && {category.icon}} - {category.name} -

- {category.description && ( -

{category.description}

- )} -
-
- -
-
-
- - {/* Posts List */} -
- {posts.length === 0 ? ( -
- -

Bu kategoride henüz konu bulunmuyor.

- -
- ) : ( -
- {posts.map((post) => ( -
-
-
-
- - {post.title} - -
- - - {post.author?.name || 'Anonim'} - - - - {formatDistanceToNow(new Date(post.createdAt), { - addSuffix: true, - locale: tr - })} - - - - {post.viewCount || 0} - - - - {post.replyCount || 0} - -
-
-
- - {post.likeCount || 0} -
-
- - {post.tags && post.tags.length > 0 && ( -
- {post.tags.map((tag, index) => ( - - #{tag} - - ))} -
- )} -
- - {post.lastReply && ( -
-
- - Son yanıt: - {post.lastReply.author?.name} - - - {formatDistanceToNow(new Date(post.lastReply.createdAt), { - addSuffix: true, - locale: tr - })} - -
-
- )} -
- ))} -
- )} -
- - {/* New Post Modal */} - {showNewPostModal && ( -
-
-
-

Yeni Konu Oluştur

-
- -
-
- - setNewPost({ ...newPost, title: e.target.value })} - className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" - placeholder="Konunuzun başlığını girin" - /> -
- -
- -