diff --git a/api/src/Kurs.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs b/api/src/Kurs.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs index b60a6e2b..09bb4d7e 100644 --- a/api/src/Kurs.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs +++ b/api/src/Kurs.Platform.Application.Contracts/Intranet/IntranetDashboardDto.cs @@ -17,5 +17,7 @@ public class IntranetDashboardDto public List Meals { get; set; } = []; public List Leaves { get; set; } = []; public List Overtimes { get; set; } = []; + public List Surveys { get; set; } = []; + public List SocialPosts { get; set; } = []; } diff --git a/api/src/Kurs.Platform.Application.Contracts/Intranet/SocialPostDto.cs b/api/src/Kurs.Platform.Application.Contracts/Intranet/SocialPostDto.cs new file mode 100644 index 00000000..01e72f71 --- /dev/null +++ b/api/src/Kurs.Platform.Application.Contracts/Intranet/SocialPostDto.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace Kurs.Platform.Intranet; + +public class SocialPostDto : FullAuditedEntityDto +{ + public Guid? EmployeeId { get; set; } + public EmployeeDto? Employee { get; set; } + public string Content { get; set; } + + public int LikeCount { get; set; } + public bool IsLiked { get; set; } + public bool IsOwnPost { get; set; } + + public SocialLocationDto? Location { get; set; } + public SocialMediaDto? Media { get; set; } + public List Comments { get; set; } + public List Likes { get; set; } +} + +public class SocialLocationDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public string Name { get; set; } + public string? Address { get; set; } + public double? Lat { get; set; } + public double? Lng { get; set; } + public string? PlaceId { get; set; } +} + +public class SocialMediaDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public string Type { get; set; } // image | video | poll + public string[] Urls { get; set; } + + // Poll Fields + public string? PollQuestion { get; set; } + public int? PollTotalVotes { get; set; } + public DateTime? PollEndsAt { get; set; } + public string? PollUserVoteId { get; set; } + + public List PollOptions { get; set; } +} + +public class SocialPollOptionDto : FullAuditedEntityDto +{ + public Guid SocialMediaId { get; set; } + public string Text { get; set; } + public int Votes { get; set; } +} + +public class SocialCommentDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public Guid? EmployeeId { get; set; } + public EmployeeDto? Employee { get; set; } + public string Content { get; set; } +} + +public class SocialLikeDto : FullAuditedEntityDto +{ + public Guid SocialPostId { get; set; } + public Guid? EmployeeId { get; set; } + public EmployeeDto? Employee { get; set; } +} \ No newline at end of file diff --git a/api/src/Kurs.Platform.Application.Contracts/Intranet/SurveyDto.cs b/api/src/Kurs.Platform.Application.Contracts/Intranet/SurveyDto.cs new file mode 100644 index 00000000..2fb75c34 --- /dev/null +++ b/api/src/Kurs.Platform.Application.Contracts/Intranet/SurveyDto.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Application.Dtos; + +namespace Kurs.Platform.Intranet; + +public class SurveyDto : FullAuditedEntityDto +{ + public string Title { get; set; } + public string Description { get; set; } + public DateTime Deadline { get; set; } + public int Responses { get; set; } + public string Status { get; set; } // draft | active | closed + public bool IsAnonymous { get; set; } + + public List Questions { get; set; } +} + +public class SurveyQuestionDto : FullAuditedEntityDto +{ + public Guid SurveyId { get; set; } + public string QuestionText { get; set; } + public string Type { get; set; } // rating | multiple-choice | text | textarea | yes-no + public int Order { get; set; } + public bool IsRequired { get; set; } + + public List Options { get; set; } +} + +public class SurveyQuestionOptionDto : FullAuditedEntityDto +{ + public Guid QuestionId { get; set; } + public string Text { get; set; } + public int Order { get; set; } +} + +public class SurveyResponseDto : FullAuditedEntityDto +{ + public Guid SurveyId { get; set; } + public Guid? EmployeeId { get; set; } + public DateTime SubmissionTime { get; set; } + + public List Answers { get; set; } +} + +public class SurveyAnswerDto : FullAuditedEntityDto +{ + public Guid ResponseId { get; set; } + public Guid QuestionId { get; set; } + public string QuestionType { get; set; } + public string Value { get; set; } +} \ No newline at end of file diff --git a/api/src/Kurs.Platform.Application/Intranet/IntranetAppService.cs b/api/src/Kurs.Platform.Application/Intranet/IntranetAppService.cs index 2d7b1891..b84734eb 100644 --- a/api/src/Kurs.Platform.Application/Intranet/IntranetAppService.cs +++ b/api/src/Kurs.Platform.Application/Intranet/IntranetAppService.cs @@ -9,6 +9,7 @@ using Kurs.Platform.Entities; using Kurs.Platform.FileManagement; using Kurs.Platform.Intranet; using Microsoft.AspNetCore.Authorization; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Volo.Abp.Domain.Repositories; @@ -35,6 +36,8 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService private readonly IRepository _mealRepository; private readonly IRepository _leaveRepository; private readonly IRepository _overtimeRepository; + private readonly IRepository _surveyRepository; + private readonly IRepository _socialPostRepository; public IntranetAppService( ICurrentTenant currentTenant, @@ -52,7 +55,9 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService IRepository shuttleRouteRepository, IRepository mealRepository, IRepository leaveRepository, - IRepository overtimeRepository + IRepository overtimeRepository, + IRepository surveyRepository, + IRepository socialPostRepository ) { _currentTenant = currentTenant; @@ -71,6 +76,8 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService _mealRepository = mealRepository; _leaveRepository = leaveRepository; _overtimeRepository = overtimeRepository; + _surveyRepository = surveyRepository; + _socialPostRepository = socialPostRepository; } public async Task GetIntranetDashboardAsync() @@ -88,10 +95,34 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService ShuttleRoutes = await GetShuttleRoutesAsync(), Meals = await GetMealsAsync(), Leaves = await GetLeavesAsync(), - Overtimes = await GetOvertimesAsync() + Overtimes = await GetOvertimesAsync(), + Surveys = await GetSurveysAsync(), + SocialPosts = await GetSocialPostsAsync() }; } + private async Task> GetSocialPostsAsync() + { + var socialPosts = await _socialPostRepository + .WithDetailsAsync(e => e.Employee, e => e.Location, e => e.Media, e => e.Comments, e => e.Likes) + .ContinueWith(t => t.Result.ToList()); + + return ObjectMapper.Map, List>(socialPosts); + } + + private async Task> GetSurveysAsync() + { + var queryable = await _surveyRepository.GetQueryableAsync(); + + var surveys = queryable + .Where(s => s.Status == "active") + .Include(s => s.Questions) + .ThenInclude(q => q.Options) + .ToList(); + + return ObjectMapper.Map, List>(surveys); + } + private async Task> GetOvertimesAsync() { var today = DateTime.Now; diff --git a/api/src/Kurs.Platform.Application/Intranet/IntranetAutoMapperProfile.cs b/api/src/Kurs.Platform.Application/Intranet/IntranetAutoMapperProfile.cs index cbf3663f..9bf215bf 100644 --- a/api/src/Kurs.Platform.Application/Intranet/IntranetAutoMapperProfile.cs +++ b/api/src/Kurs.Platform.Application/Intranet/IntranetAutoMapperProfile.cs @@ -28,5 +28,17 @@ public class IntranetAutoMapperProfile : Profile CreateMap() .ForMember(dest => dest.Route, opt => opt.Ignore()); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); } } diff --git a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/SocialPost.cs b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/SocialPost.cs index ed3024e4..34a54158 100644 --- a/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/SocialPost.cs +++ b/api/src/Kurs.Platform.Domain/Entities/Tenant/Hr/SocialPost.cs @@ -10,7 +10,7 @@ public class SocialPost : FullAuditedEntity, IMultiTenant public Guid? TenantId { get; set; } public Guid? EmployeeId { get; set; } - public Employee? Employee { get; set; } + public Employee Employee { get; set; } public string Content { get; set; } @@ -19,8 +19,8 @@ public class SocialPost : FullAuditedEntity, IMultiTenant public bool IsOwnPost { get; set; } // Relations - public SocialLocation? Location { get; set; } - public SocialMedia? Media { get; set; } + public SocialLocation Location { get; set; } + public SocialMedia Media { get; set; } public ICollection Comments { get; set; } public ICollection Likes { get; set; } } diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029074530_Initial.Designer.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029185945_Initial.Designer.cs similarity index 99% rename from api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029074530_Initial.Designer.cs rename to api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029185945_Initial.Designer.cs index 030e6f14..8d09972b 100644 --- a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029074530_Initial.Designer.cs +++ b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029185945_Initial.Designer.cs @@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore; namespace Kurs.Platform.Migrations { [DbContext(typeof(PlatformDbContext))] - [Migration("20251029074530_Initial")] + [Migration("20251029185945_Initial")] partial class Initial { /// diff --git a/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029074530_Initial.cs b/api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029185945_Initial.cs similarity index 100% rename from api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029074530_Initial.cs rename to api/src/Kurs.Platform.EntityFrameworkCore/Migrations/20251029185945_Initial.cs diff --git a/ui/src/mocks/mockIntranet.ts b/ui/src/mocks/mockIntranet.ts deleted file mode 100644 index b29608a9..00000000 --- a/ui/src/mocks/mockIntranet.ts +++ /dev/null @@ -1,1196 +0,0 @@ -import { - AnnouncementDto, - CertificateDto, - DocumentDto, - EventDto, - ExpenseDto, - LeaveDto, - OvertimeDto, - ReservationDto, - ShuttleRouteDto, - TrainingDto, - VisitorDto, -} from '@/proxy/intranet/models' -import { mockEmployees } from './mockEmployees' -import { Survey, SocialPost } from '@/types/intranet' -import { LeaveStatusEnum, LeaveTypeEnum } from '@/types/hr' - -const currentUser = { ...mockEmployees[0], fullName: 'Siz' } - -export const mockSurveys: Survey[] = [ - { - id: 'survey1', - title: 'Çalışan Memnuniyet Anketi 2024', - description: 'Yıllık çalışan memnuniyeti ve bağlılık araştırması', - creatorId: mockEmployees[0], - creationTime: new Date('2024-10-01'), - deadline: new Date('2024-10-31'), - questions: [ - { - id: 'q1', - surveyId: 'survey1', - questionText: 'Genel memnuniyet düzeyiniz nedir?', - type: 'rating', - order: 1, - isRequired: true, - ratingConfig: { - min: 1, - max: 5, - labels: { - 1: 'Çok Kötü', - 2: 'Kötü', - 3: 'Orta', - 4: 'İyi', - 5: 'Çok İyi', - }, - }, - }, - { - id: 'q2', - surveyId: 'survey1', - questionText: 'Hangi departmanda çalışıyorsunuz?', - type: 'multiple-choice', - order: 2, - isRequired: true, - options: [ - { id: 'opt1', text: 'Bilgi Teknolojileri', order: 1 }, - { id: 'opt2', text: 'İnsan Kaynakları', order: 2 }, - { id: 'opt3', text: 'Finans', order: 3 }, - { id: 'opt4', text: 'Satış', order: 4 }, - { id: 'opt5', text: 'Pazarlama', order: 5 }, - ], - }, - { - id: 'q3', - surveyId: 'survey1', - questionText: 'Görüş ve önerileriniz', - type: 'textarea', - order: 3, - isRequired: false, - }, - { - id: 'q4', - surveyId: 'survey1', - questionText: 'Çalışma ortamından memnun musunuz?', - type: 'yes-no', - order: 4, - isRequired: true, - }, - ], - responses: 45, - targetAudience: ['Tüm Çalışanlar'], - status: 'active', - isAnonymous: true, - }, - { - id: 'survey2', - title: 'Eğitim İhtiyaç Analizi', - description: '2025 yılı eğitim planlaması için ihtiyaç tespiti', - creatorId: mockEmployees[2], - creationTime: new Date('2024-10-10'), - deadline: new Date('2024-11-15'), - questions: [ - { - id: 'q5', - surveyId: 'survey2', - questionText: 'Hangi teknoloji konularında eğitim almak istiyorsunuz?', - type: 'multiple-choice', - order: 1, - isRequired: true, - options: [ - { id: 'opt6', text: 'React / Frontend', order: 1 }, - { id: 'opt7', text: 'Node.js / Backend', order: 2 }, - { id: 'opt8', text: 'Database / SQL', order: 3 }, - { id: 'opt9', text: 'DevOps / Cloud', order: 4 }, - { id: 'opt10', text: 'Mobile Development', order: 5 }, - ], - }, - { - id: 'q6', - surveyId: 'survey2', - questionText: 'Eğitim formatı tercihiniz nedir?', - type: 'multiple-choice', - order: 2, - isRequired: true, - options: [ - { id: 'opt11', text: 'Online Eğitim', order: 1 }, - { id: 'opt12', text: 'Yüz Yüze Eğitim', order: 2 }, - { id: 'opt13', text: 'Hibrit (Karma)', order: 3 }, - ], - }, - { - id: 'q7', - surveyId: 'survey2', - questionText: 'Eğitim için haftalık ne kadar zaman ayırabilirsiniz?', - type: 'rating', - order: 3, - isRequired: true, - ratingConfig: { - min: 1, - max: 10, - labels: { - 1: '1 saat', - 5: '5 saat', - 10: '10+ saat', - }, - }, - }, - ], - responses: 28, - targetAudience: ['Yazılım Geliştirme', 'Ürün Yönetimi'], - status: 'active', - isAnonymous: false, - }, - { - id: 'survey3', - title: 'Kafeterya Memnuniyet Anketi', - description: 'Yemek kalitesi ve servis değerlendirmesi', - creatorId: mockEmployees[4], - creationTime: new Date('2024-09-15'), - deadline: new Date('2024-09-30'), - questions: [ - { - id: 'q8', - surveyId: 'survey3', - questionText: 'Yemek kalitesini nasıl değerlendiriyorsunuz?', - type: 'rating', - order: 1, - isRequired: true, - ratingConfig: { - min: 1, - max: 5, - labels: { - 1: 'Çok Kötü', - 2: 'Kötü', - 3: 'Orta', - 4: 'İyi', - 5: 'Mükemmel', - }, - }, - }, - { - id: 'q9', - surveyId: 'survey3', - questionText: 'Hangi yemekleri daha sık görmek istiyorsunuz?', - type: 'textarea', - order: 2, - isRequired: false, - }, - { - id: 'q10', - surveyId: 'survey3', - questionText: 'Servis hızından memnun musunuz?', - type: 'yes-no', - order: 3, - isRequired: true, - }, - ], - responses: 62, - targetAudience: ['Tüm Çalışanlar'], - status: 'closed', - isAnonymous: true, - }, -] - -export const mockSocialPosts: SocialPost[] = [ - { - id: '1', - creator: mockEmployees[2], // Mehmet Yılmaz - content: - 'Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀', - creationTime: new Date('2024-10-15T10:30:00'), - locationJson: JSON.stringify({ - id: '1', - name: 'Taksim Meydanı', - address: 'Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul', - lat: 41.0369, - lng: 28.985, - placeId: 'ChIJBQRGmL25yhQRXwqRTHAwAAQ', - }), - media: { - type: 'image', - urls: ['https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80'], - }, - likeCount: 24, - isLiked: true, - likeUsers: [mockEmployees[1], mockEmployees[3]], // Ayşe Kaya, Selin Demir - comments: [ - { - id: 'c1', - creator: mockEmployees[1], // Ayşe Kaya - content: 'Harika görünüyor! Başarılar 👏', - creationTime: new Date('2024-10-15T11:00:00'), - }, - { - id: 'c2', - creator: mockEmployees[3], // Selin Demir - content: 'TypeScript gerçekten fark yaratıyor!', - creationTime: new Date('2024-10-15T11:30:00'), - }, - ], - isOwnPost: false, - }, - { - id: '2', - creator: currentUser, - content: - 'Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!', - creationTime: new Date('2024-10-16T09:00:00'), - media: { - type: 'poll', - pollQuestion: 'Hangi özelliği öncelikli olarak geliştirmeliyiz?', - pollOptions: [ - { id: 'p1', text: 'Kullanıcı profilleri', votes: 12 }, - { id: 'p2', text: 'Bildirim sistemi', votes: 8 }, - { id: 'p3', text: 'Mesajlaşma', votes: 15 }, - { id: 'p4', text: 'Raporlama', votes: 5 }, - ], - pollTotalVotes: 40, - pollEndsAt: new Date('2024-10-20T23:59:59'), - pollUserVoteId: 'p3', - }, - likeCount: 18, - isLiked: false, - likeUsers: [], - comments: [ - { - id: 'c3', - creator: mockEmployees[4], // Ahmet Çelik - content: 'Mesajlaşma özelliğine kesinlikle ihtiyacımız var!', - creationTime: new Date('2024-10-16T10:15:00'), - }, - ], - isOwnPost: true, - }, - { - id: '3', - creator: mockEmployees[5], // Zeynep Arslan - content: - 'Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨', - creationTime: new Date('2024-10-17T14:20:00'), - media: { - type: 'image', - urls: [ - 'https://images.unsplash.com/photo-1561070791-2526d30994b5?w=800&q=80', - 'https://images.unsplash.com/photo-1586717799252-bd134ad00e26?w=800&q=80', - 'https://images.unsplash.com/photo-1609921212029-bb5a28e60960?w=800&q=80', - ], - }, - likeCount: 42, - isLiked: true, - likeUsers: [mockEmployees[2]], // Mehmet Yılmaz - comments: [ - { - id: 'c4', - creator: mockEmployees[6], // Burak Koç - content: 'Tasarımlar çok şık! Renk paleti özellikle güzel 😍', - creationTime: new Date('2024-10-17T15:00:00'), - }, - { - id: 'c5', - creator: mockEmployees[7], // Elif Şahin - content: 'Dark mode opsiyonu da olacak mı?', - creationTime: new Date('2024-10-17T15:30:00'), - }, - ], - isOwnPost: false, - }, - { - id: '4', - creator: mockEmployees[6], // Burak Koç - content: - 'CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪', - creationTime: new Date('2024-10-18T08:45:00'), - media: { - type: 'video', - urls: ['https://www.w3schools.com/html/mov_bbb.mp4'], - }, - likeCount: 31, - isLiked: false, - likeUsers: [], - comments: [ - { - id: 'c6', - creator: mockEmployees[8], // Canan Öztürk - content: 'Harika iş! Detayları paylaşabilir misin?', - creationTime: new Date('2024-10-18T09:15:00'), - }, - ], - isOwnPost: false, - }, - { - id: '5', - creator: mockEmployees[7], // Elif Şahin - content: - 'Ekip üyelerimize yeni eğitim programımızı duyurmak istiyorum! 🎓 React, TypeScript ve Modern Web Geliştirme konularında kapsamlı bir program hazırladık.', - creationTime: new Date('2024-10-14T16:00:00'), - likeCount: 56, - isLiked: true, - likeUsers: [], - comments: [ - { - id: 'c7', - creator: mockEmployees[2], // Mehmet Yılmaz - content: 'Ne zaman başlıyor?', - creationTime: new Date('2024-10-14T16:30:00'), - }, - { - id: 'c8', - creator: mockEmployees[7], // Elif Şahin - content: 'Gelecek hafta başlıyoruz! Kayıt linki mail ile paylaşılacak.', - creationTime: new Date('2024-10-14T17:00:00'), - }, - ], - isOwnPost: false, - }, - { - id: '6', - creator: mockEmployees[9], // Murat Aydın - content: 'Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯', - creationTime: new Date('2024-10-17T14:00:00'), - locationJson: JSON.stringify({ - id: '4', - name: 'Sultanahmet Meydanı', - address: 'Sultanahmet Mahallesi, 34122 Fatih/İstanbul', - lat: 41.0058, - lng: 28.9768, - placeId: 'ChIJ7fVVZiy5yhQRzsXXXXXXXXk', - }), - likeCount: 18, - isLiked: false, - likeUsers: [], - comments: [], - isOwnPost: false, - }, -] - -///////////////////////////////////////////////////////////////////////////////////// -///////APP SERVİS YAPILANLAR////////// -export const mockEvents: EventDto[] = [ - { - id: 'evt1', - name: 'Yaz Pikniği 2025', - description: - 'Şirket çalışanları olarak doğayla iç içe harika bir gün geçirdik. Takım oyunları, barbekü ve çok eğlence!', - categoryName: 'Spor', - typeName: 'Futbol Turnuvası', - date: new Date('2025-10-20'), - place: 'Polonezköy Piknik Alanı', - organizer: mockEmployees[4], - participants: 45, - photos: [ - 'https://images.unsplash.com/photo-1530541930197-ff16ac917b0e?w=800', - 'https://images.unsplash.com/photo-1527529482837-4698179dc6ce?w=800', - 'https://images.unsplash.com/photo-1528605105345-5344ea20e269?w=800', - 'https://images.unsplash.com/photo-1504196606672-aef5c9cefc92?w=800', - ], - comments: [ - { - id: 'c1', - author: mockEmployees[0], - content: 'Muhteşem bir gündü! Yılın en güzel etkinliği 🎉', - creationTime: new Date('2025-07-16T10:30:00'), - likes: 12, - }, - { - id: 'c2', - author: mockEmployees[2], - content: 'Voleybol turnuvası harikaydı, gelecek yıl yine yapalım!', - creationTime: new Date('2025-07-16T14:20:00'), - likes: 8, - }, - ], - likes: 34, - isPublished: true, - }, - { - id: 'evt2', - name: 'Hackathon 2025', - description: '24 saatlik yazılım geliştirme maratonu. İnovasyon, teknoloji ve takım çalışması!', - categoryName: 'Spor', - typeName: 'training', - date: new Date('2025-20-22'), - place: 'Ofis - Ana Salon', - organizer: mockEmployees[0], - participants: 28, - photos: [ - 'https://images.unsplash.com/photo-1504384308090-c894fdcc538d?w=800', - 'https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=800', - 'https://images.unsplash.com/photo-1531482615713-2afd69097998?w=800', - ], - comments: [ - { - id: 'c3', - author: mockEmployees[1], - content: 'Ekibimiz 2. oldu! Çok gurur duydum herkesle 💪', - creationTime: new Date('2025-09-11T09:00:00'), - likes: 15, - }, - { - id: 'c4', - author: mockEmployees[3], - content: 'Gece boyunca kod yazmak ve pizza yemek priceless! 🍕', - creationTime: new Date('2025-09-11T11:45:00'), - likes: 10, - }, - ], - likes: 42, - isPublished: true, - }, - { - id: 'evt3', - name: 'Kurumsal Futbol Turnuvası', - description: 'Departmanlar arası futbol turnuvasında ter döktük, gol attık ve kazandık! 🏆', - categoryName: 'Spor', - typeName: 'sport', - date: new Date('2025-10-25'), - place: 'Spor Kompleksi Halı Saha', - organizer: mockEmployees[2], - participants: 32, - photos: [ - 'https://images.unsplash.com/photo-1579952363873-27f3bade9f55?w=800', - 'https://images.unsplash.com/photo-1574629810360-7efbbe195018?w=800', - 'https://images.unsplash.com/photo-1431324155629-1a6deb1dec8d?w=800', - 'https://images.unsplash.com/photo-1553778263-73a83bab9b0c?w=800', - ], - comments: [ - { - id: 'c5', - author: mockEmployees[4], - content: 'İT departmanı şampiyon oldu! Gelecek sene kupayı koruyacağız 🏆', - creationTime: new Date('2025-06-21T08:30:00'), - likes: 18, - }, - ], - likes: 28, - isPublished: true, - }, - { - id: 'evt4', - name: 'Yılbaşı Gala Gecesi 2024', - description: 'Harika bir yıla muhteşem bir gala ile veda ettik. Müzik, dans ve sürprizler!', - categoryName: 'Spor', - typeName: 'company', - date: new Date('2024-12-28'), - place: 'Grand Hotel - Balo Salonu', - organizer: mockEmployees[3], - participants: 68, - photos: [ - 'https://images.unsplash.com/photo-1511795409834-ef04bbd61622?w=800', - 'https://images.unsplash.com/photo-1519167758481-83f29da8c2b9?w=800', - 'https://images.unsplash.com/photo-1464366400600-7168b8af9bc3?w=800', - 'https://images.unsplash.com/photo-1478147427282-58a87a120781?w=800', - 'https://images.unsplash.com/photo-1492684223066-81342ee5ff30?w=800', - ], - comments: [ - { - id: 'c6', - author: mockEmployees[0], - content: 'Yılın en şık gecesi! Organizasyon mükemmeldi 👏', - creationTime: new Date('2024-12-29T10:00:00'), - likes: 25, - }, - { - id: 'c7', - author: mockEmployees[1], - content: 'Tombala hediyelerim harika, çok teşekkürler! 🎁', - creationTime: new Date('2024-12-29T12:30:00'), - likes: 14, - }, - { - id: 'c8', - author: mockEmployees[2], - content: 'Müzik grubunuz süperdi, dans pistinden ayrılamadık! 🎵', - creationTime: new Date('2024-12-29T15:20:00'), - likes: 19, - }, - ], - likes: 51, - isPublished: true, - }, - { - id: 'evt5', - name: 'Sanat Atölyesi - Ebru Workshop', - description: 'Geleneksel Türk sanatı ebru yapımı atölyesinde harika eserler ortaya çıktı!', - categoryName: 'Spor', - typeName: 'culture', - date: new Date('2025-05-12'), - place: 'Ofis - Yaratıcı Alan', - organizer: mockEmployees[1], - participants: 18, - photos: [ - 'https://images.unsplash.com/photo-1460661419201-fd4cecdf8a8b?w=800', - 'https://images.unsplash.com/photo-1513364776144-60967b0f800f?w=800', - 'https://images.unsplash.com/photo-1515405295579-ba7b45403062?w=800', - ], - comments: [ - { - id: 'c9', - author: mockEmployees[3], - content: 'İlk defa ebru yaptım, çok huzurlu bir deneyimdi 🎨', - creationTime: new Date('2025-05-13T09:15:00'), - likes: 11, - }, - ], - likes: 22, - isPublished: true, - }, -] - -export const mockVisitors: VisitorDto[] = [ - { - id: 'vis1', - fullName: 'Ali Veli', - companyName: 'ABC Teknoloji', - email: 'ali.veli@abc.com', - phone: '+90 532 111 22 33', - visitDate: new Date('2025-10-25T10:00:00'), - checkIn: new Date('2025-10-25T10:15:00'), - employeeId: mockEmployees[1].id, - employee: mockEmployees[1], - purpose: 'İş Ortaklığı Görüşmesi', - status: 'checked-in', - badgeNumber: 'V-001', - photo: 'https://i.pravatar.cc/150?img=60', - }, - { - id: 'vis2', - fullName: 'Fatma Yıldız', - companyName: 'XYZ Danışmanlık', - email: 'fatma@xyz.com', - phone: '+90 533 222 33 44', - visitDate: new Date('2024-10-21T14:00:00'), - employeeId: mockEmployees[2].id, - employee: mockEmployees[2], - purpose: 'Eğitim Danışmanlığı', - status: 'scheduled', - photo: 'https://i.pravatar.cc/150?img=47', - }, - { - id: 'vis3', - fullName: 'Mehmet Kara', - companyName: 'DEF Yazılım', - email: 'mehmet@def.com', - phone: '+90 534 333 44 55', - visitDate: new Date('2024-10-18T11:00:00'), - checkIn: new Date('2024-10-18T11:05:00'), - checkOut: new Date('2024-10-18T13:30:00'), - employeeId: mockEmployees[3].id, - employee: mockEmployees[3], - purpose: 'Teknik Sunum', - status: 'checked-out', - badgeNumber: 'V-002', - photo: 'https://i.pravatar.cc/150?img=68', - }, -] - -export const mockTrainings: TrainingDto[] = [ - { - id: 'tr1', - title: 'React & TypeScript İleri Seviye', - description: - 'Modern React uygulamaları geliştirmek için TypeScript kullanımı, hooks, context API ve performans optimizasyonu', - instructor: 'Mehmet Demir', - category: 'technical', - type: 'online', - duration: 16, - startDate: new Date('2024-11-01'), - endDate: new Date('2024-11-08'), - maxParticipants: 20, - enrolled: 15, - status: 'upcoming', - thumbnail: 'https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=400&h=300&fit=crop', - }, - { - id: 'tr2', - title: 'Etkili İletişim ve Sunum Teknikleri', - description: - 'İş hayatında etkili iletişim kurma, profesyonel sunum hazırlama ve konuşma becerileri geliştirme', - instructor: 'Ayşe Kara', - category: 'soft-skills', - type: 'classroom', - duration: 8, - startDate: new Date('2024-10-25'), - endDate: new Date('2024-10-25'), - maxParticipants: 15, - enrolled: 12, - status: 'ongoing', - location: 'Eğitim Salonu A', - thumbnail: 'https://images.unsplash.com/photo-1557804506-669a67965ba0?w=400&h=300&fit=crop', - }, - { - id: 'tr3', - title: 'Agile & Scrum Master Eğitimi', - description: - 'Çevik yazılım geliştirme metodolojileri, Scrum framework ve sertifikasyon hazırlığı', - instructor: 'Can Öztürk', - category: 'management', - type: 'hybrid', - duration: 24, - startDate: new Date('2024-09-15'), - endDate: new Date('2024-09-30'), - maxParticipants: 25, - enrolled: 25, - status: 'completed', - thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=400&h=300&fit=crop', - }, - { - id: 'tr4', - title: 'Siber Güvenlik ve Veri Koruma', - description: 'KVKK uyumluluğu, siber güvenlik tehditleri ve kurumsal veri koruma stratejileri', - instructor: 'Zeynep Arslan', - category: 'compliance', - type: 'online', - duration: 12, - startDate: new Date('2024-11-15'), - endDate: new Date('2024-11-22'), - maxParticipants: 50, - enrolled: 8, - status: 'upcoming', - thumbnail: 'https://images.unsplash.com/photo-1550751827-4bd374c3f58b?w=400&h=300&fit=crop', - }, -] - -export const mockCertificates: CertificateDto[] = [ - { - id: 'cert1', - employee: mockEmployees[0], - trainingTitle: 'Agile & Scrum Master Eğitimi', - issueDate: new Date('2024-09-30'), - expiryDate: new Date('2026-09-30'), - certificateUrl: '/certificates/cert1.pdf', - score: 95, - }, - { - id: 'cert2', - employee: mockEmployees[2], - trainingTitle: 'React & TypeScript İleri Seviye', - issueDate: new Date('2024-08-15'), - certificateUrl: '/certificates/cert2.pdf', - score: 88, - }, - { - id: 'cert3', - employee: mockEmployees[4], - trainingTitle: 'Siber Güvenlik ve Veri Koruma', - issueDate: new Date('2024-07-20'), - expiryDate: new Date('2025-07-20'), - certificateUrl: '/certificates/cert3.pdf', - score: 92, - }, -] - -export const mockExpenseRequests: ExpenseDto[] = [ - { - id: 'exp1', - employee: mockEmployees[0], - category: 'travel', - amount: 850, - currency: 'TRY', - date: new Date('2024-10-15'), - description: 'Ankara ofis ziyareti - uçak bileti', - project: 'Intranet v2', - receipts: [{ name: 'ucak_bileti.pdf', url: '#', size: '234 KB' }], - status: 'approved', - approver: mockEmployees[4], - approvalDate: new Date('2024-10-16T10:00:00'), - creationTime: new Date('2024-10-15T18:00:00'), - }, - { - id: 'exp2', - employee: mockEmployees[2], - category: 'meal', - amount: 320, - currency: 'TRY', - date: new Date('2024-10-17'), - description: 'Müşteri toplantısı - öğle yemeği', - receipts: [{ name: 'restoran_fisi.jpg', url: '#', size: '156 KB' }], - status: 'pending', - creationTime: new Date('2024-10-17T20:00:00'), - }, - { - id: 'exp3', - employee: mockEmployees[1], - category: 'accommodation', - amount: 1200, - currency: 'TRY', - date: new Date('2024-10-14'), - description: 'İzmir workshop - otel konaklaması (2 gece)', - project: 'UX Workshop', - receipts: [{ name: 'otel_fatura.pdf', url: '#', size: '445 KB' }], - status: 'approved', - approver: mockEmployees[4], - approvalDate: new Date('2024-10-15T09:00:00'), - creationTime: new Date('2024-10-14T22:00:00'), - }, -] - -export const mockDocuments: DocumentDto[] = [ - { - id: '1', - name: 'Çalışan El Kitabı 2024.pdf', - type: 'file', - size: 3355443, // 3.2 MB - extension: '.pdf', - mimeType: 'application/pdf', - createdAt: new Date('2024-01-15T10:30:00'), - modifiedAt: new Date('2024-01-15T10:30:00'), - path: 'Çalışan El Kitabı 2024.pdf', - parentId: '', - isReadOnly: false, - childCount: 0, - }, - { - id: '2', - name: 'İzin Talep Formu.docx', - type: 'file', - size: 126976, // 124 KB - extension: '.docx', - mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - createdAt: new Date('2024-02-01T09:00:00'), - modifiedAt: new Date('2024-02-01T09:00:00'), - path: 'İzin Talep Formu.docx', - parentId: '', - isReadOnly: false, - childCount: 0, - }, - { - id: '3', - name: 'Yazılım Geliştirme Standartları.pdf', - type: 'file', - size: 1887437, // 1.8 MB - extension: '.pdf', - mimeType: 'application/pdf', - createdAt: new Date('2024-03-10T14:20:00'), - modifiedAt: new Date('2024-03-10T14:20:00'), - path: 'Yazılım Geliştirme Standartları.pdf', - parentId: '', - isReadOnly: false, - childCount: 0, - }, - { - id: '4', - name: 'Masraf Raporu Şablonu.xlsx', - type: 'file', - size: 245760, // 240 KB - extension: '.xlsx', - mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - createdAt: new Date('2024-04-05T11:15:00'), - modifiedAt: new Date('2024-04-05T11:15:00'), - path: 'Masraf Raporu Şablonu.xlsx', - parentId: '', - isReadOnly: false, - childCount: 0, - }, - { - id: '5', - name: 'Şirket Sunumu 2024.pptx', - type: 'file', - size: 5242880, // 5 MB - extension: '.pptx', - mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - createdAt: new Date('2024-05-20T16:45:00'), - modifiedAt: new Date('2024-06-10T10:30:00'), - path: 'Şirket Sunumu 2024.pptx', - parentId: '', - isReadOnly: false, - childCount: 0, - }, - { - id: '6', - name: 'İK Politikaları.pdf', - type: 'file', - size: 2097152, // 2 MB - extension: '.pdf', - mimeType: 'application/pdf', - createdAt: new Date('2024-01-10T08:00:00'), - modifiedAt: new Date('2024-01-10T08:00:00'), - path: 'İK Politikaları.pdf', - parentId: '', - isReadOnly: true, - childCount: 0, - }, -] - -export const mockReservations: ReservationDto[] = [ - { - id: 'res1', - type: 'room', - resourceName: 'Toplantı Salonu A', - bookedBy: mockEmployees[2], - startDate: new Date('2024-10-20T09:00:00'), - endDate: new Date('2024-10-20T11:00:00'), - purpose: 'Sprint Planning Toplantısı', - status: 'approved', - participants: 8, - notes: 'Projeksiyon cihazı gerekli', - }, - { - id: 'res2', - type: 'vehicle', - resourceName: 'Şirket Aracı - 34 ABC 123', - bookedBy: mockEmployees[3], - startDate: new Date('2024-10-22T08:00:00'), - endDate: new Date('2024-10-22T18:00:00'), - purpose: 'Müşteri Ziyareti', - status: 'pending', - notes: 'Ankara çıkışı', - }, - { - id: 'res3', - type: 'equipment', - resourceName: 'Kamera ve Tripod Seti', - bookedBy: mockEmployees[5], - startDate: new Date('2024-10-19T14:00:00'), - endDate: new Date('2024-10-19T17:00:00'), - purpose: 'Ürün Tanıtım Videosu Çekimi', - status: 'approved', - }, - { - id: 'res4', - type: 'room', - resourceName: 'Eğitim Salonu B', - bookedBy: mockEmployees[6], - startDate: new Date('2024-10-25T09:00:00'), - endDate: new Date('2024-10-25T17:00:00'), - purpose: 'Etkili İletişim Eğitimi', - status: 'approved', - participants: 15, - notes: 'Tüm gün rezervasyon, öğle yemeği dahil', - }, -] - -export const mockAnnouncements: AnnouncementDto[] = [ - { - id: 'ann1', - title: '🎉 Yeni Ofis Açılışı', - content: - 'Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor! Tüm çalışanlarımızı açılış törenimize davet ediyoruz.', - excerpt: 'Ankara ofisimiz 1 Kasım tarihinde hizmete başlıyor!', - category: 'general', - employeeId: mockEmployees[4].id, - employee: mockEmployees[4], - publishDate: new Date('2024-10-15T09:00:00'), - isPinned: true, - viewCount: 156, - imageUrl: 'https://images.unsplash.com/photo-1497366216548-37526070297c?w=800&q=80', - }, - { - id: 'ann2', - title: '📅 Performans Değerlendirme Dönemi', - content: - 'Yıl sonu performans değerlendirmelerimiz 20 Ekim - 5 Kasım tarihleri arasında gerçekleştirilecektir. Lütfen formları zamanında doldurunuz.', - excerpt: 'Yıl sonu performans değerlendirmeleri başlıyor.', - category: 'hr', - employeeId: mockEmployees[3].id, - employee: mockEmployees[3], - publishDate: new Date('2024-10-18T10:30:00'), - expiryDate: new Date('2024-11-05'), - isPinned: true, - viewCount: 89, - departments: ['Tüm Departmanlar'], - }, - { - id: 'ann3', - title: '💻 Sistem Bakımı Duyurusu', - content: - 'Bu Cumartesi saat 02:00-06:00 arası sistemlerimizde bakım çalışması yapılacaktır. Bu süre içinde sistemlere erişim sağlanamayacaktır.', - excerpt: 'Cumartesi gecesi planlı bakım çalışması', - category: 'it', - employeeId: mockEmployees[2].id, - employee: mockEmployees[2], - publishDate: new Date('2024-10-17T14:00:00'), - isPinned: false, - viewCount: 234, - }, - { - id: 'ann4', - title: '🎓 React İleri Seviye Eğitimi', - content: - 'Yazılım Geliştirme ekibimiz için React İleri Seviye eğitimi 25-26 Ekim tarihlerinde düzenlenecektir. Katılım için IK birimine başvurunuz.', - excerpt: 'React İleri Seviye eğitimi kayıtları başladı', - category: 'event', - employeeId: mockEmployees[0].id, - employee: mockEmployees[0], - publishDate: new Date('2024-10-16T11:00:00'), - isPinned: false, - viewCount: 67, - departments: ['Yazılım Geliştirme'], - }, - { - id: 'ann5', - title: '⚠️ Güvenlik Politikası Güncellemesi', - content: - 'Bilgi güvenliği politikamız güncellenmiştir. Tüm çalışanlarımızın yeni politikayı okuması ve onaylaması gerekmektedir.', - excerpt: 'Güvenlik politikası güncellendi - Onay gerekli', - category: 'urgent', - employeeId: mockEmployees[4].id, - employee: mockEmployees[4], - publishDate: new Date('2024-10-18T08:00:00'), - isPinned: true, - viewCount: 312, - attachments: [{ name: 'Bilgi_Guvenligi_Politikasi_v2.pdf', url: '#', size: '2.4 MB' }], - }, -] - -export const mockShuttleRoutes: ShuttleRouteDto[] = [ - { - id: 'shuttle1', - name: 'Kadıköy - Ofis', - route: ['Kadıköy İskele', 'Bostancı', 'Acıbadem', 'Kozyatağı', 'Ofis'], - departureTime: '07:30', - arrivalTime: '08:45', - capacity: 25, - available: 3, - type: 'morning', - }, - { - id: 'shuttle2', - name: 'Üsküdar - Ofis', - route: ['Üsküdar Meydanı', 'Kısıklı', 'Bulgurlu', 'Ümraniye', 'Ofis'], - departureTime: '07:45', - arrivalTime: '08:50', - capacity: 25, - available: 8, - type: 'morning', - }, - { - id: 'shuttle3', - name: 'Ofis - Kadıköy', - route: ['Ofis', 'Kozyatağı', 'Acıbadem', 'Bostancı', 'Kadıköy İskele'], - departureTime: '18:00', - arrivalTime: '19:15', - capacity: 25, - available: 5, - type: 'evening', - }, - { - id: 'shuttle4', - name: 'Ofis - Üsküdar', - route: ['Ofis', 'Ümraniye', 'Bulgurlu', 'Kısıklı', 'Üsküdar Meydanı'], - departureTime: '18:15', - arrivalTime: '19:20', - capacity: 25, - available: 12, - type: 'evening', - }, -] - -export const mockLeaves: LeaveDto[] = [ - { - id: '1', - employeeId: '1', - employee: mockEmployees.find((e) => e.id === '1'), - leaveType: LeaveTypeEnum.Annual, - startDate: new Date('2024-12-20'), - endDate: new Date('2024-12-24'), - totalDays: 5, - reason: 'Yıllık izin talebi', - status: LeaveStatusEnum.Pending, - appliedDate: new Date('2024-11-15'), - isHalfDay: false, - attachments: [], - creationTime: new Date('2024-11-15'), - lastModificationTime: new Date('2024-11-15'), - }, - { - id: '2', - employeeId: '2', - employee: mockEmployees.find((e) => e.id === '2'), - leaveType: LeaveTypeEnum.Sick, - startDate: new Date('2024-11-10'), - endDate: new Date('2024-11-12'), - totalDays: 3, - reason: 'Sağlık kontrolü', - status: LeaveStatusEnum.Approved, - appliedDate: new Date('2024-11-08'), - approvedDate: new Date('2024-11-09'), - isHalfDay: false, - attachments: [], - creationTime: new Date('2024-11-08'), - lastModificationTime: new Date('2024-11-09'), - }, - { - id: '3', - employeeId: '3', - employee: mockEmployees.find((e) => e.id === '3'), - leaveType: LeaveTypeEnum.Personal, - startDate: new Date('2024-12-01'), - endDate: new Date('2024-12-01'), - totalDays: 0.5, - reason: 'Kişisel işler', - status: LeaveStatusEnum.Rejected, - appliedDate: new Date('2024-11-20'), - rejectionReason: 'Proje teslim tarihi nedeniyle uygun değil', - isHalfDay: true, - attachments: [], - creationTime: new Date('2024-11-20'), - lastModificationTime: new Date('2024-11-21'), - }, - { - id: '4', - employeeId: '4', - employee: mockEmployees.find((e) => e.id === '4'), - leaveType: LeaveTypeEnum.Emergency, - startDate: new Date('2024-11-25'), - endDate: new Date('2024-11-26'), - totalDays: 2, - reason: 'Acil aile durumu', - status: LeaveStatusEnum.Pending, - appliedDate: new Date('2024-11-24'), - isHalfDay: false, - attachments: [], - creationTime: new Date('2024-11-24'), - lastModificationTime: new Date('2024-11-24'), - }, -] - -export const mockOvertimes: OvertimeDto[] = [ - { - id: '1', - employeeId: '1', - date: new Date('2024-12-15'), - startTime: '18:00', - endTime: '21:00', - totalHours: 3, - reason: "Proje deadline'ı nedeniyle acil çalışma", - status: LeaveStatusEnum.Approved, - approvedBy: 'emp_002', - rate: 1.5, - amount: 450, // 3 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-15T09:00:00'), - lastModificationTime: new Date('2024-12-15T10:30:00'), - }, - { - id: '2', - employeeId: '3', - date: new Date('2024-12-14'), - startTime: '17:30', - endTime: '20:00', - totalHours: 2.5, - reason: 'Müşteri talep değişikliği nedeniyle ek çalışma', - status: LeaveStatusEnum.Pending, - rate: 1.5, - amount: 375, // 2.5 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-14T17:30:00'), - lastModificationTime: new Date('2024-12-14T17:30:00'), - }, - { - id: '3', - employeeId: '4', - date: new Date('2024-12-13'), - startTime: '19:00', - endTime: '22:30', - totalHours: 3.5, - reason: 'Sistem bakımı ve güncelleme çalışmaları', - status: LeaveStatusEnum.Approved, - approvedBy: 'emp_002', - rate: 1.5, - amount: 525, // 3.5 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-13T19:00:00'), - lastModificationTime: new Date('2024-12-13T22:35:00'), - }, - { - id: '4', - employeeId: '5', - date: new Date('2024-12-12'), - startTime: '17:00', - endTime: '19:00', - totalHours: 2, - reason: 'Rapor hazırlama ve sunum düzenleme', - status: LeaveStatusEnum.Rejected, - approvedBy: 'emp_002', - rate: 1.5, - amount: 0, // Reddedildiği için ücret hesaplanmadı - creationTime: new Date('2024-12-12T17:00:00'), - lastModificationTime: new Date('2024-12-12T08:30:00'), - }, - { - id: '5', - employeeId: '6', - date: new Date('2024-12-11'), - startTime: '18:30', - endTime: '21:00', - totalHours: 2.5, - reason: 'Acil hata düzeltme ve test çalışmaları', - status: LeaveStatusEnum.Approved, - approvedBy: 'emp_001', - rate: 2.0, // Hafta sonu çalışması - amount: 500, // 2.5 saat * 100 TL/saat * 2.0 kat - creationTime: new Date('2024-12-11T18:30:00'), - lastModificationTime: new Date('2024-12-11T21:05:00'), - }, - { - id: '6', - employeeId: '7', - date: new Date('2024-12-10'), - startTime: '16:00', - endTime: '20:00', - totalHours: 4, - reason: 'Yeni müşteri onboarding süreci', - status: LeaveStatusEnum.Pending, - rate: 1.5, - amount: 600, // 4 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-10T16:00:00'), - lastModificationTime: new Date('2024-12-10T16:00:00'), - }, - { - id: '7', - employeeId: '8', - date: new Date('2024-12-09'), - startTime: '17:45', - endTime: '21:15', - totalHours: 3.5, - reason: 'Veri analizi ve raporlama çalışmaları', - status: LeaveStatusEnum.Approved, - approvedBy: 'emp_002', - rate: 1.5, - amount: 525, // 3.5 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-09T17:45:00'), - lastModificationTime: new Date('2024-12-09T21:20:00'), - }, - { - id: '8', - employeeId: '9', - date: new Date('2024-12-08'), - startTime: '18:00', - endTime: '20:30', - totalHours: 2.5, - reason: 'Eğitim materyali hazırlama', - status: LeaveStatusEnum.Pending, - rate: 1.5, - amount: 375, // 2.5 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-08T18:00:00'), - lastModificationTime: new Date('2024-12-08T18:00:00'), - }, - { - id: '9', - employeeId: '10', - date: new Date('2024-12-07'), - startTime: '19:30', - endTime: '23:00', - totalHours: 3.5, - reason: 'Kritik sistem güvenlik yaması uygulaması', - status: LeaveStatusEnum.Approved, - approvedBy: 'emp_001', - rate: 1.5, - amount: 525, // 3.5 saat * 100 TL/saat * 1.5 kat - creationTime: new Date('2024-12-07T19:30:00'), - lastModificationTime: new Date('2024-12-07T23:05:00'), - }, - { - id: '10', - employeeId: '1', - date: new Date('2024-12-06'), - startTime: '17:30', - endTime: '20:00', - totalHours: 2.5, - reason: 'Stratejik planlama toplantısı hazırlığı', - status: LeaveStatusEnum.Rejected, - approvedBy: 'emp_002', - rate: 1.5, - amount: 0, // Reddedildiği için ücret hesaplanmadı - creationTime: new Date('2024-12-06T17:30:00'), - lastModificationTime: new Date('2024-12-06T08:15:00'), - }, -] \ No newline at end of file diff --git a/ui/src/proxy/intranet/models.ts b/ui/src/proxy/intranet/models.ts index 51c56df2..8b3ca2c0 100644 --- a/ui/src/proxy/intranet/models.ts +++ b/ui/src/proxy/intranet/models.ts @@ -28,7 +28,8 @@ export interface IntranetDashboardDto { meals: MealDto[] leaves: LeaveDto[] overtimes: OvertimeDto[] - // surveys: Survey[] + surveys: SurveyDto[] + socialPosts: SocialPostDto[] // priorityTasks: TaskDto[] } @@ -323,3 +324,97 @@ export interface LeaveDto { creationTime: Date lastModificationTime: Date } + +// Anket Cevap +export interface SurveyAnswerDto { + questionId: string + questionType: 'rating' | 'multiple-choice' | 'text' | 'textarea' | 'yes-no' + value: string | number | string[] +} + +// Sosyal Duvar - Comment Interface +export interface SocialCommentDto { + id: string + creator: EmployeeDto + content: string + creationTime: Date +} + +export interface SocialPollOptionDto { + id: string + text: string + votes: number +} + +// Sosyal Duvar - Social Media Interface +export interface SocialMediaDto { + id?: string + type: 'image' | 'video' | 'poll' + + // Ortak alanlar + urls?: string[] + + // Anket (poll) ile ilgili alanlar doğrudan burada + pollQuestion?: string + pollOptions?: SocialPollOptionDto[] + pollTotalVotes?: number + pollEndsAt?: Date + pollUserVoteId?: string +} + +// Sosyal Duvar - Ana Interface +export interface SocialPostDto { + id: string + employee: EmployeeDto + content: string + locationJson?: string + media?: SocialMediaDto + likeCount: number + isLiked: boolean + likeUsers: EmployeeDto[] + comments: SocialCommentDto[] + isOwnPost: boolean + creationTime: Date +} + +// Anket Cevabı +export interface SurveyResponseDto { + id: string + surveyId: string + respondentId?: string // Anonymous ise null + submissionTime: Date + answers: SurveyAnswerDto[] +} + +// Anket Sorusu Seçeneği +export interface SurveyQuestionOptionDto { + id: string + text: string + order: number +} + +// Anket Sorusu +export interface SurveyQuestionDto { + id: string + surveyId: string + questionText: string + type: 'rating' | 'multiple-choice' | 'text' | 'textarea' | 'yes-no' + order: number + isRequired: boolean + options?: SurveyQuestionOptionDto[] +} + +// Anket +export interface SurveyDto { + id: string + title: string + description: string + creatorId: EmployeeDto + creationTime: Date + deadline: Date + questions: SurveyQuestionDto[] + responses: number + targetAudience: string[] + status: 'draft' | 'active' | 'closed' + isAnonymous: boolean +} diff --git a/ui/src/types/intranet.ts b/ui/src/types/intranet.ts index c0657361..2d4de90f 100644 --- a/ui/src/types/intranet.ts +++ b/ui/src/types/intranet.ts @@ -1,4 +1,7 @@ -import { EmployeeDto } from "@/proxy/intranet/models" +import { + EmployeeDto, + SurveyQuestionDto, +} from '@/proxy/intranet/models' // Görev export interface Task { @@ -16,102 +19,3 @@ export interface Task { attachments?: { name: string; url: string }[] comments: number } - -// Anket -export interface Survey { - id: string - title: string - description: string - creatorId: EmployeeDto - creationTime: Date - deadline: Date - questions: SurveyQuestion[] - responses: number - targetAudience: string[] - status: 'draft' | 'active' | 'closed' - isAnonymous: boolean -} - -// Anket Sorusu -export interface SurveyQuestion { - id: string - surveyId: string - questionText: string - type: 'rating' | 'multiple-choice' | 'text' | 'textarea' | 'yes-no' - order: number - isRequired: boolean - options?: SurveyQuestionOption[] - ratingConfig?: { - min: number - max: number - labels?: { [key: number]: string } - } -} - -// Anket Sorusu Seçeneği -export interface SurveyQuestionOption { - id: string - text: string - order: number -} - -// Anket Cevabı -export interface SurveyResponse { - id: string - surveyId: string - respondentId?: string // Anonymous ise null - submissionTime: Date - answers: SurveyAnswer[] -} - -// Anket Cevap -export interface SurveyAnswer { - questionId: string - questionType: 'rating' | 'multiple-choice' | 'text' | 'textarea' | 'yes-no' - value: string | number | string[] -} - -// Sosyal Duvar - Ana Interface -export interface SocialPost { - id: string - creator: EmployeeDto - content: string - locationJson?: string - media?: SocialMedia - likeCount: number - isLiked: boolean - likeUsers: EmployeeDto[] - comments: SocialComment[] - isOwnPost: boolean - creationTime: Date -} - -// Sosyal Duvar - Social Media Interface -export interface SocialMedia { - id?: string - type: 'image' | 'video' | 'poll' - - // Ortak alanlar - urls?: string[] - - // Anket (poll) ile ilgili alanlar doğrudan burada - pollQuestion?: string - pollOptions?: SocialPollOption[] - pollTotalVotes?: number - pollEndsAt?: Date - pollUserVoteId?: string -} - -export interface SocialPollOption { - id: string - text: string - votes: number -} - -// Sosyal Duvar - Comment Interface -export interface SocialComment { - id: string - creator: EmployeeDto - content: string - creationTime: Date -} diff --git a/ui/src/views/hr/components/LeaveManagement.tsx b/ui/src/views/hr/components/LeaveManagement.tsx deleted file mode 100644 index b8c560f8..00000000 --- a/ui/src/views/hr/components/LeaveManagement.tsx +++ /dev/null @@ -1,1047 +0,0 @@ -import React, { useState } from 'react' -import { - FaCalendar, - FaUser, - FaPlus, - FaEdit, - FaCheck, - FaTimes, - FaEye, - FaUsers, -} from 'react-icons/fa' -import { LeaveStatusEnum, LeaveTypeEnum } from '../../../types/hr' -import DataTable, { Column } from '../../../components/common/DataTable' -import { mockEmployees } from '../../../mocks/mockEmployees' -import { mockDepartments } from '../../../mocks/mockDepartments' -import Widget from '../../../components/common/Widget' -import { getLeaveTypeText, getLeaveStatusColor, getLeaveStatusText } from '../../../utils/erp' -import { Container } from '@/components/shared' -import { mockLeaves } from '@/mocks/mockIntranet' -import { LeaveDto } from '@/proxy/intranet/models' - -const LeaveManagement: React.FC = () => { - // Leave states - const [leaves, setLeaves] = useState(mockLeaves) - const [selectedStatus, setSelectedStatus] = useState('all') - const [selectedType, setSelectedType] = useState('all') - const [selectedPeriod, setSelectedPeriod] = useState('all') - const [selectedDepartment, setSelectedDepartment] = useState('all') - const [searchLeavesTerm, setSearchLeavesTerm] = useState('') - - // Modal states - const [showAddModal, setShowAddModal] = useState(false) - const [showEditModal, setShowEditModal] = useState(false) - const [showViewModal, setShowViewModal] = useState(false) - const [showRejectModal, setShowRejectModal] = useState(false) - const [showBulkModal, setShowBulkModal] = useState(false) - const [selectedLeave, setSelectedLeave] = useState(null) - const [rejectReason, setRejectReason] = useState('') - - // Form state for add/edit - const [formData, setFormData] = useState({ - employeeId: '', - leaveType: LeaveTypeEnum.Annual, - startDate: '', - endDate: '', - reason: '', - isHalfDay: false, - }) - - // Bulk leave form state - const [bulkFormData, setBulkFormData] = useState({ - departmentId: '', - selectedEmployees: [] as string[], - leaveType: LeaveTypeEnum.Annual, - startDate: '', - endDate: '', - reason: '', - isHalfDay: false, - }) - - // Get employees by department - const getEmployeesByDepartment = (departmentId: string) => { - return mockEmployees.filter((emp) => emp.departmentId === departmentId) - } - - // Get selected employee object - const getSelectedEmployee = (employeeId: string) => { - return mockEmployees.find((emp) => emp.id === employeeId) - } - - const handleAdd = () => { - setFormData({ - employeeId: '', - leaveType: LeaveTypeEnum.Annual, - startDate: '', - endDate: '', - reason: '', - isHalfDay: false, - }) - setShowAddModal(true) - } - - const handleBulkAdd = () => { - setBulkFormData({ - departmentId: '', - selectedEmployees: [], - leaveType: LeaveTypeEnum.Annual, - startDate: '', - endDate: '', - reason: '', - isHalfDay: false, - }) - setShowBulkModal(true) - } - - const handleEdit = (leave: LeaveDto) => { - setSelectedLeave(leave) - setFormData({ - employeeId: leave.employeeId, - leaveType: leave.leaveType, - startDate: new Date(leave.startDate).toISOString().split('T')[0], - endDate: new Date(leave.endDate).toISOString().split('T')[0], - reason: leave.reason || '', - isHalfDay: leave.isHalfDay, - }) - setShowEditModal(true) - } - - const handleApprove = (id: string) => { - setLeaves((prevLeaves) => - prevLeaves.map((leave) => - leave.id === id - ? { - ...leave, - status: LeaveStatusEnum.Approved, - approvedDate: new Date(), - lastModificationTime: new Date(), - } - : leave, - ), - ) - alert('İzin talebi onaylandı!') - } - - const handleReject = (id: string, reason?: string) => { - if (reason) { - setLeaves((prevLeaves) => - prevLeaves.map((leave) => - leave.id === id - ? { - ...leave, - status: LeaveStatusEnum.Rejected, - rejectionReason: reason, - lastModificationTime: new Date(), - } - : leave, - ), - ) - setShowRejectModal(false) - setRejectReason('') - alert('İzin talebi reddedildi!') - } else { - const leave = leaves.find((l) => l.id === id) - if (leave) { - setSelectedLeave(leave) - setShowRejectModal(true) - } - } - } - - const handleView = (leave: LeaveDto) => { - setSelectedLeave(leave) - setShowViewModal(true) - } - - const handleSubmitAdd = () => { - if (!formData.employeeId || !formData.startDate || !formData.endDate) { - alert('Lütfen tüm gerekli alanları doldurun!') - return - } - - const startDate = new Date(formData.startDate) - const endDate = new Date(formData.endDate) - const totalDays = - Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1 - - const newLeave: LeaveDto = { - id: `leave_${Date.now()}`, - employeeId: formData.employeeId, - leaveType: formData.leaveType, - startDate: startDate, - endDate: endDate, - totalDays: formData.isHalfDay ? 0.5 : totalDays, - reason: formData.reason, - status: LeaveStatusEnum.Pending, - appliedDate: new Date(), - isHalfDay: formData.isHalfDay, - attachments: [], - creationTime: new Date(), - lastModificationTime: new Date(), - } - - setLeaves((prevLeaves) => [...prevLeaves, newLeave]) - setShowAddModal(false) - alert('İzin talebi başarıyla oluşturuldu!') - } - - const handleSubmitEdit = () => { - if (!selectedLeave) return - - if (!formData.employeeId || !formData.startDate || !formData.endDate) { - alert('Lütfen tüm gerekli alanları doldurun!') - return - } - - const startDate = new Date(formData.startDate) - const endDate = new Date(formData.endDate) - const totalDays = - Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1 - - setLeaves((prevLeaves) => - prevLeaves.map((leave) => - leave.id === selectedLeave.id - ? { - ...leave, - employeeId: formData.employeeId, - leaveType: formData.leaveType, - startDate: startDate, - endDate: endDate, - totalDays: formData.isHalfDay ? 0.5 : totalDays, - reason: formData.reason, - isHalfDay: formData.isHalfDay, - lastModificationTime: new Date(), - } - : leave, - ), - ) - - setShowEditModal(false) - setSelectedLeave(null) - alert('İzin talebi başarıyla güncellendi!') - } - - const handleSubmitReject = () => { - if (!selectedLeave || !rejectReason.trim()) { - alert('Lütfen red nedeni giriniz!') - return - } - - handleReject(selectedLeave.id, rejectReason) - } - - const handleSubmitBulk = () => { - if ( - !bulkFormData.selectedEmployees.length || - !bulkFormData.startDate || - !bulkFormData.endDate - ) { - alert('Lütfen en az bir personel seçin ve tüm gerekli alanları doldurun!') - return - } - - const startDate = new Date(bulkFormData.startDate) - const endDate = new Date(bulkFormData.endDate) - const totalDays = - Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1 - - const newLeaves: LeaveDto[] = bulkFormData.selectedEmployees.map((employeeId) => { - const employee = getSelectedEmployee(employeeId) - return { - id: `leave_${Date.now()}_${employeeId}`, - employeeId: employeeId, - employee: employee, - leaveType: bulkFormData.leaveType, - startDate: startDate, - endDate: endDate, - totalDays: bulkFormData.isHalfDay ? 0.5 : totalDays, - reason: bulkFormData.reason, - status: LeaveStatusEnum.Pending, - appliedDate: new Date(), - isHalfDay: bulkFormData.isHalfDay, - attachments: [], - creationTime: new Date(), - lastModificationTime: new Date(), - } - }) - - setLeaves((prevLeaves) => [...prevLeaves, ...newLeaves]) - setShowBulkModal(false) - setBulkFormData({ - departmentId: '', - selectedEmployees: [], - leaveType: LeaveTypeEnum.Annual, - startDate: '', - endDate: '', - reason: '', - isHalfDay: false, - }) - alert(`${newLeaves.length} personel için toplu izin talebi başarıyla oluşturuldu!`) - } - - const filteredLeaves = leaves.filter((leave) => { - if (selectedStatus !== 'all' && leave.status !== selectedStatus) { - return false - } - if (selectedType !== 'all' && leave.leaveType !== selectedType) { - return false - } - if (selectedDepartment !== 'all' && leave.employee?.department?.name !== selectedDepartment) { - return false - } - if (selectedPeriod !== 'all') { - const now = new Date() - const leaveStart = new Date(leave.startDate) - - switch (selectedPeriod) { - case 'current': { - const currentMonth = now.getMonth() - const currentYear = now.getFullYear() - return leaveStart.getMonth() === currentMonth && leaveStart.getFullYear() === currentYear - } - case 'upcoming': - return leaveStart > now - case 'past': - return leaveStart < now - default: - return true - } - } - - // Search filtresi - if (searchLeavesTerm.trim() !== '') { - const term = searchLeavesTerm.toLowerCase() - const employee = leave.employee - - const matches = - employee?.fullName.toLowerCase().includes(term) || - employee?.code.toLowerCase().includes(term) || - employee?.email?.toLowerCase().includes(term) - - if (!matches) { - return false - } - } - - return true - }) - - const columns: Column[] = [ - { - key: 'employee', - header: 'Personel', - render: (leave: LeaveDto) => ( -
- -
-
{leave.employee?.fullName}
-
{leave.employee?.code}
-
-
- ), - }, - { - key: 'leaveType', - header: 'İzin Türü', - render: (leave: LeaveDto) => getLeaveTypeText(leave.leaveType), - }, - { - key: 'period', - header: 'İzin Dönemi', - render: (leave: LeaveDto) => ( -
-
{new Date(leave.startDate).toLocaleDateString('tr-TR')}
-
{new Date(leave.endDate).toLocaleDateString('tr-TR')}
-
- ), - }, - { - key: 'totalDays', - header: 'Gün Sayısı', - render: (leave: LeaveDto) => ( -
- - {leave.totalDays} gün -
- ), - }, - { - key: 'appliedDate', - header: 'Başvuru Tarihi', - render: (leave: LeaveDto) => new Date(leave.appliedDate).toLocaleDateString('tr-TR'), - }, - { - key: 'status', - header: 'Durum', - render: (leave: LeaveDto) => ( - - {getLeaveStatusText(leave.status)} - - ), - }, - { - key: 'actions', - header: 'İşlemler', - render: (leave: LeaveDto) => ( -
- - - {leave.status === LeaveStatusEnum.Pending && ( - <> - - - - )} - - -
- ), - }, - ] - - // Calculate statistics - const stats = { - total: leaves.length, - pending: leaves.filter((l) => l.status === LeaveStatusEnum.Pending).length, - approved: leaves.filter((l) => l.status === LeaveStatusEnum.Approved).length, - rejected: leaves.filter((l) => l.status === LeaveStatusEnum.Rejected).length, - } - - return ( - -
- {/* Header */} -
-
-

İzin Yönetimi

-

Personel izin talepleri ve onay süreçleri

-
-
- - -
-
- - {/* Stats Cards */} -
- - - - - - - -
- - {/* Filters */} -
- - - - - - - - - -
- - {/* Data Table */} -
- -
- - {filteredLeaves.length === 0 && ( -
- -

İzin talebi bulunamadı

-

Seçilen kriterlere uygun izin talebi bulunmamaktadır.

-
- )} -
- - {/* Add/Edit Modal */} - {(showAddModal || (showEditModal && selectedLeave)) && ( -
-
-

- {showAddModal ? 'Yeni İzin Talebi' : 'İzin Talebini Düzenle'} -

- -
-
- - -
- -
- - -
- -
-
- - setFormData({ ...formData, startDate: e.target.value })} - className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" - /> -
- -
- - setFormData({ ...formData, endDate: e.target.value })} - className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" - /> -
-
- -
- -
- -
- -