LocalStorage kaldırıldı ama henüz End pointler ile doğru çalışmıyor

This commit is contained in:
Sedat ÖZTÜRK 2025-10-13 17:58:08 +03:00
parent 87d155a04b
commit 5e4726c9be
2 changed files with 275 additions and 168 deletions

View file

@ -37,6 +37,7 @@ export const FormActivityPanel: React.FC<ActivityPanelProps> = ({
const { const {
activities, activities,
loading,
deleteActivity, deleteActivity,
deleteFile, deleteFile,
addNote, addNote,
@ -279,6 +280,13 @@ export const FormActivityPanel: React.FC<ActivityPanelProps> = ({
{/* Content */} {/* Content */}
<div className="flex-1 overflow-y-auto p-4"> <div className="flex-1 overflow-y-auto p-4">
{loading ? (
<div className="flex items-center justify-center h-32">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<span className="ml-2 text-gray-600">Yükleniyor...</span>
</div>
) : (
<>
{activeTab === 'activities' && ( {activeTab === 'activities' && (
<ActivityList <ActivityList
activities={activities} activities={activities}
@ -305,6 +313,8 @@ export const FormActivityPanel: React.FC<ActivityPanelProps> = ({
onDownloadFile={handleDownloadFile} onDownloadFile={handleDownloadFile}
/> />
)} )}
</>
)}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,40 +1,81 @@
import { ActivityItem, ActivityFile, Activity } from '@/proxy/formActivity/models' import { ActivityItem, ActivityFile, Activity } from '@/proxy/formActivity/models'
import { ActivityDto, ActivityItemDto, ActivityFileDto } from '@/proxy/activity/models'
import { activityService } from '@/services/activity.service'
import { useStoreState } from '@/store/store' import { useStoreState } from '@/store/store'
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
const STORAGE_PREFIX = 'form_activity_'
export const useFormActivity = (entityName: string, entityId: string) => { export const useFormActivity = (entityName: string, entityId: string) => {
const [activityItems, setActivityItems] = useState<ActivityItem[]>([]) const [activityItems, setActivityItems] = useState<ActivityItem[]>([])
const [files, setFiles] = useState<ActivityFile[]>([]) const [files, setFiles] = useState<ActivityFile[]>([])
const [activities, setActivities] = useState<Activity[]>([]) const [activities, setActivities] = useState<Activity[]>([])
const [loading, setLoading] = useState(false)
const { user } = useStoreState((state) => state.auth) const { user } = useStoreState((state) => state.auth)
const storageKey = `${STORAGE_PREFIX}${entityName}_${entityId}` // Load data from API on component mount
// Load data from localStorage on component mount
useEffect(() => { useEffect(() => {
if (!entityName || !entityId) return if (!entityName || !entityId) return
loadActivitiesFromAPI()
const savedData = localStorage.getItem(storageKey)
if (savedData) {
try {
const parsed = JSON.parse(savedData)
// Eski veriyi yeni yapıya dönüştür
const oldNotes = parsed.notes || []
const oldMessages = parsed.messages || []
const combinedActivityItems: ActivityItem[] = [
...oldNotes.map((note: any) => ({ ...note, type: 'note' as const })),
...oldMessages.map((message: any) => ({ ...message, type: 'message' as const })),
]
setActivityItems(parsed.activityItems || combinedActivityItems || [])
setFiles(parsed.files || [])
} catch (error) {
console.error('Failed to load activity data:', error)
}
}
}, [entityName, entityId]) }, [entityName, entityId])
const loadActivitiesFromAPI = async () => {
try {
setLoading(true)
// Tüm ActivityItem'ları al
const items = await activityService.getItems()
// EntityName ve EntityId ile filtrele
const filteredItems = items.filter(
item => item.entityName === entityName && item.entityId === entityId
)
// DTO'dan ActivityItem'a dönüştür
const convertedItems: ActivityItem[] = filteredItems.map(dto => ({
id: dto.id,
type: (dto.type as 'note' | 'message') || 'note',
entityName: dto.entityName || entityName,
entityId: dto.entityId || entityId,
recipientUserId: dto.recipientUserId,
recipientUserName: dto.recipientUserName,
subject: dto.subject || '',
content: dto.content || '',
creatorId: dto.creatorId || user.id,
creationTime: dto.creationTime ? new Date(dto.creationTime) : new Date(),
attachedFiles: []
}))
// Her ActivityItem için dosyaları yükle
for (const item of convertedItems) {
if (item.id) {
try {
const itemFiles = await activityService.getFiles(item.id)
const convertedFiles: ActivityFile[] = itemFiles.map(fileDto => ({
id: fileDto.id,
entityName: fileDto.entityName || entityName,
entityId: fileDto.entityId || entityId,
fileName: fileDto.fileName || '',
fileSize: fileDto.fileSize || 0,
fileType: fileDto.fileType || '',
filePath: fileDto.filePath || '',
creatorId: fileDto.creatorId || user.id,
creationTime: fileDto.creationTime ? new Date(fileDto.creationTime) : new Date(),
}))
item.attachedFiles = convertedFiles
setFiles(prev => [...prev, ...convertedFiles])
} catch (error) {
console.error('Failed to load files for activity item:', item.id, error)
}
}
}
setActivityItems(convertedItems)
} catch (error) {
console.error('Failed to load activities from API:', error)
} finally {
setLoading(false)
}
}
// Update activities when data changes // Update activities when data changes
useEffect(() => { useEffect(() => {
const allActivities: Activity[] = [] const allActivities: Activity[] = []
@ -60,161 +101,217 @@ export const useFormActivity = (entityName: string, entityId: string) => {
setActivities(allActivities) setActivities(allActivities)
}, [activityItems, files]) }, [activityItems, files])
// Save to localStorage whenever data changes
useEffect(() => {
if (!entityName || !entityId) return
const dataToSave = {
activityItems,
files,
}
localStorage.setItem(storageKey, JSON.stringify(dataToSave))
}, [activityItems, files, storageKey])
const addActivity = (subject: string, content: string, type: 'note' | 'message' = 'note') => {
const newActivityItem: ActivityItem = {
id: `${type}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
type,
entityName,
entityId,
subject,
content,
creatorId: user.id,
creationTime: new Date(),
}
setActivityItems((prev) => [...prev, newActivityItem])
return newActivityItem
}
const addNote = async (subject: string, content: string, files: File[]) => { const addNote = async (subject: string, content: string, files: File[]) => {
const timestamp = new Date() try {
const baseId = `content_${timestamp.getTime()}_${Math.random().toString(36).substr(2, 9)}` setLoading(true)
// Hem not hem de dosya varsa veya sadece biri varsa tek bir note aktivitesi oluştur // Önce Activity oluştur
const newActivityItem: ActivityItem = { const activityDto: Partial<ActivityDto> = {
id: baseId, type: 'note',
subject: subject || 'Not',
content: content || (files.length > 0 ? `${files.length} dosya eklendi` : ''),
}
const createdActivity = await activityService.create(activityDto as ActivityDto)
// ActivityItem oluştur
const activityItemDto: Partial<ActivityItemDto> = {
activityId: createdActivity.id,
type: 'note', type: 'note',
entityName, entityName,
entityId, entityId,
subject, subject: subject || 'Not',
content: content || (files.length > 0 ? `${files.length} dosya eklendi` : ''), content: content || (files.length > 0 ? `${files.length} dosya eklendi` : ''),
creatorId: user.id,
creationTime: timestamp,
attachedFiles: [], // Dosyaları buraya ekleyeceğiz
} }
// Dosyaları yükle ve note'a attach et const createdActivityItem = await activityService.createItem(activityItemDto as ActivityItemDto)
// Dosyaları yükle
const uploadedFiles: ActivityFile[] = [] const uploadedFiles: ActivityFile[] = []
for (const file of files) { for (const file of files) {
try { try {
const uploadedFile = await new Promise<ActivityFile>((resolve, reject) => { const activityFileDto: Partial<ActivityFileDto> = {
const reader = new FileReader() activityItemId: createdActivityItem.id,
reader.onload = () => {
const newFile: ActivityFile = {
id: `${baseId}_file_${Math.random().toString(36).substr(2, 9)}`,
entityName, entityName,
entityId, entityId,
fileName: file.name, fileName: file.name,
fileSize: file.size, fileSize: file.size,
fileType: file.type, fileType: file.type,
filePath: `uploads/${entityName}/${entityId}/${file.name}`, filePath: `uploads/${entityName}/${entityId}/${file.name}`,
creatorId: user.id,
creationTime: timestamp,
} }
resolve(newFile)
const createdFile = await activityService.uploadFile(activityFileDto as ActivityFileDto)
const newFile: ActivityFile = {
id: createdFile.id,
entityName: createdFile.entityName || entityName,
entityId: createdFile.entityId || entityId,
fileName: createdFile.fileName || file.name,
fileSize: createdFile.fileSize || file.size,
fileType: createdFile.fileType || file.type,
filePath: createdFile.filePath || '',
creatorId: createdFile.creatorId || user.id,
creationTime: createdFile.creationTime ? new Date(createdFile.creationTime) : new Date(),
} }
reader.onerror = () => reject(reader.error)
reader.readAsDataURL(file) uploadedFiles.push(newFile)
})
uploadedFiles.push(uploadedFile)
} catch (error) { } catch (error) {
console.error('File upload failed:', error) console.error('File upload failed:', error)
} }
} }
// Note'a dosyaları ekle // Yeni ActivityItem'ı local state'e ekle
newActivityItem.attachedFiles = uploadedFiles const newActivityItem: ActivityItem = {
id: createdActivityItem.id,
type: 'note',
entityName,
entityId,
subject: createdActivityItem.subject || '',
content: createdActivityItem.content || '',
creatorId: createdActivityItem.creatorId || user.id,
creationTime: createdActivityItem.creationTime ? new Date(createdActivityItem.creationTime) : new Date(),
attachedFiles: uploadedFiles
}
// Activity Item'ı kaydet
setActivityItems((prev) => [...prev, newActivityItem]) setActivityItems((prev) => [...prev, newActivityItem])
// Dosyaları ayrı ayrı da kaydet (eski sistem uyumluluğu için)
if (uploadedFiles.length > 0) { if (uploadedFiles.length > 0) {
setFiles((prev) => [...prev, ...uploadedFiles]) setFiles((prev) => [...prev, ...uploadedFiles])
} }
return newActivityItem return newActivityItem
} catch (error) {
console.error('Failed to create note:', error)
throw error
} finally {
setLoading(false)
} }
const addFile = (file: File) => {
return new Promise<ActivityFile>((resolve, reject) => {
// Simulate file upload - gerçek implementasyonda API call yapılacak
const reader = new FileReader()
reader.onload = () => {
const newFile: ActivityFile = {
id: `file_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
entityName,
entityId,
fileName: file.name,
fileSize: file.size,
fileType: file.type,
filePath: `uploads/${entityName}/${entityId}/${file.name}`, // Simulated path
creatorId: user.id,
creationTime: new Date(),
}
setFiles((prev) => [...prev, newFile])
resolve(newFile)
}
reader.onerror = () => reject(reader.error)
reader.readAsDataURL(file)
})
} }
const deleteActivity = (itemId: string) => {
const deleteActivity = async (itemId: string) => {
try {
// API'dan ActivityItem'ı sil
await activityService.deleteItem(itemId)
// Local state'ten kaldır
setActivityItems((prev) => prev.filter((item) => item.id !== itemId)) setActivityItems((prev) => prev.filter((item) => item.id !== itemId))
// İlgili dosyaları da kaldır
setFiles((prev) => prev.filter((file) =>
!(file as any).activityItemId || (file as any).activityItemId !== itemId
))
} catch (error) {
console.error('Failed to delete activity:', error)
throw error
}
} }
const deleteFile = (fileId: string) => { const deleteFile = async (fileId: string) => {
try {
// API'dan ActivityFile'ı sil
await activityService.deleteFile(fileId)
// Local state'ten kaldır
setFiles((prev) => prev.filter((file) => file.id !== fileId)) setFiles((prev) => prev.filter((file) => file.id !== fileId))
// ActivityItem'dan da kaldır
setActivityItems((prev) =>
prev.map(item => ({
...item,
attachedFiles: item.attachedFiles?.filter(file => file.id !== fileId) || []
}))
)
} catch (error) {
console.error('Failed to delete file:', error)
throw error
}
} }
const sendMessage = ( const sendMessage = async (
recipients: Array<{ value: string; label: string; email?: string }>, recipients: Array<{ value: string; label: string; email?: string }>,
subject: string, subject: string,
content: string, content: string,
) => { ) => {
try {
setLoading(true)
const newMessageItems: ActivityItem[] = []
// Her recipient için ayrı mesaj aktivitesi oluştur // Her recipient için ayrı mesaj aktivitesi oluştur
const newMessageItems: ActivityItem[] = recipients.map((recipient) => ({ for (const recipient of recipients) {
id: `message_${Date.now()}_${Math.random().toString(36).substr(2, 9)}_${recipient.value}`, try {
type: 'message' as const, // Activity oluştur
const activityDto: Partial<ActivityDto> = {
type: 'message',
subject,
content,
recipientUserName: recipient.label,
}
const createdActivity = await activityService.create(activityDto as ActivityDto)
// ActivityItem oluştur
const activityItemDto: Partial<ActivityItemDto> = {
activityId: createdActivity.id,
type: 'message',
entityName, entityName,
entityId, entityId,
recipientUserId: recipient.value, recipientUserId: recipient.value,
recipientUserName: recipient.label, recipientUserName: recipient.label,
subject, subject,
content, content,
creatorId: user.id, }
creationTime: new Date(),
})) const createdActivityItem = await activityService.createItem(activityItemDto as ActivityItemDto)
const newMessageItem: ActivityItem = {
id: createdActivityItem.id,
type: 'message',
entityName,
entityId,
recipientUserId: createdActivityItem.recipientUserId,
recipientUserName: createdActivityItem.recipientUserName,
subject: createdActivityItem.subject || '',
content: createdActivityItem.content || '',
creatorId: createdActivityItem.creatorId || user.id,
creationTime: createdActivityItem.creationTime ? new Date(createdActivityItem.creationTime) : new Date(),
}
newMessageItems.push(newMessageItem)
} catch (error) {
console.error('Failed to send message to recipient:', recipient.label, error)
}
}
// Tüm mesajları activityItems'a ekle // Tüm mesajları activityItems'a ekle
setActivityItems((prev) => [...prev, ...newMessageItems]) setActivityItems((prev) => [...prev, ...newMessageItems])
return newMessageItems return newMessageItems
} catch (error) {
console.error('Failed to send messages:', error)
throw error
} finally {
setLoading(false)
}
} }
return { return {
activityItems, activityItems,
files, files,
activities, activities,
loading,
// Ana aktivite fonksiyonları // Ana aktivite fonksiyonları
addActivity,
deleteActivity, deleteActivity,
addNote, addNote,
sendMessage, sendMessage,
// Dosya işlemleri // Dosya işlemleri
addFile,
deleteFile, deleteFile,
// Veri yenileme
refreshActivities: loadActivitiesFromAPI,
} }
} }