diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-11 09:02:00 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-11 09:02:00 +0000 |
| commit | cbb4c7fe0b94459162ad5e998bc05cd293e0ff96 (patch) | |
| tree | 0a26712f7685e4f6511e637b9a81269d90a47c8f /lib/vendor-document-list/ship/send-to-shi-button.tsx | |
| parent | eb654f88214095f71be142b989e620fd28db3f69 (diff) | |
(대표님) 입찰, EDP 변경사항 대응, spreadJS 오류 수정, 벤더실사 수정
Diffstat (limited to 'lib/vendor-document-list/ship/send-to-shi-button.tsx')
| -rw-r--r-- | lib/vendor-document-list/ship/send-to-shi-button.tsx | 127 |
1 files changed, 74 insertions, 53 deletions
diff --git a/lib/vendor-document-list/ship/send-to-shi-button.tsx b/lib/vendor-document-list/ship/send-to-shi-button.tsx index 7236dfde..447b461b 100644 --- a/lib/vendor-document-list/ship/send-to-shi-button.tsx +++ b/lib/vendor-document-list/ship/send-to-shi-button.tsx @@ -26,6 +26,8 @@ import { Alert, AlertDescription } from "@/components/ui/alert" // ✅ 업데이트된 Hook import import { useClientSyncStatus, useTriggerSync, syncUtils } from "@/hooks/use-sync-status" import type { EnhancedDocument } from "@/types/enhanced-documents" +import { useParams } from "next/navigation" +import { useTranslation } from "@/i18n/client" interface SendToSHIButtonProps { documents?: EnhancedDocument[] @@ -42,6 +44,10 @@ export function SendToSHIButton({ const [syncProgress, setSyncProgress] = React.useState(0) const [currentSyncingContract, setCurrentSyncingContract] = React.useState<number | null>(null) + const params = useParams() + const lng = (params?.lng as string) || "ko" + const { t } = useTranslation(lng, "engineering") + const targetSystem = projectType === 'ship' ? "DOLCE" : "SWP" // 문서에서 유효한 계약 ID 목록 추출 (projectId 사용) @@ -80,7 +86,7 @@ export function SendToSHIButton({ // 동기화 실행 함수 const handleSync = async () => { if (documentsContractIds.length === 0) { - toast.info('동기화할 계약이 없습니다.') + toast.info(t('shiSync.messages.noContractsToSync')) return } @@ -105,7 +111,7 @@ export function SendToSHIButton({ }) if (contractsToSync.length === 0) { - toast.info('동기화할 변경사항이 없습니다.') + toast.info(t('shiSync.messages.noPendingChanges')) setIsDialogOpen(false) return } @@ -132,13 +138,13 @@ export function SendToSHIButton({ failedSyncs++ totalFailureCount += result?.failureCount || 0 const errorMsg = result?.errors?.[0] || result?.message || 'Unknown sync error' - errors.push(`Contract ${projectId}: ${errorMsg}`) + errors.push(t('shiSync.messages.contractError', { projectId, error: errorMsg })) console.error(`Contract ${projectId} sync failed:`, result) } } catch (error) { failedSyncs++ - const errorMessage = error instanceof Error ? error.message : '알 수 없는 오류' - errors.push(`Contract ${projectId}: ${errorMessage}`) + const errorMessage = error instanceof Error ? error.message : t('shiSync.messages.unknownError') + errors.push(t('shiSync.messages.contractError', { projectId, error: errorMessage })) console.error(`Contract ${projectId} sync exception:`, error) } @@ -155,23 +161,30 @@ export function SendToSHIButton({ if (failedSyncs === 0) { toast.success( - `모든 계약 동기화 완료: ${totalSuccessCount}건 성공`, + t('shiSync.messages.allSyncCompleted', { successCount: totalSuccessCount }), { - description: `${successfulSyncs}개 계약에서 ${totalSuccessCount}개 항목이 SHI 시스템으로 전송되었습니다.` + description: t('shiSync.messages.allSyncCompletedDescription', { + contractCount: successfulSyncs, + itemCount: totalSuccessCount + }) } ) } else if (successfulSyncs > 0) { toast.warning( - `부분 동기화 완료: ${successfulSyncs}개 성공, ${failedSyncs}개 실패`, + t('shiSync.messages.partialSyncCompleted', { + successfulCount: successfulSyncs, + failedCount: failedSyncs + }), { - description: errors.slice(0, 3).join(', ') + (errors.length > 3 ? ' 외 더보기...' : '') + description: errors.slice(0, 3).join(', ') + + (errors.length > 3 ? t('shiSync.messages.andMore') : '') } ) } else { toast.error( - `동기화 실패: ${failedSyncs}개 계약 모두 실패`, + t('shiSync.messages.allSyncFailed', { failedCount: failedSyncs }), { - description: errors[0] || '모든 계약 동기화에 실패했습니다.' + description: errors[0] || t('shiSync.messages.allContractsSyncFailed') } ) } @@ -186,7 +199,7 @@ export function SendToSHIButton({ setCurrentSyncingContract(null) const errorMessage = syncUtils.formatError(error as Error) - toast.error('동기화 실패', { + toast.error(t('shiSync.messages.syncFailed'), { description: errorMessage }) console.error('Sync process failed:', error) @@ -199,7 +212,7 @@ export function SendToSHIButton({ return ( <Badge variant="secondary" className="gap-1"> <Loader2 className="w-3 h-3 animate-spin" /> - 확인 중... + {t('shiSync.status.checking')} </Badge> ) } @@ -208,20 +221,20 @@ export function SendToSHIButton({ return ( <Badge variant="destructive" className="gap-1"> <AlertTriangle className="w-3 h-3" /> - 연결 오류 + {t('shiSync.status.connectionError')} </Badge> ) } if (documentsContractIds.length === 0) { - return <Badge variant="secondary">계약 없음</Badge> + return <Badge variant="secondary">{t('shiSync.status.noContracts')}</Badge> } if (totalStats.totalPending > 0) { return ( <Badge variant="destructive" className="gap-1"> <AlertTriangle className="w-3 h-3" /> - {totalStats.totalPending}건 대기 + {t('shiSync.status.pendingItems', { count: totalStats.totalPending })} </Badge> ) } @@ -230,12 +243,12 @@ export function SendToSHIButton({ return ( <Badge variant="default" className="gap-1 bg-green-500 hover:bg-green-600"> <CheckCircle className="w-3 h-3" /> - 동기화됨 + {t('shiSync.status.synchronized')} </Badge> ) } - return <Badge variant="secondary">변경사항 없음</Badge> + return <Badge variant="secondary">{t('shiSync.status.noChanges')}</Badge> } return ( @@ -254,7 +267,7 @@ export function SendToSHIButton({ ) : ( <Send className="w-4 h-4" /> )} - <span className="hidden sm:inline">Send to SHI</span> + <span className="hidden sm:inline">{t('shiSync.buttons.sendToSHI')}</span> {totalStats.totalPending > 0 && ( <Badge variant="destructive" @@ -271,7 +284,7 @@ export function SendToSHIButton({ <div className="space-y-4"> <div className="space-y-2"> <div className="flex items-center justify-between"> - <h4 className="font-medium">SHI 동기화 상태</h4> + <h4 className="font-medium">{t('shiSync.labels.syncStatus')}</h4> <Button variant="ghost" size="sm" @@ -288,12 +301,15 @@ export function SendToSHIButton({ </div> <div className="flex items-center justify-between"> - <span className="text-sm text-muted-foreground">전체 상태</span> + <span className="text-sm text-muted-foreground">{t('shiSync.labels.overallStatus')}</span> {getSyncStatusBadge()} </div> <div className="text-xs text-muted-foreground"> - {documentsContractIds.length}개 계약 대상 • {targetSystem} 시스템 + {t('shiSync.descriptions.targetInfo', { + contractCount: documentsContractIds.length, + targetSystem + })} </div> </div> @@ -302,10 +318,12 @@ export function SendToSHIButton({ <Alert variant="destructive"> <AlertTriangle className="h-4 w-4" /> <AlertDescription> - 일부 계약의 동기화 상태를 확인할 수 없습니다. 네트워크 연결을 확인해주세요. + {t('shiSync.descriptions.statusCheckError')} {process.env.NODE_ENV === 'development' && ( <div className="text-xs mt-1 font-mono"> - Debug: {contractStatuses.filter(({ error }) => error).length}개 계약에서 오류 + Debug: {t('shiSync.descriptions.contractsWithError', { + count: contractStatuses.filter(({ error }) => error).length + })} </div> )} </AlertDescription> @@ -319,46 +337,46 @@ export function SendToSHIButton({ <div className="grid grid-cols-3 gap-4 text-sm"> <div className="text-center"> - <div className="text-muted-foreground">대기 중</div> - <div className="font-medium text-orange-600">{totalStats.totalPending}건</div> + <div className="text-muted-foreground">{t('shiSync.labels.pending')}</div> + <div className="font-medium text-orange-600">{t('shiSync.labels.itemCount', { count: totalStats.totalPending })}</div> </div> <div className="text-center"> - <div className="text-muted-foreground">동기화됨</div> - <div className="font-medium text-green-600">{totalStats.totalSynced}건</div> + <div className="text-muted-foreground">{t('shiSync.labels.synced')}</div> + <div className="font-medium text-green-600">{t('shiSync.labels.itemCount', { count: totalStats.totalSynced })}</div> </div> <div className="text-center"> - <div className="text-muted-foreground">실패</div> - <div className="font-medium text-red-600">{totalStats.totalFailed}건</div> + <div className="text-muted-foreground">{t('shiSync.labels.failed')}</div> + <div className="font-medium text-red-600">{t('shiSync.labels.itemCount', { count: totalStats.totalFailed })}</div> </div> </div> {/* 계약별 상세 상태 */} {contractStatuses.length > 1 && ( <div className="space-y-2"> - <div className="text-sm font-medium">계약별 상태</div> + <div className="text-sm font-medium">{t('shiSync.labels.statusByContract')}</div> <ScrollArea className="h-32"> <div className="space-y-2"> {contractStatuses.map(({ projectId, syncStatus, isLoading, error }) => ( <div key={projectId} className="flex items-center justify-between text-xs p-2 rounded border"> - <span className="font-medium">Contract {projectId}</span> + <span className="font-medium">{t('shiSync.labels.contractLabel', { projectId })}</span> {isLoading ? ( <Badge variant="secondary" className="text-xs"> <Loader2 className="w-3 h-3 mr-1 animate-spin" /> - 로딩... + {t('shiSync.status.loading')} </Badge> ) : error ? ( <Badge variant="destructive" className="text-xs"> <AlertTriangle className="w-3 h-3 mr-1" /> - 오류 + {t('shiSync.status.error')} </Badge> ) : syncStatus && syncStatus.pendingChanges > 0 ? ( <Badge variant="destructive" className="text-xs"> - {syncStatus.pendingChanges}건 대기 + {t('shiSync.status.pendingCount', { count: syncStatus.pendingChanges })} </Badge> ) : ( <Badge variant="secondary" className="text-xs"> <CheckCircle className="w-3 h-3 mr-1" /> - 최신 + {t('shiSync.status.upToDate')} </Badge> )} </div> @@ -374,7 +392,7 @@ export function SendToSHIButton({ {documentsContractIds.length === 0 && ( <Alert> <AlertDescription> - 동기화할 문서가 없습니다. 문서를 선택해주세요. + {t('shiSync.descriptions.noDocumentsToSync')} </AlertDescription> </Alert> )} @@ -392,12 +410,12 @@ export function SendToSHIButton({ {isSyncing ? ( <> <Loader2 className="w-4 h-4 mr-2 animate-spin" /> - 동기화 중... + {t('shiSync.buttons.syncing')} </> ) : ( <> <Send className="w-4 h-4 mr-2" /> - 지금 동기화 + {t('shiSync.buttons.syncNow')} </> )} </Button> @@ -426,10 +444,13 @@ export function SendToSHIButton({ <DialogHeader> <DialogTitle className="flex items-center gap-2"> <Send className="w-5 h-5" /> - SHI 시스템으로 동기화 + {t('shiSync.dialog.title')} </DialogTitle> <DialogDescription> - {documentsContractIds.length}개 계약의 변경된 문서 데이터를 {targetSystem} 시스템으로 전송합니다. + {t('shiSync.dialog.description', { + contractCount: documentsContractIds.length, + targetSystem + })} </DialogDescription> </DialogHeader> @@ -437,30 +458,30 @@ export function SendToSHIButton({ {!totalStats.hasError && documentsContractIds.length > 0 && ( <div className="rounded-lg border p-4 space-y-3"> <div className="flex items-center justify-between text-sm"> - <span>전송 대상</span> - <span className="font-medium">{totalStats.totalPending}건</span> + <span>{t('shiSync.labels.syncTarget')}</span> + <span className="font-medium">{t('shiSync.labels.itemCount', { count: totalStats.totalPending })}</span> </div> <div className="flex items-center justify-between text-sm"> - <span>대상 계약</span> - <span className="font-medium">{documentsContractIds.length}개</span> + <span>{t('shiSync.labels.targetContracts')}</span> + <span className="font-medium">{t('shiSync.labels.contractCount', { count: documentsContractIds.length })}</span> </div> <div className="text-xs text-muted-foreground"> - 문서, 리비전, 첨부파일의 변경사항이 포함됩니다. + {t('shiSync.descriptions.includesChanges')} </div> {isSyncing && ( <div className="space-y-2"> <div className="flex items-center justify-between text-sm"> - <span>진행률</span> + <span>{t('shiSync.labels.progress')}</span> <span>{Math.round(syncProgress)}%</span> </div> <Progress value={syncProgress} className="h-2" /> {currentSyncingContract && ( <div className="text-xs text-muted-foreground flex items-center gap-1"> <Loader2 className="w-3 h-3 animate-spin" /> - 현재 처리 중: Contract {currentSyncingContract} + {t('shiSync.descriptions.currentlyProcessing', { contractId: currentSyncingContract })} </div> )} </div> @@ -472,7 +493,7 @@ export function SendToSHIButton({ <Alert variant="destructive"> <AlertTriangle className="h-4 w-4" /> <AlertDescription> - 일부 계약의 동기화 상태를 확인할 수 없습니다. 네트워크 연결을 확인하고 다시 시도해주세요. + {t('shiSync.descriptions.dialogStatusCheckError')} </AlertDescription> </Alert> )} @@ -480,7 +501,7 @@ export function SendToSHIButton({ {documentsContractIds.length === 0 && ( <Alert> <AlertDescription> - 동기화할 계약이 없습니다. 문서를 선택해주세요. + {t('shiSync.descriptions.noContractsToSync')} </AlertDescription> </Alert> )} @@ -491,7 +512,7 @@ export function SendToSHIButton({ onClick={() => setIsDialogOpen(false)} disabled={isSyncing} > - 취소 + {t('buttons.cancel')} </Button> <Button onClick={handleSync} @@ -500,12 +521,12 @@ export function SendToSHIButton({ {isSyncing ? ( <> <Loader2 className="w-4 h-4 mr-2 animate-spin" /> - 동기화 중... + {t('shiSync.buttons.syncing')} </> ) : ( <> <Send className="w-4 h-4 mr-2" /> - 동기화 시작 + {t('shiSync.buttons.startSync')} </> )} </Button> |
