From ea5685439c0a983a3eac0366de86fd19cc7d7e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96zt=C3=BCrk?= Date: Mon, 20 Oct 2025 21:38:21 +0300 Subject: [PATCH] =?UTF-8?q?Intranet=20d=C3=BCzenlemeleri?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ui/src/mocks/mockIntranetData.ts | 521 ++++++++++-------- ui/src/mocks/mockSocialPosts.ts | 312 ----------- ui/src/types/intranet.ts | 297 ++++++++++ .../views/intranet/SocialWall/CreatePost.tsx | 33 +- .../views/intranet/SocialWall/LocationMap.tsx | 8 +- .../intranet/SocialWall/LocationPicker.tsx | 26 +- .../intranet/SocialWall/MediaLightbox.tsx | 7 +- .../intranet/SocialWall/MediaManager.tsx | 22 +- ui/src/views/intranet/SocialWall/PostItem.tsx | 28 +- .../intranet/SocialWall/UserProfileCard.tsx | 12 +- ui/src/views/intranet/SocialWall/index.tsx | 8 +- 11 files changed, 639 insertions(+), 635 deletions(-) delete mode 100644 ui/src/mocks/mockSocialPosts.ts create mode 100644 ui/src/types/intranet.ts diff --git a/ui/src/mocks/mockIntranetData.ts b/ui/src/mocks/mockIntranetData.ts index abd63fa6..4b501640 100644 --- a/ui/src/mocks/mockIntranetData.ts +++ b/ui/src/mocks/mockIntranetData.ts @@ -1,230 +1,10 @@ -// Intranet Mock Data Types and Sample Data - import { mockEmployees } from './mockEmployees' import { mockEmployeeLeaves } from './mockEmployeeLeaves' import { mockOvertimes } from './mockOvertimes' -import type { HrEmployee, HrOvertime } from '../types/hr' -import { mockDepartments } from './mockDepartments' -// Duyuru -export interface Announcement { - id: string - title: string - content: string - excerpt: string - category: 'general' | 'hr' | 'it' | 'event' | 'urgent' - author: HrEmployee - publishDate: Date - expiryDate?: Date - isPinned: boolean - attachments?: { name: string; url: string; size: string }[] - departments?: string[] - viewCount: number - imageUrl?: string -} +import { Announcement, CalendarEvent, Visitor, Document, Certificate, ExpenseRequest, Task, Birthday, WorkAnniversary, QuickLink, Training, Reservation, MealMenu, ShuttleRoute, Survey, SocialPost } from '@/types/intranet' -// Etkinlik Yorumu -export interface EventComment { - id: string - author: HrEmployee - content: string - createdAt: Date - likes: number -} - -// Etkinlik -export interface CalendarEvent { - id: string - title: string - description: string - type: 'social' | 'training' | 'company' | 'sport' | 'culture' - date: Date - location: string - organizer: HrEmployee - participants: number - photos: string[] - comments: EventComment[] - likes: number - isPublished: boolean -} - -// Harcama -export interface ExpenseRequest { - id: string - employee: HrEmployee - category: 'travel' | 'meal' | 'accommodation' | 'transport' | 'other' - amount: number - currency: string - date: Date - description: string - project?: string - receipts: { name: string; url: string; size: string }[] - status: 'pending' | 'approved' | 'rejected' - approver?: HrEmployee - approvalDate?: Date - notes?: string - createdAt: Date -} - -// Görev -export interface Task { - id: string - title: string - description: string - project: string - assignedTo: HrEmployee[] - assignedBy: HrEmployee - priority: 'low' | 'medium' | 'high' | 'urgent' - status: 'todo' | 'in-progress' | 'review' | 'done' - dueDate: Date - createdAt: Date - labels: string[] - attachments?: { name: string; url: string }[] - comments: number -} - -// Doküman -export interface Document { - id: string - name: string - type: 'pdf' | 'doc' | 'xls' | 'ppt' | 'other' - category: 'policy' | 'procedure' | 'form' | 'template' | 'report' | 'other' - size: string - uploadedBy: HrEmployee - uploadDate: Date - version: string - url: string - description: string - departments: string[] - downloadCount: number - tags: string[] -} - -// Doğum günü -export interface Birthday { - employee: HrEmployee - date: Date - age?: number -} - -// İş yıldönümü -export interface WorkAnniversary { - employee: HrEmployee - hireDate: Date - years: number -} - -// Hızlı Erişim -export interface QuickLink { - id: string - name: string - description: string - icon: string - url: string - color: string - category: string -} - -// Eğitim -export interface Training { - id: string - title: string - description: string - instructor: string - category: 'technical' | 'soft-skills' | 'management' | 'compliance' | 'other' - type: 'online' | 'classroom' | 'hybrid' - duration: number // saat - startDate: Date - endDate: Date - maxParticipants: number - enrolled: number - status: 'upcoming' | 'ongoing' | 'completed' - location?: string - thumbnail?: string -} - -// Sertifika -export interface Certificate { - id: string - employee: HrEmployee - trainingTitle: string - issueDate: Date - expiryDate?: Date - certificateUrl: string - score?: number -} - -// Rezervasyon -export interface Reservation { - id: string - type: 'room' | 'vehicle' | 'equipment' - resourceName: string - bookedBy: HrEmployee - startDate: Date - endDate: Date - purpose: string - status: 'pending' | 'approved' | 'rejected' | 'completed' - participants?: number - notes?: string -} - -// Yemek Menüsü -export interface MealMenu { - id: string - date: Date - dayOfWeek: string - meals: { - type: 'breakfast' | 'lunch' | 'dinner' - items: string[] - calories?: number - }[] -} - -// Servis -export interface ShuttleRoute { - id: string - name: string - route: string[] - departureTime: string - arrivalTime: string - capacity: number - available: number - type: 'morning' | 'evening' -} - -// Anket -export interface Survey { - id: string - title: string - description: string - createdBy: HrEmployee - createdAt: Date - deadline: Date - totalQuestions: number - responses: number - targetAudience: string[] - status: 'draft' | 'active' | 'closed' - isAnonymous: boolean -} - -// Ziyaretçi -export interface Visitor { - id: string - fullName: string - company: string - email: string - phone: string - visitDate: Date - checkIn?: Date - checkOut?: Date - host: HrEmployee - purpose: string - status: 'scheduled' | 'checked-in' | 'checked-out' | 'cancelled' - badgeNumber?: string - photo?: string -} // ============== SAMPLE DATA ============== - export const mockAnnouncements: Announcement[] = [ { id: 'ann1', @@ -315,14 +95,14 @@ export const mockEvents: CalendarEvent[] = [ id: 'c1', author: mockEmployees[0], content: 'Muhteşem bir gündü! Yılın en güzel etkinliği 🎉', - createdAt: new Date('2025-07-16T10:30:00'), + 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!', - createdAt: new Date('2025-07-16T14:20:00'), + creationTime: new Date('2025-07-16T14:20:00'), likes: 8, }, ], @@ -348,14 +128,14 @@ export const mockEvents: CalendarEvent[] = [ id: 'c3', author: mockEmployees[1], content: 'Ekibimiz 2. oldu! Çok gurur duydum herkesle 💪', - createdAt: new Date('2025-09-11T09:00:00'), + creationTime: new Date('2025-09-11T09:00:00'), likes: 15, }, { id: 'c4', author: mockEmployees[3], content: 'Gece boyunca kod yazmak ve pizza yemek priceless! 🍕', - createdAt: new Date('2025-09-11T11:45:00'), + creationTime: new Date('2025-09-11T11:45:00'), likes: 10, }, ], @@ -382,7 +162,7 @@ export const mockEvents: CalendarEvent[] = [ id: 'c5', author: mockEmployees[4], content: 'İT departmanı şampiyon oldu! Gelecek sene kupayı koruyacağız 🏆', - createdAt: new Date('2025-06-21T08:30:00'), + creationTime: new Date('2025-06-21T08:30:00'), likes: 18, }, ], @@ -410,21 +190,21 @@ export const mockEvents: CalendarEvent[] = [ id: 'c6', author: mockEmployees[0], content: 'Yılın en şık gecesi! Organizasyon mükemmeldi 👏', - createdAt: new Date('2024-12-29T10:00:00'), + creationTime: new Date('2024-12-29T10:00:00'), likes: 25, }, { id: 'c7', author: mockEmployees[1], content: 'Tombala hediyelerim harika, çok teşekkürler! 🎁', - createdAt: new Date('2024-12-29T12:30:00'), + 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! 🎵', - createdAt: new Date('2024-12-29T15:20:00'), + creationTime: new Date('2024-12-29T15:20:00'), likes: 19, }, ], @@ -450,7 +230,7 @@ export const mockEvents: CalendarEvent[] = [ id: 'c9', author: mockEmployees[3], content: 'İlk defa ebru yaptım, çok huzurlu bir deneyimdi 🎨', - createdAt: new Date('2025-05-13T09:15:00'), + creationTime: new Date('2025-05-13T09:15:00'), likes: 11, }, ], @@ -479,7 +259,7 @@ export const mockExpenseRequests: ExpenseRequest[] = [ status: 'approved', approver: mockEmployees[4], approvalDate: new Date('2024-10-16T10:00:00'), - createdAt: new Date('2024-10-15T18:00:00'), + creationTime: new Date('2024-10-15T18:00:00'), }, { id: 'exp2', @@ -491,7 +271,7 @@ export const mockExpenseRequests: ExpenseRequest[] = [ description: 'Müşteri toplantısı - öğle yemeği', receipts: [{ name: 'restoran_fisi.jpg', url: '#', size: '156 KB' }], status: 'pending', - createdAt: new Date('2024-10-17T20:00:00'), + creationTime: new Date('2024-10-17T20:00:00'), }, { id: 'exp3', @@ -506,7 +286,7 @@ export const mockExpenseRequests: ExpenseRequest[] = [ status: 'approved', approver: mockEmployees[4], approvalDate: new Date('2024-10-15T09:00:00'), - createdAt: new Date('2024-10-14T22:00:00'), + creationTime: new Date('2024-10-14T22:00:00'), }, ] @@ -521,7 +301,7 @@ export const mockTasks: Task[] = [ priority: 'high', status: 'in-progress', dueDate: new Date('2024-10-25'), - createdAt: new Date('2024-10-14'), + creationTime: new Date('2024-10-14'), labels: ['backend', 'api'], comments: 3, }, @@ -535,7 +315,7 @@ export const mockTasks: Task[] = [ priority: 'medium', status: 'review', dueDate: new Date('2024-10-22'), - createdAt: new Date('2024-10-10'), + creationTime: new Date('2024-10-10'), labels: ['design', 'ui/ux'], comments: 5, }, @@ -549,7 +329,7 @@ export const mockTasks: Task[] = [ priority: 'urgent', status: 'todo', dueDate: new Date('2024-10-20'), - createdAt: new Date('2024-10-17'), + creationTime: new Date('2024-10-17'), labels: ['devops', 'infrastructure'], comments: 1, }, @@ -962,8 +742,8 @@ 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ı', - createdBy: mockEmployees[0], - createdAt: new Date('2024-10-01'), + creatorId: mockEmployees[0], + creationTime: new Date('2024-10-01'), deadline: new Date('2024-10-31'), totalQuestions: 25, responses: 45, @@ -975,8 +755,8 @@ export const mockSurveys: Survey[] = [ id: 'survey2', title: 'Eğitim İhtiyaç Analizi', description: '2025 yılı eğitim planlaması için ihtiyaç tespiti', - createdBy: mockEmployees[2], - createdAt: new Date('2024-10-10'), + creatorId: mockEmployees[2], + creationTime: new Date('2024-10-10'), deadline: new Date('2024-11-15'), totalQuestions: 15, responses: 28, @@ -988,8 +768,8 @@ export const mockSurveys: Survey[] = [ id: 'survey3', title: 'Kafeterya Memnuniyet Anketi', description: 'Yemek kalitesi ve servis değerlendirmesi', - createdBy: mockEmployees[4], - createdAt: new Date('2024-09-15'), + creatorId: mockEmployees[4], + creationTime: new Date('2024-09-15'), deadline: new Date('2024-09-30'), totalQuestions: 10, responses: 62, @@ -1043,3 +823,260 @@ export const mockVisitors: Visitor[] = [ photo: 'https://i.pravatar.cc/150?img=68', }, ] + +export const mockSocialPosts: SocialPost[] = [ + { + id: '1', + author: { + id: 'user1', + name: 'Ahmet Yılmaz', + avatar: 'https://i.pravatar.cc/150?img=12', + title: 'Yazılım Geliştirici', + email: 'ahmet.yilmaz@sozsoft.com', + phone: '+90 532 123 45 67', + department: 'Yazılım Geliştirme', + location: 'İstanbul, Türkiye' + }, + 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'), + location: { + id: '1', + name: 'Taksim Meydanı', + address: 'Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul', + lat: 41.0369, + lng: 28.9850, + placeId: 'ChIJBQRGmL25yhQRXwqRTHAwAAQ' + }, + media: { + type: 'image', + url: 'https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80' + }, + likes: { + count: 24, + isLiked: true, + users: [ + { id: 'user2', name: 'Ayşe Demir', avatar: 'https://i.pravatar.cc/150?img=5' }, + { id: 'user3', name: 'Mehmet Kaya', avatar: 'https://i.pravatar.cc/150?img=8' } + ] + }, + comments: [ + { + id: 'c1', + author: { + id: 'user2', + name: 'Ayşe Demir', + avatar: 'https://i.pravatar.cc/150?img=5' + }, + content: 'Harika görünüyor! Başarılar 👏', + creationTime: new Date('2024-10-15T11:00:00') + }, + { + id: 'c2', + author: { + id: 'user3', + name: 'Mehmet Kaya', + avatar: 'https://i.pravatar.cc/150?img=8' + }, + content: 'TypeScript gerçekten fark yaratıyor!', + creationTime: new Date('2024-10-15T11:30:00') + } + ], + isOwnPost: false + }, + { + id: '2', + author: { + id: 'currentUser', + name: 'Siz', + avatar: 'https://i.pravatar.cc/150?img=1', + title: 'Proje Yöneticisi' + }, + 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', + poll: { + question: 'Hangi özelliği öncelikli olarak geliştirmeliyiz?', + options: [ + { 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 } + ], + totalVotes: 40, + endsAt: new Date('2024-10-20T23:59:59'), + userVote: 'p3' + } + }, + likes: { + count: 18, + isLiked: false, + users: [] + }, + comments: [ + { + id: 'c3', + author: { + id: 'user4', + name: 'Fatma Şahin', + avatar: 'https://i.pravatar.cc/150?img=9' + }, + content: 'Mesajlaşma özelliğine kesinlikle ihtiyacımız var!', + creationTime: new Date('2024-10-16T10:15:00') + } + ], + isOwnPost: true + }, + { + id: '3', + author: { + id: 'user5', + name: 'Zeynep Arslan', + avatar: 'https://i.pravatar.cc/150?img=10', + title: 'UI/UX Tasarımcı' + }, + 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' + ] + }, + likes: { + count: 42, + isLiked: true, + users: [ + { id: 'user1', name: 'Ahmet Yılmaz', avatar: 'https://i.pravatar.cc/150?img=12' } + ] + }, + comments: [ + { + id: 'c4', + author: { + id: 'user6', + name: 'Can Öztürk', + avatar: 'https://i.pravatar.cc/150?img=11' + }, + content: 'Tasarımlar çok şık! Renk paleti özellikle güzel 😍', + creationTime: new Date('2024-10-17T15:00:00') + }, + { + id: 'c5', + author: { + id: 'user7', + name: 'Elif Yıldız', + avatar: 'https://i.pravatar.cc/150?img=20' + }, + content: 'Dark mode opsiyonu da olacak mı?', + creationTime: new Date('2024-10-17T15:30:00') + } + ], + isOwnPost: false + }, + { + id: '4', + author: { + id: 'user8', + name: 'Burak Çelik', + avatar: 'https://i.pravatar.cc/150?img=13', + title: 'DevOps Mühendisi' + }, + 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', + url: 'https://www.w3schools.com/html/mov_bbb.mp4' + }, + likes: { + count: 31, + isLiked: false, + users: [] + }, + comments: [ + { + id: 'c6', + author: { + id: 'user9', + name: 'Deniz Koç', + avatar: 'https://i.pravatar.cc/150?img=14' + }, + content: 'Harika iş! Detayları paylaşabilir misin?', + creationTime: new Date('2024-10-18T09:15:00') + } + ], + isOwnPost: false + }, + { + id: '5', + author: { + id: 'user10', + name: 'Selin Aydın', + avatar: 'https://i.pravatar.cc/150?img=15', + title: 'İK Müdürü' + }, + 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'), + likes: { + count: 56, + isLiked: true, + users: [] + }, + comments: [ + { + id: 'c7', + author: { + id: 'user1', + name: 'Ahmet Yılmaz', + avatar: 'https://i.pravatar.cc/150?img=12' + }, + content: 'Ne zaman başlıyor?', + creationTime: new Date('2024-10-14T16:30:00') + }, + { + id: 'c8', + author: { + id: 'user10', + name: 'Selin Aydın', + avatar: 'https://i.pravatar.cc/150?img=15' + }, + 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', + author: { + id: 'user11', + name: 'Deniz Öztürk', + avatar: 'https://i.pravatar.cc/150?img=20', + title: 'Proje Yöneticisi' + }, + 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'), + location: { + id: '4', + name: 'Sultanahmet Meydanı', + address: 'Sultanahmet Mahallesi, 34122 Fatih/İstanbul', + lat: 41.0058, + lng: 28.9768, + placeId: 'ChIJ7fVVZiy5yhQRzsXXXXXXXXk' + }, + likes: { + count: 18, + isLiked: false, + users: [] + }, + comments: [], + isOwnPost: false + } +] diff --git a/ui/src/mocks/mockSocialPosts.ts b/ui/src/mocks/mockSocialPosts.ts deleted file mode 100644 index 1d55323a..00000000 --- a/ui/src/mocks/mockSocialPosts.ts +++ /dev/null @@ -1,312 +0,0 @@ -export interface SocialPost { - id: string - author: { - id: string - name: string - avatar: string - title: string - email?: string - phone?: string - department?: string - location?: string - } - content: string - createdAt: Date - location?: { - id: string - name: string - address: string - lat: number - lng: number - placeId?: string - } - media?: { - type: 'image' | 'video' | 'poll' - url?: string - urls?: string[] - poll?: { - question: string - options: Array<{ - id: string - text: string - votes: number - }> - totalVotes: number - endsAt: Date - userVote?: string - } - } - likes: { - count: number - isLiked: boolean - users: Array<{ id: string; name: string; avatar: string }> - } - comments: Array<{ - id: string - author: { - id: string - name: string - avatar: string - } - content: string - createdAt: Date - }> - isOwnPost: boolean -} - -export const mockSocialPosts: SocialPost[] = [ - { - id: '1', - author: { - id: 'user1', - name: 'Ahmet Yılmaz', - avatar: 'https://i.pravatar.cc/150?img=12', - title: 'Yazılım Geliştirici', - email: 'ahmet.yilmaz@sozsoft.com', - phone: '+90 532 123 45 67', - department: 'Yazılım Geliştirme', - location: 'İstanbul, Türkiye' - }, - content: - 'Yeni proje üzerinde çalışıyoruz! React ve TypeScript ile harika bir deneyim oluşturuyoruz. Ekip çalışması harika gidiyor! 🚀', - createdAt: new Date('2024-10-15T10:30:00'), - location: { - id: '1', - name: 'Taksim Meydanı', - address: 'Taksim, Gümüşsuyu Mahallesi, 34437 Beyoğlu/İstanbul', - lat: 41.0369, - lng: 28.9850, - placeId: 'ChIJBQRGmL25yhQRXwqRTHAwAAQ' - }, - media: { - type: 'image', - url: 'https://images.unsplash.com/photo-1633356122544-f134324a6cee?w=800&q=80' - }, - likes: { - count: 24, - isLiked: true, - users: [ - { id: 'user2', name: 'Ayşe Demir', avatar: 'https://i.pravatar.cc/150?img=5' }, - { id: 'user3', name: 'Mehmet Kaya', avatar: 'https://i.pravatar.cc/150?img=8' } - ] - }, - comments: [ - { - id: 'c1', - author: { - id: 'user2', - name: 'Ayşe Demir', - avatar: 'https://i.pravatar.cc/150?img=5' - }, - content: 'Harika görünüyor! Başarılar 👏', - createdAt: new Date('2024-10-15T11:00:00') - }, - { - id: 'c2', - author: { - id: 'user3', - name: 'Mehmet Kaya', - avatar: 'https://i.pravatar.cc/150?img=8' - }, - content: 'TypeScript gerçekten fark yaratıyor!', - createdAt: new Date('2024-10-15T11:30:00') - } - ], - isOwnPost: false - }, - { - id: '2', - author: { - id: 'currentUser', - name: 'Siz', - avatar: 'https://i.pravatar.cc/150?img=1', - title: 'Proje Yöneticisi' - }, - content: - 'Bu hafta sprint planlamasını yaptık. Ekibimizle birlikte yeni özellikleri değerlendirdik. Heyecan verici bir hafta olacak!', - createdAt: new Date('2024-10-16T09:00:00'), - media: { - type: 'poll', - poll: { - question: 'Hangi özelliği öncelikli olarak geliştirmeliyiz?', - options: [ - { 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 } - ], - totalVotes: 40, - endsAt: new Date('2024-10-20T23:59:59'), - userVote: 'p3' - } - }, - likes: { - count: 18, - isLiked: false, - users: [] - }, - comments: [ - { - id: 'c3', - author: { - id: 'user4', - name: 'Fatma Şahin', - avatar: 'https://i.pravatar.cc/150?img=9' - }, - content: 'Mesajlaşma özelliğine kesinlikle ihtiyacımız var!', - createdAt: new Date('2024-10-16T10:15:00') - } - ], - isOwnPost: true - }, - { - id: '3', - author: { - id: 'user5', - name: 'Zeynep Arslan', - avatar: 'https://i.pravatar.cc/150?img=10', - title: 'UI/UX Tasarımcı' - }, - content: - 'Yeni tasarım sistemimizin ilk prototipini hazırladık! Kullanıcı deneyimini iyileştirmek için çok çalıştık. Geri bildirimlerinizi bekliyorum! 🎨', - createdAt: 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' - ] - }, - likes: { - count: 42, - isLiked: true, - users: [ - { id: 'user1', name: 'Ahmet Yılmaz', avatar: 'https://i.pravatar.cc/150?img=12' } - ] - }, - comments: [ - { - id: 'c4', - author: { - id: 'user6', - name: 'Can Öztürk', - avatar: 'https://i.pravatar.cc/150?img=11' - }, - content: 'Tasarımlar çok şık! Renk paleti özellikle güzel 😍', - createdAt: new Date('2024-10-17T15:00:00') - }, - { - id: 'c5', - author: { - id: 'user7', - name: 'Elif Yıldız', - avatar: 'https://i.pravatar.cc/150?img=20' - }, - content: 'Dark mode opsiyonu da olacak mı?', - createdAt: new Date('2024-10-17T15:30:00') - } - ], - isOwnPost: false - }, - { - id: '4', - author: { - id: 'user8', - name: 'Burak Çelik', - avatar: 'https://i.pravatar.cc/150?img=13', - title: 'DevOps Mühendisi' - }, - content: - 'CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪', - createdAt: new Date('2024-10-18T08:45:00'), - media: { - type: 'video', - url: 'https://www.w3schools.com/html/mov_bbb.mp4' - }, - likes: { - count: 31, - isLiked: false, - users: [] - }, - comments: [ - { - id: 'c6', - author: { - id: 'user9', - name: 'Deniz Koç', - avatar: 'https://i.pravatar.cc/150?img=14' - }, - content: 'Harika iş! Detayları paylaşabilir misin?', - createdAt: new Date('2024-10-18T09:15:00') - } - ], - isOwnPost: false - }, - { - id: '5', - author: { - id: 'user10', - name: 'Selin Aydın', - avatar: 'https://i.pravatar.cc/150?img=15', - title: 'İK Müdürü' - }, - 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.', - createdAt: new Date('2024-10-14T16:00:00'), - likes: { - count: 56, - isLiked: true, - users: [] - }, - comments: [ - { - id: 'c7', - author: { - id: 'user1', - name: 'Ahmet Yılmaz', - avatar: 'https://i.pravatar.cc/150?img=12' - }, - content: 'Ne zaman başlıyor?', - createdAt: new Date('2024-10-14T16:30:00') - }, - { - id: 'c8', - author: { - id: 'user10', - name: 'Selin Aydın', - avatar: 'https://i.pravatar.cc/150?img=15' - }, - content: 'Gelecek hafta başlıyoruz! Kayıt linki mail ile paylaşılacak.', - createdAt: new Date('2024-10-14T17:00:00') - } - ], - isOwnPost: false - }, - { - id: '6', - author: { - id: 'user11', - name: 'Deniz Öztürk', - avatar: 'https://i.pravatar.cc/150?img=20', - title: 'Proje Yöneticisi' - }, - content: 'Bugün müşteri ile harika bir toplantı yaptık! Yeni projenin detaylarını konuştuk. 🎯', - createdAt: new Date('2024-10-17T14:00:00'), - location: { - id: '4', - name: 'Sultanahmet Meydanı', - address: 'Sultanahmet Mahallesi, 34122 Fatih/İstanbul', - lat: 41.0058, - lng: 28.9768, - placeId: 'ChIJ7fVVZiy5yhQRzsXXXXXXXXk' - }, - likes: { - count: 18, - isLiked: false, - users: [] - }, - comments: [], - isOwnPost: false - } -] diff --git a/ui/src/types/intranet.ts b/ui/src/types/intranet.ts new file mode 100644 index 00000000..8cc6ac60 --- /dev/null +++ b/ui/src/types/intranet.ts @@ -0,0 +1,297 @@ +import { HrEmployee } from './hr' + +// Duyuru +export interface Announcement { + id: string + title: string + content: string + excerpt: string + category: 'general' | 'hr' | 'it' | 'event' | 'urgent' + author: HrEmployee + publishDate: Date + expiryDate?: Date + isPinned: boolean + attachments?: { name: string; url: string; size: string }[] + departments?: string[] + viewCount: number + imageUrl?: string +} + +// Etkinlik Yorumu +export interface EventComment { + id: string + author: HrEmployee + content: string + creationTime: Date + likes: number +} + +// Etkinlik +export interface CalendarEvent { + id: string + title: string + description: string + type: 'social' | 'training' | 'company' | 'sport' | 'culture' + date: Date + location: string + organizer: HrEmployee + participants: number + photos: string[] + comments: EventComment[] + likes: number + isPublished: boolean +} + +// Harcama +export interface ExpenseRequest { + id: string + employee: HrEmployee + category: 'travel' | 'meal' | 'accommodation' | 'transport' | 'other' + amount: number + currency: string + date: Date + description: string + project?: string + receipts: { name: string; url: string; size: string }[] + status: 'pending' | 'approved' | 'rejected' + approver?: HrEmployee + approvalDate?: Date + notes?: string + creationTime: Date +} + +// Görev +export interface Task { + id: string + title: string + description: string + project: string + assignedTo: HrEmployee[] + assignedBy: HrEmployee + priority: 'low' | 'medium' | 'high' | 'urgent' + status: 'todo' | 'in-progress' | 'review' | 'done' + dueDate: Date + creationTime: Date + labels: string[] + attachments?: { name: string; url: string }[] + comments: number +} + +// Doküman +export interface Document { + id: string + name: string + type: 'pdf' | 'doc' | 'xls' | 'ppt' | 'other' + category: 'policy' | 'procedure' | 'form' | 'template' | 'report' | 'other' + size: string + uploadedBy: HrEmployee + uploadDate: Date + version: string + url: string + description: string + departments: string[] + downloadCount: number + tags: string[] +} + +// Doğum günü +export interface Birthday { + employee: HrEmployee + date: Date + age?: number +} + +// İş yıldönümü +export interface WorkAnniversary { + employee: HrEmployee + hireDate: Date + years: number +} + +// Hızlı Erişim +export interface QuickLink { + id: string + name: string + description: string + icon: string + url: string + color: string + category: string +} + +// Eğitim +export interface Training { + id: string + title: string + description: string + instructor: string + category: 'technical' | 'soft-skills' | 'management' | 'compliance' | 'other' + type: 'online' | 'classroom' | 'hybrid' + duration: number // saat + startDate: Date + endDate: Date + maxParticipants: number + enrolled: number + status: 'upcoming' | 'ongoing' | 'completed' + location?: string + thumbnail?: string +} + +// Sertifika +export interface Certificate { + id: string + employee: HrEmployee + trainingTitle: string + issueDate: Date + expiryDate?: Date + certificateUrl: string + score?: number +} + +// Rezervasyon +export interface Reservation { + id: string + type: 'room' | 'vehicle' | 'equipment' + resourceName: string + bookedBy: HrEmployee + startDate: Date + endDate: Date + purpose: string + status: 'pending' | 'approved' | 'rejected' | 'completed' + participants?: number + notes?: string +} + +// Yemek Menüsü +export interface MealMenu { + id: string + date: Date + dayOfWeek: string + meals: { + type: 'breakfast' | 'lunch' | 'dinner' + items: string[] + calories?: number + }[] +} + +// Servis +export interface ShuttleRoute { + id: string + name: string + route: string[] + departureTime: string + arrivalTime: string + capacity: number + available: number + type: 'morning' | 'evening' +} + +// Anket +export interface Survey { + id: string + title: string + description: string + creatorId: HrEmployee + creationTime: Date + deadline: Date + totalQuestions: number + responses: number + targetAudience: string[] + status: 'draft' | 'active' | 'closed' + isAnonymous: boolean +} + +// Ziyaretçi +export interface Visitor { + id: string + fullName: string + company: string + email: string + phone: string + visitDate: Date + checkIn?: Date + checkOut?: Date + host: HrEmployee + purpose: string + status: 'scheduled' | 'checked-in' | 'checked-out' | 'cancelled' + badgeNumber?: string + photo?: string +} + +export interface MediaItem { + id: string + type: 'image' | 'video' + url: string + file?: File +} + +export interface LightboxMedia { + type: 'image' | 'video' + url?: string + urls?: string[] +} + +export interface Location { + id: string + name: string + address: string + lat: number + lng: number + placeId?: string +} + +export interface SocialPost { + id: string + author: { + id: string + name: string + avatar: string + title: string + email?: string + phone?: string + department?: string + location?: string + } + content: string + creationTime: Date + location?: { + id: string + name: string + address: string + lat: number + lng: number + placeId?: string + } + media?: { + type: 'image' | 'video' | 'poll' + url?: string + urls?: string[] + poll?: { + question: string + options: Array<{ + id: string + text: string + votes: number + }> + totalVotes: number + endsAt: Date + userVote?: string + } + } + likes: { + count: number + isLiked: boolean + users: Array<{ id: string; name: string; avatar: string }> + } + comments: Array<{ + id: string + author: { + id: string + name: string + avatar: string + } + content: string + creationTime: Date + }> + isOwnPost: boolean +} diff --git a/ui/src/views/intranet/SocialWall/CreatePost.tsx b/ui/src/views/intranet/SocialWall/CreatePost.tsx index ff4938e3..0cd5eb17 100644 --- a/ui/src/views/intranet/SocialWall/CreatePost.tsx +++ b/ui/src/views/intranet/SocialWall/CreatePost.tsx @@ -3,14 +3,15 @@ import { motion, AnimatePresence } from 'framer-motion' import classNames from 'classnames' import EmojiPicker, { EmojiClickData } from 'emoji-picker-react' import { - HiOutlineChartBar, - HiOutlineEmojiHappy, - HiX, - HiOutlineCollection, - HiOutlineLocationMarker -} from 'react-icons/hi' -import MediaManager, { MediaItem } from './MediaManager' -import LocationPicker, { Location } from './LocationPicker' + FaChartBar, + FaSmile, + FaTimes, + FaImages, + FaMapMarkerAlt +} from 'react-icons/fa' +import MediaManager from './MediaManager' +import LocationPicker from './LocationPicker' +import { Location, MediaItem } from '@/types/intranet' interface CreatePostProps { onCreatePost: (post: { @@ -220,7 +221,7 @@ const CreatePost: React.FC = ({ onCreatePost }) => { onClick={() => removeMediaItem(item.id)} className="absolute -top-2 -right-2 p-1 bg-red-600 text-white rounded-full opacity-0 group-hover:opacity-100 transition-opacity" > - +
{item.type === 'image' ? '📷' : '🎥'} @@ -232,7 +233,7 @@ const CreatePost: React.FC = ({ onCreatePost }) => { onClick={() => setShowMediaManager(true)} className="h-24 border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg flex items-center justify-center hover:border-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 transition-colors" > - +
@@ -258,7 +259,7 @@ const CreatePost: React.FC = ({ onCreatePost }) => {
- +

{location.name} @@ -315,7 +316,7 @@ const CreatePost: React.FC = ({ onCreatePost }) => { onClick={() => removePollOption(index)} className="p-2 text-gray-500 hover:text-red-600" > - + )}

@@ -365,7 +366,7 @@ const CreatePost: React.FC = ({ onCreatePost }) => { )} title={mediaType === 'media' ? 'Medyaları düzenle' : 'Medya ekle'} > - + {mediaType === 'media' && mediaItems.length > 0 && ( {mediaItems.length} @@ -389,7 +390,7 @@ const CreatePost: React.FC = ({ onCreatePost }) => { )} title={mediaType === 'poll' ? 'Anketi kaldır' : 'Anket ekle'} > - + {/* Emoji Picker */} diff --git a/ui/src/views/intranet/SocialWall/LocationMap.tsx b/ui/src/views/intranet/SocialWall/LocationMap.tsx index d7813010..3eb55f4a 100644 --- a/ui/src/views/intranet/SocialWall/LocationMap.tsx +++ b/ui/src/views/intranet/SocialWall/LocationMap.tsx @@ -1,6 +1,6 @@ import React from 'react' -import { HiOutlineExternalLink, HiOutlineLocationMarker } from 'react-icons/hi' -import type { Location } from './LocationPicker' +import { FaExternalLinkAlt, FaMapMarkerAlt } from 'react-icons/fa' +import { Location } from '@/types/intranet' interface LocationMapProps { location: Location @@ -52,7 +52,7 @@ const LocationMap: React.FC = ({ {/* Location Info */}
- +

{location.name}

@@ -82,7 +82,7 @@ const LocationMap: React.FC = ({ onClick={handleOpenGoogleMaps} className="w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors" > - + Google Maps'te Aç

diff --git a/ui/src/views/intranet/SocialWall/LocationPicker.tsx b/ui/src/views/intranet/SocialWall/LocationPicker.tsx index 429611da..9fc41933 100644 --- a/ui/src/views/intranet/SocialWall/LocationPicker.tsx +++ b/ui/src/views/intranet/SocialWall/LocationPicker.tsx @@ -1,16 +1,8 @@ import React, { useState, useEffect, useRef } from 'react' import { motion } from 'framer-motion' -import { HiX, HiOutlineSearch, HiOutlineLocationMarker } from 'react-icons/hi' +import { FaTimes, FaSearch, FaMapMarkerAlt } from 'react-icons/fa' import classNames from 'classnames' - -export interface Location { - id: string - name: string - address: string - lat: number - lng: number - placeId?: string -} +import { Location } from '@/types/intranet' interface LocationPickerProps { onSelect: (location: Location) => void @@ -227,14 +219,14 @@ const LocationPicker: React.FC = ({ onSelect, onClose }) => onClick={onClose} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full transition-colors" > - +

{/* Search */}
- + = ({ onSelect, onClose }) =>
) : error ? (
- +

{error}

) : searchQuery.trim() === '' ? (
- +

Aramak istediğiniz konumu yazın

@@ -281,7 +273,7 @@ const LocationPicker: React.FC = ({ onSelect, onClose }) =>
) : locations.length === 0 ? (
- +

Konum bulunamadı. Farklı bir arama yapın.

@@ -301,7 +293,7 @@ const LocationPicker: React.FC = ({ onSelect, onClose }) => >
- = ({ onSelect, onClose }) =>
{selectedLocation ? ( - + {selectedLocation.name} diff --git a/ui/src/views/intranet/SocialWall/MediaLightbox.tsx b/ui/src/views/intranet/SocialWall/MediaLightbox.tsx index 58097839..4b9f9418 100644 --- a/ui/src/views/intranet/SocialWall/MediaLightbox.tsx +++ b/ui/src/views/intranet/SocialWall/MediaLightbox.tsx @@ -5,12 +5,7 @@ import Video from 'yet-another-react-lightbox/plugins/video' import Zoom from 'yet-another-react-lightbox/plugins/zoom' import Counter from 'yet-another-react-lightbox/plugins/counter' import 'yet-another-react-lightbox/plugins/counter.css' - -export interface LightboxMedia { - type: 'image' | 'video' - url?: string - urls?: string[] -} +import { LightboxMedia } from '@/types/intranet' interface MediaLightboxProps { isOpen: boolean diff --git a/ui/src/views/intranet/SocialWall/MediaManager.tsx b/ui/src/views/intranet/SocialWall/MediaManager.tsx index 7207b024..b8baff89 100644 --- a/ui/src/views/intranet/SocialWall/MediaManager.tsx +++ b/ui/src/views/intranet/SocialWall/MediaManager.tsx @@ -1,14 +1,8 @@ import React, { useState } from 'react' -import { motion, AnimatePresence } from 'framer-motion' -import { HiX, HiPlus, HiOutlineLink, HiOutlineUpload } from 'react-icons/hi' +import { motion } from 'framer-motion' +import { FaTimes, FaLink, FaUpload } from 'react-icons/fa' import classNames from 'classnames' - -export interface MediaItem { - id: string - type: 'image' | 'video' - url: string - file?: File -} +import { MediaItem } from '@/types/intranet' interface MediaManagerProps { media: MediaItem[] @@ -68,7 +62,7 @@ const MediaManager: React.FC = ({ media, onChange, onClose }) onClick={onClose} className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full transition-colors" > - +
@@ -84,7 +78,7 @@ const MediaManager: React.FC = ({ media, onChange, onClose }) )} >
- + Bilgisayarımdan Seç
@@ -98,7 +92,7 @@ const MediaManager: React.FC = ({ media, onChange, onClose }) )} >
- + URL ile Ekle
@@ -110,7 +104,7 @@ const MediaManager: React.FC = ({ media, onChange, onClose })
@@ -336,9 +336,9 @@ const PostItem: React.FC = ({ post, onLike, onComment, onDelete, )} > {post.likes.isLiked ? ( - + ) : ( - + )} {post.likes.count} @@ -347,7 +347,7 @@ const PostItem: React.FC = ({ post, onLike, onComment, onDelete, onClick={() => setShowComments(!showComments)} className="flex items-center gap-2 text-gray-600 dark:text-gray-400 hover:text-blue-600 transition-colors" > - + {post.comments.length}
@@ -376,7 +376,7 @@ const PostItem: React.FC = ({ post, onLike, onComment, onDelete, disabled={!commentText.trim()} className="p-2 bg-blue-600 text-white rounded-full hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors" > - +
@@ -417,7 +417,7 @@ const PostItem: React.FC = ({ post, onLike, onComment, onDelete,

{comment.content}

- {dayjs(comment.createdAt).fromNow()} + {dayjs(comment.creationTime).fromNow()}

diff --git a/ui/src/views/intranet/SocialWall/UserProfileCard.tsx b/ui/src/views/intranet/SocialWall/UserProfileCard.tsx index a3a619da..4acbc31d 100644 --- a/ui/src/views/intranet/SocialWall/UserProfileCard.tsx +++ b/ui/src/views/intranet/SocialWall/UserProfileCard.tsx @@ -1,6 +1,6 @@ import React from 'react' import { motion } from 'framer-motion' -import { HiMail, HiPhone, HiBriefcase, HiLocationMarker } from 'react-icons/hi' +import { FaEnvelope, FaPhone, FaBriefcase, FaMapMarkerAlt } from 'react-icons/fa' interface UserProfileCardProps { user: { @@ -39,7 +39,7 @@ const UserProfileCard: React.FC = ({ user, position = 'bot {user.name}

- + {user.title}

@@ -49,7 +49,7 @@ const UserProfileCard: React.FC = ({ user, position = 'bot
{user.email && (
- + = ({ user, position = 'bot {user.phone && (
- + = ({ user, position = 'bot {user.department && (
- + {user.department}
)} {user.location && (
- + {user.location}
)} diff --git a/ui/src/views/intranet/SocialWall/index.tsx b/ui/src/views/intranet/SocialWall/index.tsx index a27999c7..68999f1b 100644 --- a/ui/src/views/intranet/SocialWall/index.tsx +++ b/ui/src/views/intranet/SocialWall/index.tsx @@ -1,10 +1,10 @@ import React, { useState } from 'react' import { AnimatePresence } from 'framer-motion' -import { mockSocialPosts, SocialPost } from '../../../mocks/mockSocialPosts' import PostItem from './PostItem' import { MediaItem } from './MediaManager' import CreatePost from './CreatePost' -import { Location } from './LocationPicker' +import { Location, SocialPost } from '@/types/intranet' +import { mockSocialPosts } from '@/mocks/mockIntranetData' const SocialWall: React.FC = () => { const [posts, setPosts] = useState(mockSocialPosts) @@ -73,7 +73,7 @@ const SocialWall: React.FC = () => { title: 'Çalışan' }, content: postData.content, - createdAt: new Date(), + creationTime: new Date(), media: mediaForPost, location: postData.location, likes: { @@ -118,7 +118,7 @@ const SocialWall: React.FC = () => { avatar: 'https://i.pravatar.cc/150?img=1' }, content, - createdAt: new Date() + creationTime: new Date() } return { ...post,