LocalStorage kaldırıldı ama henüz End pointler ile doğru çalışmıyor
This commit is contained in:
parent
87d155a04b
commit
5e4726c9be
2 changed files with 275 additions and 168 deletions
|
|
@ -37,6 +37,7 @@ export const FormActivityPanel: React.FC<ActivityPanelProps> = ({
|
|||
|
||||
const {
|
||||
activities,
|
||||
loading,
|
||||
deleteActivity,
|
||||
deleteFile,
|
||||
addNote,
|
||||
|
|
@ -279,31 +280,40 @@ export const FormActivityPanel: React.FC<ActivityPanelProps> = ({
|
|||
|
||||
{/* Content */}
|
||||
<div className="flex-1 overflow-y-auto p-4">
|
||||
{activeTab === 'activities' && (
|
||||
<ActivityList
|
||||
activities={activities}
|
||||
onDeleteActivity={deleteActivity}
|
||||
onDeleteFile={deleteFile}
|
||||
onDownloadFile={handleDownloadFile}
|
||||
/>
|
||||
)}
|
||||
{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' && (
|
||||
<ActivityList
|
||||
activities={activities}
|
||||
onDeleteActivity={deleteActivity}
|
||||
onDeleteFile={deleteFile}
|
||||
onDownloadFile={handleDownloadFile}
|
||||
/>
|
||||
)}
|
||||
|
||||
{activeTab === 'notes' && (
|
||||
<ActivityList
|
||||
activities={activities.filter((a) => a.type === 'note')}
|
||||
onDeleteActivity={deleteActivity}
|
||||
onDeleteFile={deleteFile}
|
||||
onDownloadFile={handleDownloadFile}
|
||||
/>
|
||||
)}
|
||||
{activeTab === 'notes' && (
|
||||
<ActivityList
|
||||
activities={activities.filter((a) => a.type === 'note')}
|
||||
onDeleteActivity={deleteActivity}
|
||||
onDeleteFile={deleteFile}
|
||||
onDownloadFile={handleDownloadFile}
|
||||
/>
|
||||
)}
|
||||
|
||||
{activeTab === 'messages' && (
|
||||
<ActivityList
|
||||
activities={activities.filter((a) => a.type === 'message')}
|
||||
onDeleteActivity={deleteActivity}
|
||||
onDeleteFile={deleteFile}
|
||||
onDownloadFile={handleDownloadFile}
|
||||
/>
|
||||
{activeTab === 'messages' && (
|
||||
<ActivityList
|
||||
activities={activities.filter((a) => a.type === 'message')}
|
||||
onDeleteActivity={deleteActivity}
|
||||
onDeleteFile={deleteFile}
|
||||
onDownloadFile={handleDownloadFile}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,40 +1,81 @@
|
|||
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 { useState, useEffect } from 'react'
|
||||
|
||||
const STORAGE_PREFIX = 'form_activity_'
|
||||
|
||||
export const useFormActivity = (entityName: string, entityId: string) => {
|
||||
const [activityItems, setActivityItems] = useState<ActivityItem[]>([])
|
||||
const [files, setFiles] = useState<ActivityFile[]>([])
|
||||
const [activities, setActivities] = useState<Activity[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const { user } = useStoreState((state) => state.auth)
|
||||
|
||||
const storageKey = `${STORAGE_PREFIX}${entityName}_${entityId}`
|
||||
|
||||
// Load data from localStorage on component mount
|
||||
// Load data from API on component mount
|
||||
useEffect(() => {
|
||||
if (!entityName || !entityId) return
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
loadActivitiesFromAPI()
|
||||
}, [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
|
||||
useEffect(() => {
|
||||
const allActivities: Activity[] = []
|
||||
|
|
@ -60,161 +101,217 @@ export const useFormActivity = (entityName: string, entityId: string) => {
|
|||
setActivities(allActivities)
|
||||
}, [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 timestamp = new Date()
|
||||
const baseId = `content_${timestamp.getTime()}_${Math.random().toString(36).substr(2, 9)}`
|
||||
try {
|
||||
setLoading(true)
|
||||
|
||||
// Hem not hem de dosya varsa veya sadece biri varsa tek bir note aktivitesi oluştur
|
||||
const newActivityItem: ActivityItem = {
|
||||
id: baseId,
|
||||
type: 'note',
|
||||
entityName,
|
||||
entityId,
|
||||
subject,
|
||||
content: content || (files.length > 0 ? `${files.length} dosya eklendi` : ''),
|
||||
creatorId: user.id,
|
||||
creationTime: timestamp,
|
||||
attachedFiles: [], // Dosyaları buraya ekleyeceğiz
|
||||
}
|
||||
// Önce Activity oluştur
|
||||
const activityDto: Partial<ActivityDto> = {
|
||||
type: 'note',
|
||||
subject: subject || 'Not',
|
||||
content: content || (files.length > 0 ? `${files.length} dosya eklendi` : ''),
|
||||
}
|
||||
|
||||
const createdActivity = await activityService.create(activityDto as ActivityDto)
|
||||
|
||||
// Dosyaları yükle ve note'a attach et
|
||||
const uploadedFiles: ActivityFile[] = []
|
||||
for (const file of files) {
|
||||
try {
|
||||
const uploadedFile = await new Promise<ActivityFile>((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = () => {
|
||||
const newFile: ActivityFile = {
|
||||
id: `${baseId}_file_${Math.random().toString(36).substr(2, 9)}`,
|
||||
entityName,
|
||||
entityId,
|
||||
fileName: file.name,
|
||||
fileSize: file.size,
|
||||
fileType: file.type,
|
||||
filePath: `uploads/${entityName}/${entityId}/${file.name}`,
|
||||
creatorId: user.id,
|
||||
creationTime: timestamp,
|
||||
}
|
||||
resolve(newFile)
|
||||
// ActivityItem oluştur
|
||||
const activityItemDto: Partial<ActivityItemDto> = {
|
||||
activityId: createdActivity.id,
|
||||
type: 'note',
|
||||
entityName,
|
||||
entityId,
|
||||
subject: subject || 'Not',
|
||||
content: content || (files.length > 0 ? `${files.length} dosya eklendi` : ''),
|
||||
}
|
||||
|
||||
const createdActivityItem = await activityService.createItem(activityItemDto as ActivityItemDto)
|
||||
|
||||
// Dosyaları yükle
|
||||
const uploadedFiles: ActivityFile[] = []
|
||||
for (const file of files) {
|
||||
try {
|
||||
const activityFileDto: Partial<ActivityFileDto> = {
|
||||
activityItemId: createdActivityItem.id,
|
||||
entityName,
|
||||
entityId,
|
||||
fileName: file.name,
|
||||
fileSize: file.size,
|
||||
fileType: file.type,
|
||||
filePath: `uploads/${entityName}/${entityId}/${file.name}`,
|
||||
}
|
||||
reader.onerror = () => reject(reader.error)
|
||||
reader.readAsDataURL(file)
|
||||
})
|
||||
uploadedFiles.push(uploadedFile)
|
||||
} catch (error) {
|
||||
console.error('File upload failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// Note'a dosyaları ekle
|
||||
newActivityItem.attachedFiles = uploadedFiles
|
||||
|
||||
// Activity Item'ı kaydet
|
||||
setActivityItems((prev) => [...prev, newActivityItem])
|
||||
|
||||
// Dosyaları ayrı ayrı da kaydet (eski sistem uyumluluğu için)
|
||||
if (uploadedFiles.length > 0) {
|
||||
setFiles((prev) => [...prev, ...uploadedFiles])
|
||||
}
|
||||
|
||||
return newActivityItem
|
||||
}
|
||||
|
||||
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(),
|
||||
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(),
|
||||
}
|
||||
|
||||
uploadedFiles.push(newFile)
|
||||
} catch (error) {
|
||||
console.error('File upload failed:', error)
|
||||
}
|
||||
setFiles((prev) => [...prev, newFile])
|
||||
resolve(newFile)
|
||||
}
|
||||
reader.onerror = () => reject(reader.error)
|
||||
reader.readAsDataURL(file)
|
||||
})
|
||||
|
||||
// Yeni ActivityItem'ı local state'e ekle
|
||||
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
|
||||
}
|
||||
|
||||
setActivityItems((prev) => [...prev, newActivityItem])
|
||||
if (uploadedFiles.length > 0) {
|
||||
setFiles((prev) => [...prev, ...uploadedFiles])
|
||||
}
|
||||
|
||||
return newActivityItem
|
||||
} catch (error) {
|
||||
console.error('Failed to create note:', error)
|
||||
throw error
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const deleteActivity = (itemId: string) => {
|
||||
setActivityItems((prev) => prev.filter((item) => item.id !== itemId))
|
||||
|
||||
|
||||
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))
|
||||
|
||||
// İ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) => {
|
||||
setFiles((prev) => prev.filter((file) => file.id !== fileId))
|
||||
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))
|
||||
|
||||
// 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 }>,
|
||||
subject: string,
|
||||
content: string,
|
||||
) => {
|
||||
// Her recipient için ayrı mesaj aktivitesi oluştur
|
||||
const newMessageItems: ActivityItem[] = recipients.map((recipient) => ({
|
||||
id: `message_${Date.now()}_${Math.random().toString(36).substr(2, 9)}_${recipient.value}`,
|
||||
type: 'message' as const,
|
||||
entityName,
|
||||
entityId,
|
||||
recipientUserId: recipient.value,
|
||||
recipientUserName: recipient.label,
|
||||
subject,
|
||||
content,
|
||||
creatorId: user.id,
|
||||
creationTime: new Date(),
|
||||
}))
|
||||
|
||||
// Tüm mesajları activityItems'a ekle
|
||||
setActivityItems((prev) => [...prev, ...newMessageItems])
|
||||
return newMessageItems
|
||||
try {
|
||||
setLoading(true)
|
||||
const newMessageItems: ActivityItem[] = []
|
||||
|
||||
// Her recipient için ayrı mesaj aktivitesi oluştur
|
||||
for (const recipient of recipients) {
|
||||
try {
|
||||
// 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,
|
||||
entityId,
|
||||
recipientUserId: recipient.value,
|
||||
recipientUserName: recipient.label,
|
||||
subject,
|
||||
content,
|
||||
}
|
||||
|
||||
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
|
||||
setActivityItems((prev) => [...prev, ...newMessageItems])
|
||||
return newMessageItems
|
||||
} catch (error) {
|
||||
console.error('Failed to send messages:', error)
|
||||
throw error
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
activityItems,
|
||||
files,
|
||||
activities,
|
||||
loading,
|
||||
// Ana aktivite fonksiyonları
|
||||
addActivity,
|
||||
deleteActivity,
|
||||
addNote,
|
||||
sendMessage,
|
||||
// Dosya işlemleri
|
||||
addFile,
|
||||
deleteFile,
|
||||
// Veri yenileme
|
||||
refreshActivities: loadActivitiesFromAPI,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue