summaryrefslogtreecommitdiff
path: root/lib/vendor-document-list/ship/send-to-shi-button.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-08-11 09:02:00 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-08-11 09:02:00 +0000
commitcbb4c7fe0b94459162ad5e998bc05cd293e0ff96 (patch)
tree0a26712f7685e4f6511e637b9a81269d90a47c8f /lib/vendor-document-list/ship/send-to-shi-button.tsx
parenteb654f88214095f71be142b989e620fd28db3f69 (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.tsx127
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>