erp-platform/ui/src/views/intranet/SocialWall/index.tsx
Sedat Öztürk 988a8d0bfb mockIntranet kaldırıldı
Intranet Dashboard düzeltildi.
2025-10-29 22:24:40 +03:00

208 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react'
import { AnimatePresence } from 'framer-motion'
import PostItem from './PostItem'
import CreatePost from './CreatePost'
// import { mockSocialPosts } from '@/mocks/mockIntranet'
import { mockEmployees } from '@/mocks/mockEmployees'
import { EmployeeDto, SocialMediaDto, SocialPostDto } from '@/proxy/intranet/models'
const SocialWall: React.FC<{ posts: SocialPostDto[] }> = ({ posts }) => {
// const [posts, setPosts] = useState<SocialPost[]>(mockSocialPosts)
const [filter, setFilter] = useState<'all' | 'mine'>('all')
// Ali Öztürk'ü "Siz" kullanıcısı olarak kullan
const currentUserAuthor: EmployeeDto = { ...mockEmployees[0], fullName: 'Siz' }
const handleCreatePost = (postData: {
content: string
location?: string
media?: {
type: 'mixed' | 'poll'
mediaItems?: SocialMediaDto[]
poll?: {
question: string
options: Array<{ text: string }>
}
}
}) => {
let mediaForPost = undefined
if (postData.media) {
if (postData.media.type === 'mixed' && postData.media.mediaItems) {
// Convert MediaItems to post format
const images = postData.media.mediaItems.filter((m) => m.type === 'image')
const videos = postData.media.mediaItems.filter((m) => m.type === 'video')
if (images.length > 0 && videos.length === 0) {
mediaForPost = {
type: 'image' as const,
urls: images.map((i) => i.urls?.[0]).filter((url) => url !== undefined) as string[],
}
} else if (videos.length > 0 && images.length === 0) {
mediaForPost = {
type: 'video' as const,
urls: videos[0].urls || [],
}
} else if (images.length > 0 || videos.length > 0) {
// Mixed media - use first image for now
mediaForPost = {
type: 'image' as const,
urls: images.map((i) => i.urls?.[0]).filter((url) => url !== undefined) as string[],
}
}
} else if (postData.media.type === 'poll' && postData.media.poll) {
mediaForPost = {
type: 'poll' as const,
pollQuestion: postData.media.poll.question,
pollOptions: postData.media.poll.options.map((opt, index) => ({
id: `opt-${index}`,
text: opt.text,
votes: 0,
})),
pollTotalVotes: 0,
pollEndsAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
}
}
}
const newPost: SocialPostDto = {
id: Date.now().toString(),
employee: currentUserAuthor,
content: postData.content,
creationTime: new Date(),
media: mediaForPost,
locationJson: postData.location,
likeCount: 0,
isLiked: false,
likeUsers: [],
comments: [],
isOwnPost: true,
}
// setPosts([newPost, ...posts])
}
const handleLike = (postId: string) => {
// setPosts(
// posts.map((post) => {
// if (post.id === postId) {
// return {
// ...post,
// likeCount: post.isLiked ? post.likeCount - 1 : post.likeCount + 1,
// isLiked: !post.isLiked
// }
// }
// return post
// })
// )
}
const handleComment = (postId: string, content: string) => {
// setPosts(
// posts.map((post) => {
// if (post.id === postId) {
// const commentAuthor = currentUserAuthor
// const newComment = {
// id: Date.now().toString(),
// creator: commentAuthor,
// content,
// creationTime: new Date()
// }
// return {
// ...post,
// comments: [...post.comments, newComment]
// }
// }
// return post
// })
// )
}
const handleDelete = (postId: string) => {
if (window.confirm('Bu gönderiyi silmek istediğinizden emin misiniz?')) {
// setPosts(posts.filter((post) => post.id !== postId))
}
}
const handleVote = (postId: string, optionId: string) => {
// setPosts(
// posts.map((post) => {
// if (post.id === postId && post.media?.type === 'poll' && post.media.pollOptions) {
// // If user already voted, don't allow voting again
// if (post.media.pollUserVoteId) {
// return post
// }
// return {
// ...post,
// media: {
// ...post.media,
// pollOptions: post.media.pollOptions.map((opt) =>
// opt.id === optionId ? { ...opt, votes: opt.votes + 1 } : opt
// ),
// pollTotalVotes: (post.media.pollTotalVotes || 0) + 1,
// pollUserVoteId: optionId
// }
// }
// }
// return post
// })
// )
}
const filteredPosts = filter === 'mine' ? posts.filter((post) => post.isOwnPost) : posts
return (
<div className="mx-auto px-4">
{/* Filter Tabs */}
<div className="flex gap-4 mb-6 border-b border-gray-200 dark:border-gray-700">
<button
onClick={() => setFilter('all')}
className={`pb-3 px-1 border-b-2 transition-colors font-medium ${
filter === 'all'
? 'border-blue-600 text-blue-600'
: 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200'
}`}
>
Tüm Gönderiler
</button>
<button
onClick={() => setFilter('mine')}
className={`pb-3 px-1 border-b-2 transition-colors font-medium ${
filter === 'mine'
? 'border-blue-600 text-blue-600'
: 'border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200'
}`}
>
Gönderilerim
</button>
</div>
{/* Create Post */}
<CreatePost onCreatePost={handleCreatePost} />
{/* Posts Feed */}
<AnimatePresence>
{filteredPosts.length > 0 ? (
filteredPosts.map((post) => (
<PostItem
key={post.id}
post={post}
onLike={handleLike}
onComment={handleComment}
onDelete={handleDelete}
onVote={handleVote}
/>
))
) : (
<div className="text-center py-12">
<p className="text-gray-500 dark:text-gray-400 text-lg">
{filter === 'mine' ? 'Henüz bir gönderi paylaşmadınız.' : 'Henüz gönderi yok.'}
</p>
</div>
)}
</AnimatePresence>
</div>
)
}
export default SocialWall