fix:전자세금계산서 운영모드 안전장치 추가

- 운영 모드일 때 "새로 발행" 버튼에서 "(랜덤 데이터)" 텍스트 제거
- 운영 모드일 때 "랜덤 데이터 재생성" 버튼 숨김
- 운영 모드일 때 국세청 전송 경고 메시지 표시
- 운영 모드일 때 발행 버튼 빨간색으로 변경 (주의 환기)
- 헤더에 "운영 모드" 뱃지 표시 (경고 아이콘 포함)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
김보곤
2026-02-03 07:57:30 +09:00
parent 83b2c1d16c
commit ccbe596f6f

View File

@@ -101,6 +101,9 @@
isHeadquarters: {{ ($currentTenant?->id ?? 0) == 1 ? 'true' : 'false' }}
};
// 서버 모드 정보
const IS_TEST_MODE = {{ $isTestMode ? 'true' : 'false' }};
// StatCard Component
const StatCard = ({ title, value, subtext, icon }) => (
<div className="bg-white rounded-xl p-6 shadow-sm border border-stone-100 hover:shadow-md transition-shadow">
@@ -352,15 +355,33 @@
<textarea className="w-full rounded-lg border-stone-200 border p-3 focus:ring-2 focus:ring-blue-500 outline-none" rows="2" value={formData.memo} onChange={(e) => setFormData({ ...formData, memo: e.target.value })} placeholder="추가 메모사항" />
</div>
{/* 운영 모드 경고 */}
{!IS_TEST_MODE && (
<div className="p-4 bg-red-50 border border-red-200 rounded-lg mb-4">
<div className="flex items-start gap-3">
<svg className="w-5 h-5 text-red-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
</svg>
<div>
<p className="text-sm font-semibold text-red-800">운영 서버 - 실제 국세청 전송</p>
<p className="text-xs text-red-600 mt-1">발행된 세금계산서는 실제 국세청으로 전송됩니다. 입력 정보를 신중히 확인하시기 바랍니다.</p>
</div>
</div>
</div>
)}
<div className="flex items-center justify-between pt-4 border-t">
<div className="flex gap-2">
<button type="button" onClick={onCancel} className="px-4 py-2 text-stone-600 hover:text-stone-800">취소</button>
<button type="button" onClick={regenerateData} className="px-4 py-2 text-blue-600 hover:text-blue-700 flex items-center gap-1">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
랜덤 데이터 재생성
</button>
{/* 랜덤 데이터 재생성 버튼은 테스트 모드에서만 표시 */}
{IS_TEST_MODE && (
<button type="button" onClick={regenerateData} className="px-4 py-2 text-blue-600 hover:text-blue-700 flex items-center gap-1">
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
랜덤 데이터 재생성
</button>
)}
</div>
<button type="submit" disabled={isSubmitting} className="px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium transition-colors disabled:opacity-50 flex items-center gap-2">
<button type="submit" disabled={isSubmitting} className={`px-6 py-3 text-white rounded-lg font-medium transition-colors disabled:opacity-50 flex items-center gap-2 ${IS_TEST_MODE ? 'bg-blue-600 hover:bg-blue-700' : 'bg-red-600 hover:bg-red-700'}`}>
{isSubmitting ? (
<><div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div> 발행 ...</>
) : (
@@ -841,6 +862,13 @@ className="px-3 py-1.5 text-sm bg-stone-100 text-stone-600 rounded-lg hover:bg-s
<div className="flex items-center gap-2">
@if($isTestMode)
<span className="px-3 py-1 bg-amber-100 text-amber-700 rounded-full text-xs font-medium">테스트 모드</span>
@else
<span className="px-3 py-1 bg-red-100 text-red-700 rounded-full text-xs font-medium flex items-center gap-1">
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
운영 모드
</span>
@endif
@if($hasSoapClient)
<span className="px-3 py-1 bg-green-100 text-green-700 rounded-full text-xs font-medium">SOAP 연결됨</span>
@@ -866,9 +894,9 @@ className="px-3 py-1.5 text-sm bg-stone-100 text-stone-600 rounded-lg hover:bg-s
전자세금계산서 발행
</h2>
{!showIssueForm && (
<button onClick={() => setShowIssueForm(true)} className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 font-medium transition-colors flex items-center gap-2">
<button onClick={() => setShowIssueForm(true)} className={`px-4 py-2 text-white rounded-lg font-medium transition-colors flex items-center gap-2 ${IS_TEST_MODE ? 'bg-blue-600 hover:bg-blue-700' : 'bg-red-600 hover:bg-red-700'}`}>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/></svg>
새로 발행 (랜덤 데이터)
{IS_TEST_MODE ? '새로 발행 (랜덤 데이터)' : '새로 발행'}
</button>
)}
</div>