Looka vs Brandmark 비교 마크다운 문서를 세련된 디자인의 PHP 대시보드 페이지로 변환 완료
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,3 +35,7 @@ g "작업 요약 내용"
|
||||
- 단지 제안만 하세요
|
||||
- 커밋 메시지는 작업 내용을 정확히 반영해야 합니다
|
||||
|
||||
## 문서 작성 규칙
|
||||
1. **한국어 사용**: `.md` (Markdown) 파일을 작성할 때는 항상 한국어를 사용하세요.
|
||||
2. **명확한 구조**: 문서의 가독성을 위해 헤더, 목록, 코드 블록 등을 적절히 사용하여 구조화하세요.
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
require_once('barobill_account_config.php');
|
||||
require_once(getenv('DOCUMENT_ROOT') . '/session.php');
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
// 인증서 키(CERTKEY) 파일 경로
|
||||
// load .env file
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
// 인증서 키(CERTKEY) 파일 경로
|
||||
$documentRoot = getenv('DOCUMENT_ROOT');
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
// 인증서 키(CERTKEY) 파일 경로
|
||||
// load .env file
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
// 인증서 키(CERTKEY) 파일 경로
|
||||
$documentRoot = getenv('DOCUMENT_ROOT');
|
||||
@@ -5,8 +5,8 @@
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
require_once('barobill_account_config.php');
|
||||
require_once(getenv('DOCUMENT_ROOT') . '/session.php');
|
||||
@@ -5,8 +5,8 @@
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
require_once(getenv('DOCUMENT_ROOT') . '/session.php');
|
||||
require_once(getenv('DOCUMENT_ROOT') . '/lib/mydb.php');
|
||||
@@ -5,8 +5,8 @@
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
require_once(getenv('DOCUMENT_ROOT') . '/session.php');
|
||||
require_once(getenv('DOCUMENT_ROOT') . '/lib/mydb.php');
|
||||
@@ -16,8 +16,8 @@
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// load .env
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
require_once('barobill_card_config.php');
|
||||
|
||||
@@ -70,31 +70,47 @@
|
||||
<line x1="12" x2="12" y1="21" y2="8"/>
|
||||
</svg>
|
||||
),
|
||||
arrowUp: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-red-500">
|
||||
<line x1="12" y1="19" x2="12" y2="5"></line>
|
||||
<polyline points="5 12 12 5 19 12"></polyline>
|
||||
</svg>
|
||||
),
|
||||
arrowDown: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-blue-500">
|
||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||||
<polyline points="19 12 12 19 5 12"></polyline>
|
||||
</svg>
|
||||
),
|
||||
search: () => (
|
||||
building: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="11" cy="11" r="8"/>
|
||||
<path d="m21 21-4.3-4.3"/>
|
||||
<rect width="16" height="20" x="4" y="2" rx="2" ry="2"/>
|
||||
<path d="M9 22v-4h6v4"/>
|
||||
<path d="M8 6h.01"/>
|
||||
<path d="M16 6h.01"/>
|
||||
<path d="M12 6h.01"/>
|
||||
<path d="M12 10h.01"/>
|
||||
<path d="M12 14h.01"/>
|
||||
<path d="M16 10h.01"/>
|
||||
<path d="M16 14h.01"/>
|
||||
<path d="M8 10h.01"/>
|
||||
<path d="M8 14h.01"/>
|
||||
</svg>
|
||||
),
|
||||
fileText: () => (
|
||||
creditCard: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
|
||||
<path d="M10 9H8"/>
|
||||
<path d="M16 13H8"/>
|
||||
<path d="M16 17H8"/>
|
||||
<rect width="20" height="14" x="2" y="5" rx="2"/>
|
||||
<line x1="2" x2="22" y1="10" y2="10"/>
|
||||
</svg>
|
||||
),
|
||||
receipt: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1-2-1Z"/>
|
||||
<path d="M14 8H8"/>
|
||||
<path d="M16 12H8"/>
|
||||
<path d="M13 16H8"/>
|
||||
</svg>
|
||||
),
|
||||
users: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
||||
</svg>
|
||||
),
|
||||
bookOpen: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a4 4 0 0 0-4-4H2z"/>
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a4 4 0 0 1 4-4h6z"/>
|
||||
</svg>
|
||||
),
|
||||
home: () => (
|
||||
@@ -103,26 +119,10 @@
|
||||
<polyline points="9 22 9 12 15 12 15 22"/>
|
||||
</svg>
|
||||
),
|
||||
chevronsLeft: () => (
|
||||
search: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m11 17-5-5 5-5"/>
|
||||
<path d="m18 17-5-5 5-5"/>
|
||||
</svg>
|
||||
),
|
||||
chevronLeft: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m15 18-6-6 6-6"/>
|
||||
</svg>
|
||||
),
|
||||
chevronRight: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m9 18 6-6-6-6"/>
|
||||
</svg>
|
||||
),
|
||||
chevronsRight: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m6 17 5-5-5-5"/>
|
||||
<path d="m13 17 5-5-5-5"/>
|
||||
<circle cx="11" cy="11" r="8"/>
|
||||
<path d="m21 21-4.3-4.3"/>
|
||||
</svg>
|
||||
),
|
||||
download: ({ className }) => (
|
||||
@@ -139,18 +139,16 @@
|
||||
<path d="M12 8h.01"/>
|
||||
</svg>
|
||||
),
|
||||
receipt: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1-2-1Z"/>
|
||||
<path d="M14 8H8"/>
|
||||
<path d="M16 12H8"/>
|
||||
<path d="M13 16H8"/>
|
||||
arrowUp: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="12" y1="19" x2="12" y2="5"></line>
|
||||
<polyline points="5 12 12 5 19 12"></polyline>
|
||||
</svg>
|
||||
),
|
||||
creditCard: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<rect width="20" height="14" x="2" y="5" rx="2"/>
|
||||
<line x1="2" x2="22" y1="10" y2="10"/>
|
||||
arrowDown: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||||
<polyline points="19 12 12 19 5 12"></polyline>
|
||||
</svg>
|
||||
),
|
||||
x: ({ className }) => (
|
||||
@@ -158,27 +156,40 @@
|
||||
<path d="M18 6 6 18"/>
|
||||
<path d="m6 6 12 12"/>
|
||||
</svg>
|
||||
),
|
||||
fileText: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
|
||||
<path d="M10 9H8"/>
|
||||
<path d="M16 13H8"/>
|
||||
<path d="M16 17H8"/>
|
||||
</svg>
|
||||
)
|
||||
};
|
||||
|
||||
// Header Component
|
||||
const Header = ({ activeTab, onTabChange, tenants, currentTenantId, onTenantChange }) => (
|
||||
<header className="bg-white border-b border-gray-100 sticky top-0 z-50 transition-all">
|
||||
const Header = ({ activeTab, onTabChange, tenants, currentTenantId, onTenantChange, onOpenApiInfo }) => (
|
||||
<header className="bg-white/80 backdrop-blur-md border-b border-blue-100/50 sticky top-0 z-50 transition-all shadow-sm">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="h-16 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600 font-bold shadow-sm">
|
||||
🏦
|
||||
<div className="h-18 flex items-center justify-between py-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-xl flex items-center justify-center text-white shadow-lg shadow-blue-200/50 ring-4 ring-blue-50">
|
||||
<Icons.wallet />
|
||||
</div>
|
||||
<h1 className="text-lg font-semibold text-slate-900">계좌 입출금내역</h1>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-slate-900 tracking-tight leading-none">계좌 입출금내역</h1>
|
||||
<p className="text-[10px] text-blue-600 font-semibold mt-1 uppercase tracking-wider opacity-70">Bank Transaction History</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 text-sm text-slate-500 font-medium">
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 text-sm text-slate-500 font-medium">
|
||||
{/* 테넌트 선택 드롭다운 */}
|
||||
{tenants.length > 0 && (
|
||||
<select
|
||||
value={currentTenantId}
|
||||
onChange={(e) => onTenantChange(e.target.value)}
|
||||
className="text-sm border border-slate-300 rounded-lg px-3 py-1.5 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-blue-500 mr-2"
|
||||
className="text-xs border border-slate-200 rounded-lg px-3 py-2 bg-white/50 hover:bg-white focus:outline-none focus:ring-2 focus:ring-blue-500 mr-2 transition-all"
|
||||
>
|
||||
{tenants.map(tenant => (
|
||||
<option key={tenant.id} value={tenant.id}>
|
||||
@@ -188,29 +199,31 @@
|
||||
</select>
|
||||
)}
|
||||
|
||||
<a href="../eaccount/index.php" className="text-blue-600 flex items-center gap-1 bg-blue-50 px-3 py-1.5 rounded-lg border border-blue-100 cursor-default font-bold">
|
||||
<Icons.wallet /> 계좌조회
|
||||
<div className="flex bg-slate-100/50 p-1 rounded-xl border border-slate-200/50 mr-2">
|
||||
<a href="index.php" className="flex items-center gap-2 px-4 py-2 rounded-lg bg-white text-blue-600 shadow-sm border border-blue-100 font-bold transition-all">
|
||||
<Icons.wallet /> <span>계좌조회</span>
|
||||
</a>
|
||||
<a href="../ecard/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<Icons.creditCard /> 카드내역
|
||||
<a href="../ecard/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.creditCard /> <span>카드내역</span>
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<Icons.bank /> 테넌트관리
|
||||
<a href="../tenant/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.bank /> <span>테넌트</span>
|
||||
</a>
|
||||
<a href="../barobill_registration/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg> 회원관리
|
||||
</a>
|
||||
<a href="../etax/barobill_api_info.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<Icons.info className="w-4 h-4" /> API정보
|
||||
<a href="../registration/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.users /> <span>바로빌 회원관리</span>
|
||||
</a>
|
||||
<button onClick={(e) => { e.preventDefault(); onOpenApiInfo(); }} className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.bookOpen /> <span>API정보</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-1"></div>
|
||||
<div className="h-4 w-px bg-slate-200 mx-2"></div>
|
||||
|
||||
<a href="../etax/index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<Icons.receipt /> 세금계산서
|
||||
<a href="../etax/index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<Icons.receipt /> <span className="hidden lg:inline text-xs">세금계산서</span>
|
||||
</a>
|
||||
<a href="../index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<Icons.home /> 홈
|
||||
<a href="../../index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<Icons.home /> <span className="hidden lg:inline text-xs">홈</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -435,6 +448,32 @@
|
||||
);
|
||||
};
|
||||
|
||||
const ApiInfoModal = ({ isOpen, onClose }) => {
|
||||
if (!isOpen) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" onClick={onClose}>
|
||||
<div className="bg-white rounded-2xl shadow-2xl w-full max-w-5xl max-h-[90vh] flex flex-col overflow-hidden animate-in fade-in zoom-in-95 duration-200" onClick={e => e.stopPropagation()}>
|
||||
<div className="p-4 border-b border-slate-100 flex justify-between items-center bg-slate-50/50">
|
||||
<h3 className="text-lg font-bold text-slate-900 flex items-center gap-2">
|
||||
<span className="w-1.5 h-6 bg-blue-500 rounded-full"></span>
|
||||
바로빌 API 상세 정보
|
||||
</h3>
|
||||
<button onClick={onClose} className="p-2 rounded-full text-slate-400 hover:text-slate-600 hover:bg-slate-100 transition-colors">
|
||||
<Icons.x className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1 bg-slate-50">
|
||||
<iframe
|
||||
src="../etax/barobill_api_info.php"
|
||||
className="w-full h-full border-none min-h-[600px]"
|
||||
title="API Information"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Usage Table Component
|
||||
const UsageTable = ({ logs, loading }) => {
|
||||
if (loading) {
|
||||
@@ -597,6 +636,7 @@
|
||||
const [diagnosticModal, setDiagnosticModal] = useState({ open: false, content: '', title: '' });
|
||||
const [tenants, setTenants] = useState([]);
|
||||
const [currentTenantId, setCurrentTenantId] = useState('');
|
||||
const [isApiInfoModalOpen, setIsApiInfoModalOpen] = useState(false);
|
||||
|
||||
// 날짜 초기화
|
||||
useEffect(() => {
|
||||
@@ -872,6 +912,7 @@
|
||||
tenants={tenants}
|
||||
currentTenantId={currentTenantId}
|
||||
onTenantChange={changeTenant}
|
||||
onOpenApiInfo={() => setIsApiInfoModalOpen(true)}
|
||||
/>
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-8">
|
||||
@@ -1419,6 +1460,11 @@
|
||||
title={diagnosticModal.title}
|
||||
content={diagnosticModal.content}
|
||||
/>
|
||||
|
||||
<ApiInfoModal
|
||||
isOpen={isApiInfoModalOpen}
|
||||
onClose={() => setIsApiInfoModalOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -59,54 +59,8 @@
|
||||
<path d="M18 12a2 2 0 0 0 0 4h4v-4Z"/>
|
||||
</svg>
|
||||
),
|
||||
receipt: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1Z"/>
|
||||
<path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"/>
|
||||
<path d="M12 17.5v-11"/>
|
||||
</svg>
|
||||
),
|
||||
creditCard: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect width="20" height="14" x="2" y="5" rx="2"/>
|
||||
<line x1="2" x2="22" y1="10" y2="10"/>
|
||||
</svg>
|
||||
),
|
||||
xCircle: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="m15 9-6 6"/>
|
||||
<path d="m9 9 6 6"/>
|
||||
</svg>
|
||||
),
|
||||
filter: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>
|
||||
</svg>
|
||||
),
|
||||
search: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="11" cy="11" r="8"/>
|
||||
<path d="m21 21-4.3-4.3"/>
|
||||
</svg>
|
||||
),
|
||||
fileText: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
|
||||
<path d="M10 9H8"/>
|
||||
<path d="M16 13H8"/>
|
||||
<path d="M16 17H8"/>
|
||||
</svg>
|
||||
),
|
||||
home: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
|
||||
<polyline points="9 22 9 12 15 12 15 22"/>
|
||||
</svg>
|
||||
),
|
||||
bank: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M3 21h18"/>
|
||||
<path d="M5 21v-7"/>
|
||||
<path d="M19 21v-7"/>
|
||||
@@ -131,6 +85,66 @@
|
||||
<path d="M8 14h.01"/>
|
||||
</svg>
|
||||
),
|
||||
creditCard: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<rect width="20" height="14" x="2" y="5" rx="2"/>
|
||||
<line x1="2" x2="22" y1="10" y2="10"/>
|
||||
</svg>
|
||||
),
|
||||
creditCardLarge: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="opacity-50">
|
||||
<rect width="20" height="14" x="2" y="5" rx="2"/>
|
||||
<line x1="2" x2="22" y1="10" y2="10"/>
|
||||
</svg>
|
||||
),
|
||||
receipt: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M4 2v20l2-1 2 1 2-1 2 1 2-1 2 1 2-1 2 1V2l-2 1-2-1-2 1-2-1-2 1-2-1-2 1-2-1Z"/>
|
||||
<path d="M14 8H8"/>
|
||||
<path d="M16 12H8"/>
|
||||
<path d="M13 16H8"/>
|
||||
</svg>
|
||||
),
|
||||
users: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87"/>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
||||
</svg>
|
||||
),
|
||||
bookOpen: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M2 3h6a4 4 0 0 1 4 4v14a4 4 0 0 0-4-4H2z"/>
|
||||
<path d="M22 3h-6a4 4 0 0 0-4 4v14a4 4 0 0 1 4-4h6z"/>
|
||||
</svg>
|
||||
),
|
||||
home: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
|
||||
<polyline points="9 22 9 12 15 12 15 22"/>
|
||||
</svg>
|
||||
),
|
||||
search: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="11" cy="11" r="8"/>
|
||||
<path d="m21 21-4.3-4.3"/>
|
||||
</svg>
|
||||
),
|
||||
download: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" x2="12" y1="15" y2="3"/>
|
||||
</svg>
|
||||
),
|
||||
info: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 16v-4"/>
|
||||
<path d="M12 8h.01"/>
|
||||
</svg>
|
||||
),
|
||||
alertCircle: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
@@ -138,6 +152,30 @@
|
||||
<line x1="12" x2="12.01" y1="16" y2="16"/>
|
||||
</svg>
|
||||
),
|
||||
xCircle: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="m15 9-6 6"/>
|
||||
<path d="m9 9 6 6"/>
|
||||
</svg>
|
||||
),
|
||||
filter: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>
|
||||
</svg>
|
||||
),
|
||||
arrowUp: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="12" y1="19" x2="12" y2="5"></line>
|
||||
<polyline points="5 12 12 5 19 12"></polyline>
|
||||
</svg>
|
||||
),
|
||||
arrowDown: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||||
<polyline points="19 12 12 19 5 12"></polyline>
|
||||
</svg>
|
||||
),
|
||||
chevronsLeft: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="m11 17-5-5 5-5"/>
|
||||
@@ -160,68 +198,63 @@
|
||||
<path d="m13 17 5-5-5-5"/>
|
||||
</svg>
|
||||
),
|
||||
creditCardLarge: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="opacity-50">
|
||||
<rect width="20" height="14" x="2" y="5" rx="2"/>
|
||||
<line x1="2" x2="22" y1="10" y2="10"/>
|
||||
</svg>
|
||||
),
|
||||
download: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" x2="12" y1="15" y2="3"/>
|
||||
</svg>
|
||||
),
|
||||
info: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 16v-4"/>
|
||||
<path d="M12 8h.01"/>
|
||||
</svg>
|
||||
),
|
||||
x: ({ className }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
|
||||
<path d="M18 6 6 18"/>
|
||||
<path d="m6 6 12 12"/>
|
||||
</svg>
|
||||
),
|
||||
fileText: () => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/>
|
||||
<path d="M14 2v4a2 2 0 0 0 2 2h4"/>
|
||||
<path d="M10 9H8"/>
|
||||
<path d="M16 13H8"/>
|
||||
<path d="M16 17H8"/>
|
||||
</svg>
|
||||
)
|
||||
};
|
||||
|
||||
// Header Component
|
||||
const Header = () => (
|
||||
<header className="bg-white border-b border-gray-100 sticky top-0 z-50 transition-all">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-emerald-100 rounded-lg flex items-center justify-center text-emerald-600 font-bold shadow-sm">
|
||||
💳
|
||||
const Header = ({ onOpenApiInfo }) => (
|
||||
<header className="bg-white/80 backdrop-blur-md border-b border-emerald-100/50 sticky top-0 z-50 transition-all shadow-sm">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-18 flex items-center justify-between py-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-emerald-500 to-teal-600 rounded-xl flex items-center justify-center text-white shadow-lg shadow-emerald-200/50 ring-4 ring-emerald-50">
|
||||
<Icons.creditCard />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-slate-900 tracking-tight leading-none">법인카드 내역</h1>
|
||||
<p className="text-[10px] text-emerald-600 font-semibold mt-1 uppercase tracking-wider opacity-70">Corporate Card History</p>
|
||||
</div>
|
||||
<h1 className="text-lg font-semibold text-slate-900">법인카드 사용내역</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 text-sm text-slate-500 font-medium">
|
||||
<a href="../eaccount/index.php" className="hover:text-emerald-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<Icons.wallet /> 계좌조회
|
||||
</a>
|
||||
<a href="../ecard/index.php" className="text-emerald-600 flex items-center gap-1 bg-emerald-50 px-3 py-1.5 rounded-lg border border-emerald-100 cursor-default font-bold">
|
||||
<Icons.creditCard /> 카드내역
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="hover:text-emerald-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<Icons.building /> 테넌트관리
|
||||
</a>
|
||||
<a href="../barobill_registration/index.php" className="hover:text-emerald-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg> 회원관리
|
||||
</a>
|
||||
<a href="../etax/barobill_api_info.php" className="hover:text-emerald-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<Icons.info className="w-4 h-4" /> API정보
|
||||
</a>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-1"></div>
|
||||
|
||||
<a href="../etax/index.php" className="hover:text-emerald-700 flex items-center gap-1">
|
||||
<Icons.receipt /> 세금계산서
|
||||
<div className="flex items-center gap-2 text-sm text-slate-500 font-medium">
|
||||
<div className="flex bg-slate-100/50 p-1 rounded-xl border border-slate-200/50 mr-2">
|
||||
<a href="../eaccount/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-emerald-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.wallet /> <span>계좌조회</span>
|
||||
</a>
|
||||
<a href="../index.php" className="hover:text-emerald-700 flex items-center gap-1">
|
||||
<Icons.home /> 홈
|
||||
<a href="index.php" className="flex items-center gap-4 px-4 py-2 rounded-lg bg-white text-emerald-600 shadow-sm border border-emerald-100 font-bold">
|
||||
<Icons.creditCard /> <span>카드내역</span>
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-emerald-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.building /> <span>테넌트</span>
|
||||
</a>
|
||||
<a href="../registration/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-emerald-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.users /> <span>바로빌 회원관리</span>
|
||||
</a>
|
||||
<button onClick={(e) => { e.preventDefault(); onOpenApiInfo(); }} className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-emerald-600 hover:bg-white transition-all duration-200">
|
||||
<Icons.bookOpen /> <span>API정보</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-2"></div>
|
||||
|
||||
<a href="../etax/index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-emerald-600 transition-colors">
|
||||
<Icons.receipt /> <span className="hidden lg:inline text-xs">세금계산서</span>
|
||||
</a>
|
||||
<a href="../../index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-emerald-600 transition-colors">
|
||||
<Icons.home /> <span className="hidden lg:inline text-xs">홈</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -492,6 +525,32 @@
|
||||
);
|
||||
};
|
||||
|
||||
const ApiInfoModal = ({ isOpen, onClose }) => {
|
||||
if (!isOpen) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" onClick={onClose}>
|
||||
<div className="bg-white rounded-2xl shadow-2xl w-full max-w-5xl max-h-[90vh] flex flex-col overflow-hidden animate-in fade-in zoom-in-95 duration-200" onClick={e => e.stopPropagation()}>
|
||||
<div className="p-4 border-b border-emerald-100 flex justify-between items-center bg-emerald-50/50">
|
||||
<h3 className="text-lg font-bold text-slate-900 flex items-center gap-2">
|
||||
<span className="w-1.5 h-6 bg-emerald-500 rounded-full"></span>
|
||||
바로빌 API 상세 정보
|
||||
</h3>
|
||||
<button onClick={onClose} className="p-2 rounded-full text-slate-400 hover:text-slate-600 hover:bg-slate-100 transition-colors">
|
||||
<Icons.x className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1 bg-slate-50">
|
||||
<iframe
|
||||
src="../etax/barobill_api_info.php"
|
||||
className="w-full h-full border-none min-h-[600px]"
|
||||
title="API Information"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Date Range Selector Component
|
||||
const DateRangeSelector = ({ startDate, endDate, onStartChange, onEndChange, onSearch }) => (
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
@@ -700,6 +759,7 @@
|
||||
const [error, setError] = useState(null);
|
||||
const [txtExportModalOpen, setTxtExportModalOpen] = useState(false);
|
||||
const [fieldExportModalOpen, setFieldExportModalOpen] = useState(false);
|
||||
const [isApiInfoModalOpen, setIsApiInfoModalOpen] = useState(false);
|
||||
|
||||
// 날짜 초기화
|
||||
useEffect(() => {
|
||||
@@ -783,7 +843,7 @@
|
||||
|
||||
return (
|
||||
<div className="min-h-screen pb-20">
|
||||
<Header />
|
||||
<Header onOpenApiInfo={() => setIsApiInfoModalOpen(true)} />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-8">
|
||||
{/* 통계 카드 */}
|
||||
@@ -916,6 +976,11 @@
|
||||
onClose={() => setFieldExportModalOpen(false)}
|
||||
logs={logs}
|
||||
/>
|
||||
|
||||
<ApiInfoModal
|
||||
isOpen={isApiInfoModalOpen}
|
||||
onClose={() => setIsApiInfoModalOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
|
||||
// load .env file
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
|
||||
// 인증서 키(CERTKEY) 파일 경로
|
||||
$documentRoot = getenv('DOCUMENT_ROOT');
|
||||
@@ -5,21 +5,21 @@ error_reporting(E_ALL);
|
||||
header('Content-Type: text/plain');
|
||||
|
||||
echo "Current Dir: " . __DIR__ . "\n";
|
||||
echo "DotEnv Path: " . __DIR__ . '/../../lib/DotEnv.php' . "\n";
|
||||
echo "Env File Path: " . __DIR__ . '/../../.env' . "\n";
|
||||
echo "DotEnv Path: " . __DIR__ . '/../../../lib/DotEnv.php' . "\n";
|
||||
echo "Env File Path: " . __DIR__ . '/../../../.env' . "\n";
|
||||
|
||||
if (file_exists(__DIR__ . '/../../lib/DotEnv.php')) {
|
||||
if (file_exists(__DIR__ . '/../../../lib/DotEnv.php')) {
|
||||
echo "DotEnv file exists.\n";
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
require_once __DIR__ . '/../../../lib/DotEnv.php';
|
||||
echo "DotEnv loaded.\n";
|
||||
} else {
|
||||
echo "DotEnv file NOT found.\n";
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__ . '/../../.env')) {
|
||||
if (file_exists(__DIR__ . '/../../../.env')) {
|
||||
echo ".env file exists.\n";
|
||||
try {
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
(new DotEnv(__DIR__ . '/../../../.env'))->load();
|
||||
echo ".env loaded.\n";
|
||||
} catch (Exception $e) {
|
||||
echo "Error loading .env: " . $e->getMessage() . "\n";
|
||||
@@ -313,6 +313,34 @@
|
||||
"memo": "A\/S 납품",
|
||||
"createdAt": "2026-01-14T09:13:58",
|
||||
"barobillInvoiceId": "1"
|
||||
},
|
||||
{
|
||||
"id": "inv_1768384628",
|
||||
"issueKey": "MGT202601141857081230",
|
||||
"mgtKey": "MGT202601141857081230",
|
||||
"supplierBizno": "664-86-03713",
|
||||
"supplierName": "(주)코드브릿지엑스",
|
||||
"recipientBizno": "311-46-00378",
|
||||
"recipientName": "김인태",
|
||||
"supplyDate": "2025-12-22",
|
||||
"items": [
|
||||
{
|
||||
"name": "조명기구",
|
||||
"qty": 21,
|
||||
"unitPrice": 173624,
|
||||
"vatType": "vat",
|
||||
"supplyAmt": 3646104,
|
||||
"vat": 364610,
|
||||
"total": 4010714
|
||||
}
|
||||
],
|
||||
"totalSupplyAmt": 3646104,
|
||||
"totalVat": 364610,
|
||||
"total": 4010714,
|
||||
"status": "issued",
|
||||
"memo": "A\/S 납품",
|
||||
"createdAt": "2026-01-14T18:57:08",
|
||||
"barobillInvoiceId": "1"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../.env'))->load();
|
||||
require_once __DIR__ . '/../../lib/DotEnv.php';
|
||||
(new DotEnv(__DIR__ . '/../../.env'))->load();
|
||||
require_once(getenv('DOCUMENT_ROOT') . "/session.php");
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
@@ -20,12 +20,12 @@ require_once(getenv('DOCUMENT_ROOT') . "/session.php");
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #43cea2 0%, #185a9d 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
margin: 20px auto;
|
||||
background: white;
|
||||
border-radius: 20px;
|
||||
padding: 40px;
|
||||
@@ -166,31 +166,6 @@ require_once(getenv('DOCUMENT_ROOT') . "/session.php");
|
||||
color: #e83e8c;
|
||||
}
|
||||
|
||||
.home-btn {
|
||||
position: fixed;
|
||||
top: 30px;
|
||||
left: 30px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 25px;
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
font-size: 1em;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
z-index: 1000;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.home-btn:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
@@ -201,21 +176,10 @@ require_once(getenv('DOCUMENT_ROOT') . "/session.php");
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.home-btn {
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
padding: 10px 20px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Home Button -->
|
||||
<a href="../index.php" class="home-btn">
|
||||
<span>🏠</span>
|
||||
<span>홈으로</span>
|
||||
</a>
|
||||
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
@@ -425,7 +389,6 @@ Content-Type: application/json
|
||||
<li>인증서 등록 및 연동</li>
|
||||
<li>실제 프로젝트에 통합</li>
|
||||
</ol>
|
||||
<p><a href="../strategy/electronicTaxInvoice_index.php" class="btn">전략 페이지로 돌아가기</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
@@ -8,21 +8,26 @@
|
||||
<!-- Fonts: Pretendard -->
|
||||
<link rel="stylesheet" as="style" crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.8/dist/web/static/pretendard.css" />
|
||||
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<!-- Global Meta & Scripts -->
|
||||
<?php include_once __DIR__ . '/../../lib/meta_common.php'; ?>
|
||||
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Pretendard', 'sans-serif'],
|
||||
sans: ['Pretendard', 'Inter', 'Noto Sans KR', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
background: 'rgb(250, 250, 250)',
|
||||
primary: {
|
||||
DEFAULT: '#2563eb',
|
||||
foreground: '#ffffff',
|
||||
},
|
||||
brand: {
|
||||
50: '#f0f9ff',
|
||||
100: '#e0f2fe',
|
||||
200: '#bae6fd',
|
||||
500: '#0ea5e9',
|
||||
600: '#0284c7',
|
||||
700: '#0369a1',
|
||||
900: '#0c4a6e',
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
'card': '12px',
|
||||
@@ -31,18 +36,8 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- React & ReactDOM -->
|
||||
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
||||
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
||||
|
||||
<!-- Babel for JSX -->
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
|
||||
<!-- Icons: Lucide -->
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
</head>
|
||||
<body class="bg-background text-slate-800 antialiased">
|
||||
<body class="bg-slate-50 text-slate-800 antialiased">
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="text/babel">
|
||||
@@ -51,44 +46,63 @@
|
||||
// --- Components ---
|
||||
|
||||
// 1. Header Component
|
||||
const Header = ({ onOpenHelp }) => {
|
||||
const Header = ({ onOpenApiInfo }) => {
|
||||
return (
|
||||
<header className="bg-white border-b border-gray-100 sticky top-0 z-50 transition-all">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600 font-bold shadow-sm">
|
||||
📋
|
||||
<nav className="sticky top-0 z-30 bg-white/80 backdrop-blur-md border-b border-slate-200">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-center h-16">
|
||||
{/* Logo Section */}
|
||||
<div className="flex items-center gap-3 cursor-pointer" onClick={() => window.location.href='../../index.php'}>
|
||||
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold text-lg shadow-lg shadow-blue-200">
|
||||
S
|
||||
</div>
|
||||
<h1 className="text-lg font-semibold text-slate-900">전자세금계산서 솔루션</h1>
|
||||
<span className="text-xl font-bold tracking-tight text-slate-900">CodeBridgeX <span className="text-blue-600">SAM</span></span>
|
||||
<div className="h-4 w-px bg-slate-200 mx-2 hidden sm:block"></div>
|
||||
<h1 className="text-sm font-bold text-slate-500 hidden sm:block">전자세금계산서</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 text-sm text-slate-500 font-medium">
|
||||
<a href="../eaccount/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="wallet" className="w-4 h-4 text-blue-500"></i> 계좌조회
|
||||
</a>
|
||||
<a href="../ecard/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="credit-card" className="w-4 h-4 text-purple-500"></i> 카드내역
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="building" className="w-4 h-4 text-blue-600"></i> 테넌트관리
|
||||
</a>
|
||||
<a href="../barobill_registration/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="users" className="w-4 h-4 text-teal-500"></i> 회원관리
|
||||
</a>
|
||||
<a href="barobill_api_info.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="book-open" className="w-4 h-4 text-orange-500"></i> API정보
|
||||
</a>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-1"></div>
|
||||
{/* Desktop Navigation */}
|
||||
<div className="hidden md:flex items-center gap-4">
|
||||
<div className="flex bg-slate-100/50 p-1 rounded-xl border border-slate-200/50 mr-4">
|
||||
<a href="../eaccount/index.php" className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-semibold text-slate-600 hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="wallet" className="w-3.5 h-3.5 text-blue-500"></i> <span>계좌조회</span>
|
||||
</a>
|
||||
<a href="../ecard/index.php" className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-semibold text-slate-600 hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="credit-card" className="w-3.5 h-3.5 text-purple-500"></i> <span>카드내역</span>
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-semibold text-slate-600 hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="building" className="w-3.5 h-3.5 text-teal-500"></i> <span>테넌트</span>
|
||||
</a>
|
||||
<a href="../registration/index.php" className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-semibold text-slate-600 hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="users" className="w-3.5 h-3.5 text-amber-500"></i> <span>바로빌 회원관리</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<a href="../etax/index.php" className="text-blue-600 flex items-center gap-1 bg-blue-50 px-3 py-1.5 rounded-lg border border-blue-100 cursor-default font-bold">
|
||||
<i data-lucide="file-text" className="w-4 h-4"></i> 세금계산서
|
||||
</a>
|
||||
<a href="../index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<i data-lucide="home" className="w-4 h-4"></i> 홈
|
||||
<a href="../../salesmanagement/" className="text-sm font-medium text-slate-600 hover:text-blue-600 transition-colors">영업관리</a>
|
||||
<a href="../../price/index.php" className="text-sm font-medium text-slate-600 hover:text-blue-600 transition-colors">가격정책</a>
|
||||
|
||||
<button
|
||||
onClick={onOpenApiInfo}
|
||||
className="px-4 py-2 bg-slate-900 text-white text-sm font-bold rounded-lg hover:bg-slate-800 transition-all shadow-lg shadow-slate-200 flex items-center gap-2"
|
||||
>
|
||||
<i data-lucide="code-2" className="w-4 h-4"></i>
|
||||
API정보
|
||||
</button>
|
||||
|
||||
<a href="../../index.php" className="p-2 rounded-lg text-slate-400 hover:text-blue-600 hover:bg-slate-50 transition-all">
|
||||
<i data-lucide="home" className="w-5 h-5"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Mobile Toggle (Simplified for now) */}
|
||||
<div className="md:hidden">
|
||||
<button className="p-2 text-slate-600">
|
||||
<i data-lucide="menu" className="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -788,6 +802,7 @@
|
||||
const [selectedInvoice, setSelectedInvoice] = useState(null);
|
||||
const [showIssueForm, setShowIssueForm] = useState(false);
|
||||
const [apiLogs, setApiLogs] = useState([]);
|
||||
const [isApiInfoModalOpen, setIsApiInfoModalOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
loadInvoices();
|
||||
@@ -935,7 +950,7 @@
|
||||
|
||||
return (
|
||||
<div className="min-h-screen pb-20">
|
||||
<Header />
|
||||
<Header onOpenApiInfo={() => setIsApiInfoModalOpen(true)} />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8 space-y-8">
|
||||
{/* Dashboard Section */}
|
||||
@@ -1074,6 +1089,42 @@
|
||||
onClose={() => setSelectedInvoice(null)}
|
||||
/>
|
||||
)}
|
||||
|
||||
<ApiInfoModal
|
||||
isOpen={isApiInfoModalOpen}
|
||||
onClose={() => setIsApiInfoModalOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ApiInfoModal = ({ isOpen, onClose }) => {
|
||||
if (!isOpen) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-slate-900/60 backdrop-blur-sm">
|
||||
<div className="bg-white rounded-3xl w-full max-w-6xl overflow-hidden shadow-2xl animate-in fade-in zoom-in-95 duration-300 border border-slate-200 flex flex-col h-[85vh]">
|
||||
<div className="p-4 border-b border-slate-100 flex justify-between items-center bg-white/50 backdrop-blur-sm z-10">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="p-3 bg-slate-900 rounded-xl text-white shadow-lg shadow-slate-200">
|
||||
<i data-lucide="code-2" className="w-6 h-6"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-black text-slate-900 tracking-tight">바로빌 API 연동 가이드</h3>
|
||||
<p className="text-sm text-slate-500 font-medium">SAM 플랫폼의 전자세금계산서 연동 상세 규격 및 정보</p>
|
||||
</div>
|
||||
</div>
|
||||
<button onClick={onClose} className="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1 overflow-auto bg-slate-50 relative">
|
||||
<iframe
|
||||
src="barobill_api_info.php"
|
||||
className="w-full h-full border-none"
|
||||
title="API Information"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -48,43 +48,63 @@
|
||||
#modalOverlay.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 상세 단가표 (Shadcn 스타일) */
|
||||
.pricing-card { background: white; border-radius: 0.75rem; border: 1px solid #e2e8f0; box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1); }
|
||||
.pricing-badge { display: inline-flex; align-items: center; border-radius: 9999px; padding: 0.125rem 0.625rem; font-size: 0.75rem; font-weight: 500; }
|
||||
.pricing-table-header { background: #f8fafc; }
|
||||
.pricing-tier-row:hover { background: #f1f5f9; }
|
||||
.pricing-tab-active { background: white; box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1); font-weight: 600; color: #0d9488 !important; }
|
||||
.pricing-example-card { background: linear-gradient(135deg, #f8fafc, #f1f5f9); border: 1px solid #e2e8f0; }
|
||||
.pricing-summary-row { background: rgba(13, 148, 136, 0.05); }
|
||||
.pricing-collapsible { max-height: 0; overflow: hidden; transition: max-height 0.3s ease-out; }
|
||||
.pricing-collapsible.open { max-height: 2000px; }
|
||||
.pricing-rotate { transition: transform 0.3s ease; }
|
||||
.pricing-rotate.open { transform: rotate(180deg); }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-gray-100 min-h-screen">
|
||||
<!-- Header -->
|
||||
<header class="bg-white shadow-sm sticky top-0 z-50">
|
||||
<div class="max-w-6xl mx-auto px-4">
|
||||
<div class="flex items-center justify-between py-4">
|
||||
<div class="flex items-center space-x-4">
|
||||
<a href="../index.php" class="flex items-center justify-center w-10 h-10 bg-slate-100 hover:bg-teal-100 rounded-lg transition-colors" title="홈으로">
|
||||
<span class="text-xl">🏠</span>
|
||||
</a>
|
||||
<h1 class="text-xl font-bold text-slate-800">바로빌 API 회계 솔루션</h1>
|
||||
<header class="bg-white/80 backdrop-blur-md border-b border-teal-100/50 sticky top-0 z-50 transition-all shadow-sm">
|
||||
<div class="max-w-6xl mx-auto px-4 py-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="w-10 h-10 bg-gradient-to-br from-teal-500 to-emerald-600 rounded-xl flex items-center justify-center text-white shadow-lg shadow-teal-200/50 ring-4 ring-teal-50">
|
||||
<span class="text-xl">📊</span>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-lg font-bold text-slate-900 tracking-tight leading-none">바로빌 솔루션</h1>
|
||||
<p class="text-[10px] text-teal-600 font-semibold mt-1 uppercase tracking-wider opacity-70">API Integration Dashboard</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-4 text-xs text-slate-500 font-medium">
|
||||
<a href="../eaccount/index.php" class="hover:text-teal-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<span>💰</span> 계좌조회
|
||||
<div class="flex items-center gap-2 text-xs text-slate-500 font-medium">
|
||||
<div class="flex bg-slate-100/50 p-1 rounded-xl border border-slate-200/50 mr-2">
|
||||
<a href="eaccount/index.php" class="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-teal-600 hover:bg-white transition-all duration-200">
|
||||
<span>💰</span> <span>계좌조회</span>
|
||||
</a>
|
||||
<a href="../ecard/index.php" class="hover:text-teal-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<span>💳</span> 카드내역
|
||||
<a href="ecard/index.php" class="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-teal-600 hover:bg-white transition-all duration-200">
|
||||
<span>💳</span> <span>카드내역</span>
|
||||
</a>
|
||||
<a href="../tenant/index.php" class="hover:text-teal-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<span>🏢</span> 테넌트관리
|
||||
<a href="tenant/index.php" class="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-teal-600 hover:bg-white transition-all duration-200">
|
||||
<span>🏢</span> <span>테넌트</span>
|
||||
</a>
|
||||
<a href="../barobill_registration/index.php" class="hover:text-teal-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<span>👥</span> 회원관리
|
||||
</a>
|
||||
<a href="../etax/barobill_api_info.php" class="hover:text-teal-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<span>📖</span> API정보
|
||||
<a href="registration/index.php" class="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-teal-600 hover:bg-white transition-all duration-200">
|
||||
<span>👥</span> <span>바로빌 회원관리</span>
|
||||
</a>
|
||||
<button onclick="openApiInfoModal(); event.preventDefault();" class="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-teal-600 hover:bg-white transition-all duration-200">
|
||||
<span>📖</span> <span>API정보</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="h-4 w-px bg-slate-200 mx-1"></div>
|
||||
<div class="h-4 w-px bg-slate-200 mx-2"></div>
|
||||
|
||||
<a href="../etax/index.php" class="hover:text-teal-700 flex items-center gap-1">
|
||||
<span>📄</span> 세금계산서
|
||||
<a href="etax/index.php" class="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-teal-600 transition-colors">
|
||||
<span>📄</span> <span class="hidden lg:inline text-[10px]">세금계산서</span>
|
||||
</a>
|
||||
<a href="../index.php" class="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-teal-600 transition-colors">
|
||||
<span>🏠</span> <span class="hidden lg:inline text-[10px]">홈</span>
|
||||
</a>
|
||||
<span class="text-[10px] text-slate-400 opacity-50 ml-2"><?php echo date('Y-m-d'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1117,6 +1137,304 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============================================ -->
|
||||
<!-- 상세 단가표 (Shadcn Style) -->
|
||||
<!-- ============================================ -->
|
||||
<div class="mt-12 pt-12 border-t border-slate-200 fade-in fade-in-4">
|
||||
<div class="mb-8">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<div class="w-12 h-12 rounded-xl bg-gradient-to-br from-teal-500 to-teal-600 flex items-center justify-center shadow-lg">
|
||||
<svg class="w-7 h-7 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-slate-900">바로빌 API 구간별 상세 단가표</h2>
|
||||
<p class="text-sm text-slate-500">전체 구간별 할인 요율 및 계산 예시 · VAT 별도</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pricing Tabs -->
|
||||
<div class="bg-slate-100 p-1 rounded-lg inline-flex mb-6 gap-1 flex-wrap border border-slate-200">
|
||||
<button onclick="showPricingTab('all')" id="tab-pricing-all" class="pricing-tab-btn px-4 py-2 rounded-md text-sm font-medium transition-all pricing-tab-active">전체 보기</button>
|
||||
<button onclick="showPricingTab('tax')" id="tab-pricing-tax" class="pricing-tab-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-slate-600 hover:text-slate-900">전자세금계산서</button>
|
||||
<button onclick="showPricingTab('account')" id="tab-pricing-account" class="pricing-tab-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-slate-600 hover:text-slate-900">계좌조회</button>
|
||||
<button onclick="showPricingTab('card')" id="tab-pricing-card" class="pricing-tab-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-slate-600 hover:text-slate-900">카드</button>
|
||||
<button onclick="showPricingTab('hometax')" id="tab-pricing-hometax" class="pricing-tab-btn px-4 py-2 rounded-md text-sm font-medium transition-all text-slate-600 hover:text-slate-900">홈택스</button>
|
||||
</div>
|
||||
|
||||
<!-- Card: Tax -->
|
||||
<div class="pricing-card mb-6" id="card-pricing-tax">
|
||||
<div class="p-6 border-b border-slate-100">
|
||||
<div class="flex items-center justify-between flex-wrap gap-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-12 h-12 rounded-xl bg-emerald-100 flex items-center justify-center">
|
||||
<svg class="w-6 h-6 text-emerald-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-slate-900">전자세금계산서</h2>
|
||||
<p class="text-sm text-slate-500">발급 건당 과금 · 6개 구간</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="pricing-badge bg-emerald-100 text-emerald-700 text-sm px-3 py-1">건당 50~100원</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6 border-b border-slate-100">
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-4 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"></path></svg>
|
||||
구간별 기본 단가
|
||||
</h3>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="pricing-table-header">
|
||||
<th class="text-left py-3 px-4 rounded-l-lg font-medium text-slate-600">구간</th>
|
||||
<th class="text-left py-3 px-4 font-medium text-slate-600">발급건수</th>
|
||||
<th class="text-right py-3 px-4 rounded-r-lg font-medium text-slate-600">단가</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="pricing-tier-row border-b border-slate-50">
|
||||
<td class="py-3 px-4"><span class="pricing-badge bg-slate-100 text-slate-700">기본</span></td>
|
||||
<td class="py-3 px-4 text-slate-600">3,000건 이하</td>
|
||||
<td class="py-3 px-4 text-right font-semibold text-slate-900">100원</td>
|
||||
</tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50">
|
||||
<td class="py-3 px-4"><span class="pricing-badge bg-teal-50 text-teal-700">1구간</span></td>
|
||||
<td class="py-3 px-4 text-slate-600">3,001 ~ 4,000</td>
|
||||
<td class="py-3 px-4 text-right font-semibold text-slate-900">90원</td>
|
||||
</tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50">
|
||||
<td class="py-3 px-4"><span class="pricing-badge bg-teal-50 text-teal-700">2구간</span></td>
|
||||
<td class="py-3 px-4 text-slate-600">4,001 ~ 5,000</td>
|
||||
<td class="py-3 px-4 text-right font-semibold text-slate-900">80원</td>
|
||||
</tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50">
|
||||
<td class="py-3 px-4"><span class="pricing-badge bg-teal-50 text-teal-700">3구간</span></td>
|
||||
<td class="py-3 px-4 text-slate-600">5,001 ~ 8,000</td>
|
||||
<td class="py-3 px-4 text-right font-semibold text-slate-900">70원</td>
|
||||
</tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50">
|
||||
<td class="py-3 px-4"><span class="pricing-badge bg-teal-50 text-teal-700">4구간</span></td>
|
||||
<td class="py-3 px-4 text-slate-600">8,001 ~ 10,000</td>
|
||||
<td class="py-3 px-4 text-right font-semibold text-slate-900">60원</td>
|
||||
</tr>
|
||||
<tr class="pricing-tier-row">
|
||||
<td class="py-3 px-4"><span class="pricing-badge bg-purple-50 text-purple-700">5구간</span></td>
|
||||
<td class="py-3 px-4 text-slate-600">10,000건 초과</td>
|
||||
<td class="py-3 px-4 text-right font-semibold text-teal-600">50원</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<button onclick="togglePricingSection('tax-examples')" class="w-full flex items-center justify-between text-left mb-4">
|
||||
<h3 class="text-sm font-semibold text-slate-700 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path></svg>
|
||||
상세 계산 예시 (대표 사례)
|
||||
</h3>
|
||||
<svg id="tax-examples-icon" class="w-5 h-5 text-slate-400 pricing-rotate" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
|
||||
</button>
|
||||
<div id="tax-examples" class="pricing-collapsible open space-y-4">
|
||||
<div class="pricing-example-card rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<span class="font-semibold text-slate-900 text-sm">📊 월 4,000건 발급 시</span>
|
||||
<span class="pricing-badge bg-teal-100 text-teal-700">평균 98원</span>
|
||||
</div>
|
||||
<table class="w-full text-xs">
|
||||
<thead><tr class="text-slate-500"><th class="text-left py-1">구간</th><th class="text-left py-1">수량</th><th class="text-right py-1">단가</th><th class="text-right py-1">금액</th></tr></thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-slate-100"><td class="py-1 text-slate-600">기본 (3,000)</td><td>3,000</td><td class="text-right">100원</td><td class="text-right">300,000</td></tr>
|
||||
<tr class="border-b border-slate-100"><td class="py-1 text-slate-600">1구간 (1,000)</td><td>1,000</td><td class="text-right">90원</td><td class="text-right">90,000</td></tr>
|
||||
</tbody>
|
||||
<tfoot><tr class="pricing-summary-row font-bold"><td colspan="3" class="py-2 text-slate-800">계</td><td class="text-right text-teal-600">390,000원</td></tr></tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card: Account -->
|
||||
<div class="pricing-card mb-6" id="card-pricing-account">
|
||||
<div class="p-6 border-b border-slate-100">
|
||||
<div class="flex items-center justify-between flex-wrap gap-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-12 h-12 rounded-xl bg-blue-100 flex items-center justify-center">
|
||||
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-slate-900">계좌조회 (10분주기)</h2>
|
||||
<p class="text-sm text-slate-500">등록 건당 과금 · 5개 구간</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="pricing-badge bg-blue-100 text-blue-700 text-sm px-3 py-1">건당 3,000~6,000원</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-4 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"></path></svg>
|
||||
구간별 기본 단가
|
||||
</h3>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="pricing-table-header">
|
||||
<th class="text-left py-3 px-4 rounded-l-lg font-medium text-slate-600">구간</th>
|
||||
<th class="text-left py-3 px-4 font-medium text-slate-600">등록수</th>
|
||||
<th class="text-right py-3 px-4 rounded-r-lg font-medium text-slate-600">단가</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>기본 (1~50)</td><td>50개</td><td class="text-right font-semibold">6,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>1구간 (51~100)</td><td>50개</td><td class="text-right font-semibold">5,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>2구간 (101~500)</td><td>400개</td><td class="text-right font-semibold">4,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>3구간 (501~1,000)</td><td>500개</td><td class="text-right font-semibold">3,500원</td></tr>
|
||||
<tr class="pricing-tier-row"><td>4구간 (1,000 초과)</td><td>-</td><td class="text-right font-semibold text-teal-600">3,000원</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card: Card -->
|
||||
<div class="pricing-card mb-6" id="card-pricing-card">
|
||||
<div class="p-6 border-b border-slate-100">
|
||||
<div class="flex items-center justify-between flex-wrap gap-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-12 h-12 rounded-xl bg-orange-100 flex items-center justify-center">
|
||||
<svg class="w-6 h-6 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-slate-900">법인/개인카드 조회</h2>
|
||||
<p class="text-sm text-slate-500">등록 건당 과금 · 5개 구간</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="pricing-badge bg-orange-100 text-orange-700 text-sm px-3 py-1">건당 1,700~3,000원</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-4 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"></path></svg>
|
||||
구간별 기본 단가
|
||||
</h3>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="pricing-table-header">
|
||||
<th class="text-left py-3 px-4 rounded-l-lg font-medium text-slate-600">구간</th>
|
||||
<th class="text-left py-3 px-4 font-medium text-slate-600">등록수</th>
|
||||
<th class="text-right py-3 px-4 rounded-r-lg font-medium text-slate-600">단가</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>기본 (1~50)</td><td>50개</td><td class="text-right font-semibold">3,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>1구간 (51~100)</td><td>50개</td><td class="text-right font-semibold">2,500원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>2구간 (101~500)</td><td>400개</td><td class="text-right font-semibold">2,300원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>3구간 (501~1,000)</td><td>500개</td><td class="text-right font-semibold">1,900원</td></tr>
|
||||
<tr class="pricing-tier-row"><td>4구간 (1,000 초과)</td><td>-</td><td class="text-right font-semibold text-teal-600">1,700원</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card: Hometax -->
|
||||
<div class="pricing-card mb-6" id="card-pricing-hometax">
|
||||
<div class="p-6 border-b border-slate-100">
|
||||
<div class="flex items-center justify-between flex-wrap gap-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-12 h-12 rounded-xl bg-violet-100 flex items-center justify-center">
|
||||
<svg class="w-6 h-6 text-violet-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-xl font-bold text-slate-900">홈택스 매입/매출 조회</h2>
|
||||
<p class="text-sm text-slate-500">개사당 월정액 · 6개 구간</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="pricing-badge bg-violet-100 text-violet-700 text-sm px-3 py-1">월 10,000~30,000원</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-4 flex items-center gap-2">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16"></path></svg>
|
||||
구간별 기본 단가
|
||||
</h3>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="pricing-table-header">
|
||||
<th class="text-left py-3 px-4 rounded-l-lg font-medium text-slate-600">구간</th>
|
||||
<th class="text-left py-3 px-4 font-medium text-slate-600">개사수</th>
|
||||
<th class="text-right py-3 px-4 rounded-r-lg font-medium text-slate-600">단가</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>기본 (1~20)</td><td>20개사</td><td class="text-right font-semibold">30,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>1구간 (21~50)</td><td>30개사</td><td class="text-right font-semibold">20,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>2구간 (51~100)</td><td>50개사</td><td class="text-right font-semibold">18,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>3구간 (101~200)</td><td>100개사</td><td class="text-right font-semibold">15,000원</td></tr>
|
||||
<tr class="pricing-tier-row border-b border-slate-50"><td>4구간 (201~500)</td><td>300개사</td><td class="text-right font-semibold">12,000원</td></tr>
|
||||
<tr class="pricing-tier-row"><td>5구간 (500 초과)</td><td>-</td><td class="text-right font-semibold text-teal-600">10,000원</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Summary Table -->
|
||||
<div class="pricing-card mt-8" id="pricing-summary-section">
|
||||
<div class="p-6 border-b border-slate-100">
|
||||
<h3 class="text-lg font-bold text-slate-900 flex items-center gap-2">
|
||||
<svg class="w-5 h-5 text-teal-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"></path>
|
||||
</svg>
|
||||
서비스별 할인 요율 요약
|
||||
</h3>
|
||||
<p class="text-sm text-slate-500 mt-1">대량 사용 시 최대 할인폭 비교</p>
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div class="bg-emerald-50 rounded-lg p-4 text-center border border-emerald-100">
|
||||
<div class="text-xs text-emerald-600 font-medium mb-1">전자세금계산서</div>
|
||||
<div class="text-2xl font-bold text-emerald-700">50% <span class="text-xs font-normal">OFF</span></div>
|
||||
<div class="text-[10px] text-slate-500 mt-1">100원 → 50원</div>
|
||||
</div>
|
||||
<div class="bg-blue-50 rounded-lg p-4 text-center border border-blue-100">
|
||||
<div class="text-xs text-blue-600 font-medium mb-1">계좌조회</div>
|
||||
<div class="text-2xl font-bold text-blue-700">50% <span class="text-xs font-normal">OFF</span></div>
|
||||
<div class="text-[10px] text-slate-500 mt-1">6,000원 → 3,000원</div>
|
||||
</div>
|
||||
<div class="bg-orange-50 rounded-lg p-4 text-center border border-orange-100">
|
||||
<div class="text-xs text-orange-600 font-medium mb-1">카드조회</div>
|
||||
<div class="text-2xl font-bold text-orange-700">43% <span class="text-xs font-normal">OFF</span></div>
|
||||
<div class="text-[10px] text-slate-500 mt-1">3,000원 → 1,700원</div>
|
||||
</div>
|
||||
<div class="bg-violet-50 rounded-lg p-4 text-center border border-violet-100">
|
||||
<div class="text-xs text-violet-600 font-medium mb-1">홈택스조회</div>
|
||||
<div class="text-2xl font-bold text-violet-700">67% <span class="text-xs font-normal">OFF</span></div>
|
||||
<div class="text-[10px] text-slate-500 mt-1">30,000원 → 10,000원</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Additional Info -->
|
||||
<div class="mt-8 text-center text-xs text-slate-500">
|
||||
<p>위 단가표는 Code Bridge X 파트너 전용 특별 할인 단가입니다.</p>
|
||||
<p class="mt-1">정확한 견적은 사용량 추이에 따라 매달 정산됩니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
@@ -1126,7 +1444,23 @@
|
||||
<!-- ============================================ -->
|
||||
|
||||
<!-- 모달 오버레이 -->
|
||||
<div id="modalOverlay" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center p-4" onclick="closeModal(event)">
|
||||
<div id="modalOverlay" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 hidden flex items-center justify-center p-4 transition-opacity duration-200" onclick="closeModal(event)">
|
||||
|
||||
<!-- 바로빌 API 상세 정보 모달 -->
|
||||
<div id="apiInfoModal" class="modal-content bg-white rounded-2xl shadow-2xl w-full max-w-5xl h-[85vh] flex flex-col overflow-hidden hidden" onclick="event.stopPropagation()">
|
||||
<div class="px-6 py-4 border-b border-teal-100 flex justify-between items-center bg-teal-50/50">
|
||||
<h3 class="text-lg font-bold text-slate-800 flex items-center gap-2">
|
||||
<span class="w-1.5 h-6 bg-teal-500 rounded-full"></span>
|
||||
바로빌 API 상세 정보
|
||||
</h3>
|
||||
<button onclick="closeModal()" class="w-10 h-10 flex items-center justify-center rounded-full text-slate-600 hover:text-slate-900 hover:bg-slate-200 transition-all duration-200 bg-white/50 shadow-sm border border-slate-200">
|
||||
<span class="text-2xl leading-none">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 bg-slate-50 min-h-0">
|
||||
<iframe src="etax/barobill_api_info.php" class="w-full h-full border-none" title="API Information"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 회사 정보 관리 모달 -->
|
||||
<div id="companyModal" class="modal-content bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[90vh] overflow-y-auto hidden" onclick="event.stopPropagation()">
|
||||
@@ -1545,6 +1879,44 @@
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
|
||||
function openApiInfoModal() {
|
||||
openModal('apiInfoModal');
|
||||
}
|
||||
|
||||
// 상세 단가표 제어 함수
|
||||
function showPricingTab(tabId) {
|
||||
document.querySelectorAll('.pricing-tab-btn').forEach(btn => {
|
||||
btn.classList.remove('pricing-tab-active');
|
||||
btn.classList.add('text-slate-600');
|
||||
});
|
||||
|
||||
const activeTab = document.getElementById('tab-pricing-' + tabId);
|
||||
activeTab.classList.add('pricing-tab-active');
|
||||
activeTab.classList.remove('text-slate-600');
|
||||
|
||||
const cards = ['tax', 'account', 'card', 'hometax'];
|
||||
const summarySection = document.getElementById('pricing-summary-section');
|
||||
|
||||
if (tabId === 'all') {
|
||||
cards.forEach(card => {
|
||||
document.getElementById('card-pricing-' + card).style.display = 'block';
|
||||
});
|
||||
summarySection.style.display = 'block';
|
||||
} else {
|
||||
cards.forEach(card => {
|
||||
document.getElementById('card-pricing-' + card).style.display = (card === tabId) ? 'block' : 'none';
|
||||
});
|
||||
summarySection.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function togglePricingSection(sectionId) {
|
||||
const section = document.getElementById(sectionId);
|
||||
const icon = document.getElementById(sectionId + '-icon');
|
||||
section.classList.toggle('open');
|
||||
icon.classList.toggle('open');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,10 +3,10 @@ header('Content-Type: application/json');
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
try {
|
||||
if (!file_exists("../lib/mydb.php")) {
|
||||
throw new Exception("Required library file ../lib/mydb.php not found.");
|
||||
if (!file_exists("../../lib/mydb.php")) {
|
||||
throw new Exception("Required library file ../../lib/mydb.php not found.");
|
||||
}
|
||||
require_once("../lib/mydb.php");
|
||||
require_once("../../lib/mydb.php");
|
||||
|
||||
$pdo = db_connect();
|
||||
|
||||
@@ -47,42 +47,48 @@
|
||||
|
||||
// --- Layout Components ---
|
||||
|
||||
const Header = () => (
|
||||
<header className="bg-white border-b border-gray-100 sticky top-0 z-50">
|
||||
<div className="max-w-7xl mx-auto px-4 lg:px-8 h-16 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white">
|
||||
const Header = ({ onOpenApiInfo }) => (
|
||||
<header className="bg-white/80 backdrop-blur-md border-b border-blue-100/50 sticky top-0 z-50 transition-all shadow-sm">
|
||||
<div className="max-w-7xl mx-auto px-4 lg:px-8 h-18 flex items-center justify-between py-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-xl flex items-center justify-center text-white shadow-lg shadow-blue-200/50 ring-4 ring-blue-50">
|
||||
<i data-lucide="users" className="w-5 h-5"></i>
|
||||
</div>
|
||||
<h1 className="text-lg font-semibold text-slate-900">바로빌 회원관리 솔루션</h1>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-slate-900 tracking-tight leading-none">바로빌 회원관리</h1>
|
||||
<p className="text-[10px] text-blue-600 font-semibold mt-1 uppercase tracking-wider opacity-70">Barobill Member Management</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 text-sm text-slate-500 font-medium">
|
||||
<a href="../eaccount/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="wallet" className="w-4 h-4 text-blue-500"></i> 계좌조회
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 text-sm text-slate-500 font-medium">
|
||||
<div className="flex bg-slate-100/50 p-1 rounded-xl border border-slate-200/50 mr-2">
|
||||
<a href="../eaccount/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="wallet" className="w-4 h-4 text-blue-500"></i> <span>계좌조회</span>
|
||||
</a>
|
||||
<a href="../ecard/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="credit-card" className="w-4 h-4 text-purple-500"></i> 카드내역
|
||||
<a href="../ecard/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="credit-card" className="w-4 h-4 text-purple-500"></i> <span>카드내역</span>
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="building" className="w-4 h-4 text-teal-500"></i> 테넌트관리
|
||||
<a href="../tenant/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="building" className="w-4 h-4 text-teal-500"></i> <span>테넌트</span>
|
||||
</a>
|
||||
<a href="../barobill_registration/index.php" className="text-blue-600 flex items-center gap-1 bg-blue-50 px-3 py-1.5 rounded-lg border border-blue-100 cursor-default font-bold">
|
||||
<i data-lucide="users" className="w-4 h-4 text-blue-600"></i> 회원관리
|
||||
</a>
|
||||
<a href="../etax/barobill_api_info.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="book-open" className="w-4 h-4 text-orange-500"></i> API정보
|
||||
<a href="index.php" className="flex items-center gap-4 px-4 py-2 rounded-lg bg-white text-blue-600 shadow-sm border border-blue-100 font-bold transition-all">
|
||||
<i data-lucide="users" className="w-4 h-4 text-blue-600"></i> <span>바로빌 회원관리</span>
|
||||
</a>
|
||||
<button onClick={(e) => { e.preventDefault(); onOpenApiInfo(); }} className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="book-open" className="w-4 h-4 text-orange-500"></i> <span>API정보</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-2"></div>
|
||||
|
||||
<a href="../barobill/index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<i data-lucide="layout-dashboard" className="w-4 h-4"></i> 현황
|
||||
<a href="../index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<i data-lucide="layout-dashboard" className="w-4 h-4"></i> <span className="hidden lg:inline text-xs">현황</span>
|
||||
</a>
|
||||
<a href="../etax/index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<i data-lucide="file-text" className="w-4 h-4"></i> 세금계산서
|
||||
<a href="../etax/index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<i data-lucide="file-text" className="w-4 h-4"></i> <span className="hidden lg:inline text-xs">세금계산서</span>
|
||||
</a>
|
||||
<a href="../index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<i data-lucide="home" className="w-4 h-4"></i> 홈
|
||||
<a href="../../index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<i data-lucide="home" className="w-4 h-4"></i> <span className="hidden lg:inline text-xs">홈</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -191,21 +197,40 @@
|
||||
);
|
||||
};
|
||||
|
||||
const Modal = ({ isOpen, onClose, title, children }) => {
|
||||
const Modal = ({ isOpen, onClose, title, children, maxWidth = "max-w-2xl" }) => {
|
||||
if (!isOpen) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm">
|
||||
<div className="bg-white rounded-2xl w-full max-w-2xl overflow-hidden shadow-2xl">
|
||||
<div className="p-4 border-b border-slate-100 flex justify-between items-center">
|
||||
<h3 className="font-bold text-slate-800">{title}</h3>
|
||||
<button onClick={onClose} className="p-2 text-slate-400 hover:text-slate-600"><i data-lucide="x" className="w-5 h-5"></i></button>
|
||||
<div className={`bg-white rounded-2xl w-full ${maxWidth} overflow-hidden shadow-2xl animate-in fade-in zoom-in-95 duration-200`}>
|
||||
<div className="p-4 border-b border-slate-100 flex justify-between items-center bg-slate-50/50">
|
||||
<h3 className="font-bold text-slate-800 flex items-center gap-2">
|
||||
<span className="w-1.5 h-6 bg-blue-500 rounded-full"></span>
|
||||
{title}
|
||||
</h3>
|
||||
<button onClick={onClose} className="w-10 h-10 flex items-center justify-center rounded-full text-slate-600 hover:text-slate-900 hover:bg-slate-200 transition-all duration-200 bg-white/50 shadow-sm border border-slate-200">
|
||||
<i data-lucide="x" className="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-6 overflow-y-auto max-h-[80vh]">{children}</div>
|
||||
<div className="p-0 overflow-y-auto max-h-[85vh]">{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ApiInfoModal = ({ isOpen, onClose }) => {
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose} title="바로빌 API 상세 정보" maxWidth="max-w-5xl">
|
||||
<div className="relative w-full h-[700px] bg-slate-50">
|
||||
<iframe
|
||||
src="../etax/barobill_api_info.php"
|
||||
className="w-full h-full border-none"
|
||||
title="API Information"
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
// --- Main App ---
|
||||
|
||||
const App = () => {
|
||||
@@ -213,6 +238,7 @@
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [activeTab, setActiveTab] = useState('list');
|
||||
const [editingMember, setEditingMember] = useState(null);
|
||||
const [isApiInfoModalOpen, setIsApiInfoModalOpen] = useState(false);
|
||||
|
||||
// Auto-fill feature states
|
||||
const [registerKey, setRegisterKey] = useState(0);
|
||||
@@ -246,7 +272,7 @@
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => lucide.createIcons(), 100);
|
||||
}, [activeTab, members, editingMember]);
|
||||
}, [activeTab, members, editingMember, isApiInfoModalOpen]);
|
||||
|
||||
const handleRegister = async (data) => {
|
||||
try {
|
||||
@@ -300,7 +326,7 @@
|
||||
|
||||
return (
|
||||
<div className="min-h-screen">
|
||||
<Header />
|
||||
<Header onOpenApiInfo={() => setIsApiInfoModalOpen(true)} />
|
||||
|
||||
<main className="max-w-7xl mx-auto px-4 lg:px-8 py-8">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
|
||||
@@ -422,6 +448,11 @@
|
||||
onCancel={() => setEditingMember(null)}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<ApiInfoModal
|
||||
isOpen={isApiInfoModalOpen}
|
||||
onClose={() => setIsApiInfoModalOpen(false)}
|
||||
/>
|
||||
</main>
|
||||
|
||||
<footer className="mt-20 py-8 border-t border-slate-100 text-center">
|
||||
@@ -1,9 +1,9 @@
|
||||
<?php
|
||||
try {
|
||||
if (!file_exists("../lib/mydb.php")) {
|
||||
throw new Exception("Required library file ../lib/mydb.php not found.");
|
||||
if (!file_exists("../../lib/mydb.php")) {
|
||||
throw new Exception("Required library file ../../lib/mydb.php not found.");
|
||||
}
|
||||
require_once("../lib/mydb.php");
|
||||
require_once("../../lib/mydb.php");
|
||||
|
||||
$pdo = db_connect();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
include '../lib/mydb.php';
|
||||
include '../../lib/mydb.php';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
@@ -68,39 +68,45 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
const { useState, useEffect, useRef } = React;
|
||||
|
||||
// --- Header Component ---
|
||||
const Header = () => (
|
||||
<header className="bg-white border-b border-gray-100 sticky top-0 z-50 transition-all">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white shadow-sm">
|
||||
const Header = ({ onOpenApiInfo }) => (
|
||||
<header className="bg-white/80 backdrop-blur-md border-b border-blue-100/50 sticky top-0 z-50 transition-all shadow-sm">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-18 flex items-center justify-between py-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-600 to-indigo-700 rounded-xl flex items-center justify-center text-white shadow-lg shadow-blue-200/50 ring-4 ring-blue-50">
|
||||
<i data-lucide="building" className="w-5 h-5"></i>
|
||||
</div>
|
||||
<h1 className="text-lg font-semibold text-slate-900">바로빌 테넌트 관리</h1>
|
||||
<div>
|
||||
<h1 className="text-lg font-bold text-slate-900 tracking-tight leading-none">테넌트 관리</h1>
|
||||
<p className="text-[10px] text-blue-600 font-semibold mt-1 uppercase tracking-wider opacity-70">Tenant Configuration</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4 text-sm text-slate-500 font-medium">
|
||||
<a href="../eaccount/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="wallet" className="w-4 h-4 text-blue-500"></i> 계좌조회
|
||||
</a>
|
||||
<a href="../ecard/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="credit-card" className="w-4 h-4 text-purple-500"></i> 카드내역
|
||||
</a>
|
||||
<a href="../tenant/index.php" className="text-blue-600 flex items-center gap-1 bg-blue-50 px-3 py-1.5 rounded-lg border border-blue-100 cursor-default font-bold">
|
||||
<i data-lucide="building" className="w-4 h-4 text-blue-600"></i> 테넌트관리
|
||||
</a>
|
||||
<a href="../barobill_registration/index.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="users" className="w-4 h-4 text-teal-500"></i> 회원관리
|
||||
</a>
|
||||
<a href="../etax/barobill_api_info.php" className="hover:text-blue-600 flex items-center gap-1 bg-slate-50 hover:bg-slate-100 px-3 py-1.5 rounded-lg transition-colors border border-slate-100">
|
||||
<i data-lucide="book-open" className="w-4 h-4 text-orange-500"></i> API정보
|
||||
</a>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-1"></div>
|
||||
|
||||
<a href="../etax/index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<i data-lucide="file-text" className="w-4 h-4"></i> 세금계산서
|
||||
<div className="flex items-center gap-2 text-sm text-slate-500 font-medium">
|
||||
<div className="flex bg-slate-100/50 p-1 rounded-xl border border-slate-200/50 mr-2">
|
||||
<a href="../eaccount/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="wallet" className="w-4 h-4 text-blue-500"></i> <span>계좌조회</span>
|
||||
</a>
|
||||
<a href="../index.php" className="hover:text-blue-700 flex items-center gap-1">
|
||||
<i data-lucide="home" className="w-4 h-4"></i> 홈
|
||||
<a href="../ecard/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="credit-card" className="w-4 h-4 text-purple-500"></i> <span>카드내역</span>
|
||||
</a>
|
||||
<a href="index.php" className="flex items-center gap-2 px-4 py-2 rounded-lg bg-white text-blue-600 shadow-sm border border-blue-100 font-bold">
|
||||
<i data-lucide="building" className="w-4 h-4 text-blue-600"></i> <span>테넌트</span>
|
||||
</a>
|
||||
<a href="../registration/index.php" className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="users" className="w-4 h-4 text-teal-500"></i> <span>바로빌 회원관리</span>
|
||||
</a>
|
||||
<button onClick={(e) => { e.preventDefault(); onOpenApiInfo(); }} className="flex items-center gap-2 px-3 py-2 rounded-lg hover:text-blue-600 hover:bg-white transition-all duration-200">
|
||||
<i data-lucide="book-open" className="w-4 h-4 text-orange-500"></i> <span>API정보</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="h-4 w-px bg-slate-200 mx-2"></div>
|
||||
|
||||
<a href="../etax/index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<i data-lucide="file-text" className="w-4 h-4"></i> <span className="hidden lg:inline text-xs">세금계산서</span>
|
||||
</a>
|
||||
<a href="../../index.php" className="flex items-center gap-1.5 px-3 py-2 text-slate-400 hover:text-blue-600 transition-colors">
|
||||
<i data-lucide="home" className="w-4 h-4"></i> <span className="hidden lg:inline text-xs">홈</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -138,6 +144,7 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
const [isAccountModalOpen, setIsAccountModalOpen] = useState(false);
|
||||
const [selectedCompanyForAccounts, setSelectedCompanyForAccounts] = useState(null);
|
||||
const [isApiInfoModalOpen, setIsApiInfoModalOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchCompanies();
|
||||
@@ -146,7 +153,7 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
useEffect(() => {
|
||||
lucide.createIcons();
|
||||
}, [companies, isCompanyModalOpen, isCardModalOpen, isAccountModalOpen]);
|
||||
}, [companies, isCompanyModalOpen, isCardModalOpen, isAccountModalOpen, isApiInfoModalOpen]);
|
||||
|
||||
const fetchCompanies = async () => {
|
||||
try {
|
||||
@@ -167,7 +174,7 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full bg-gray-50">
|
||||
<Header />
|
||||
<Header onOpenApiInfo={() => setIsApiInfoModalOpen(true)} />
|
||||
|
||||
<main className="flex-1 overflow-auto p-4 sm:p-6 lg:p-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
@@ -269,6 +276,11 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
company={selectedCompanyForAccounts}
|
||||
/>}
|
||||
|
||||
<ApiInfoModal
|
||||
isOpen={isApiInfoModalOpen}
|
||||
onClose={() => setIsApiInfoModalOpen(false)}
|
||||
/>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -500,6 +512,32 @@ require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
);
|
||||
};
|
||||
|
||||
const ApiInfoModal = ({ isOpen, onClose }) => {
|
||||
if (!isOpen) return null;
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/40 backdrop-blur-sm">
|
||||
<div className="bg-white rounded-2xl w-full max-w-5xl overflow-hidden shadow-2xl animate-in fade-in zoom-in-95 duration-200">
|
||||
<div className="p-4 border-b border-slate-100 flex justify-between items-center bg-slate-50/50">
|
||||
<h3 className="font-bold text-slate-800 flex items-center gap-2">
|
||||
<span className="w-1.5 h-6 bg-blue-500 rounded-full"></span>
|
||||
바로빌 API 상세 정보
|
||||
</h3>
|
||||
<button onClick={onClose} className="w-10 h-10 flex items-center justify-center rounded-full text-slate-600 hover:text-slate-900 hover:bg-slate-200 transition-all duration-200 bg-white/50 shadow-sm border border-slate-200">
|
||||
<i data-lucide="x" className="w-6 h-6"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div className="relative w-full h-[700px] bg-slate-50">
|
||||
<iframe
|
||||
src="../etax/barobill_api_info.php"
|
||||
className="w-full h-full border-none"
|
||||
title="API Information"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(<App />);
|
||||
</script>
|
||||
148
company/index.php
Normal file
148
company/index.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>기업 분석 리스트 | SAM Sales</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body { font-family: 'Inter', 'Noto Sans KR', sans-serif; }
|
||||
.glass-card {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(226, 232, 240, 0.8);
|
||||
}
|
||||
.shard-glow:hover {
|
||||
box-shadow: 0 0 20px rgba(59, 130, 246, 0.1);
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-slate-50 min-h-screen">
|
||||
<!-- Navigation -->
|
||||
<nav class="sticky top-0 z-40 w-full border-b bg-white/80 backdrop-blur-md">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex h-16 items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="bg-blue-600 p-1.5 rounded-lg shadow-sm">
|
||||
<i data-lucide="layout-dashboard" class="text-white w-5 h-5"></i>
|
||||
</div>
|
||||
<span class="font-bold text-slate-900 tracking-tight">SAM Corporate Analysis</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="../index.php" class="text-sm font-medium text-slate-500 hover:text-slate-900 transition-colors">홈으로</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
|
||||
<!-- Hero Section -->
|
||||
<div class="mb-12">
|
||||
<h1 class="text-3xl font-bold tracking-tight text-slate-900 mb-2">기업 분석 라이브러리</h1>
|
||||
<p class="text-slate-500 max-w-2xl">
|
||||
다양한 산업군의 주요 기업들에 대한 심층적인 재무, 성장, 경쟁 분석 리포트를 확인하고 비즈니스 인사이트를 얻으세요.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Grid -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
|
||||
<!-- Loudsourcing Card -->
|
||||
<a href="loudsourcing/index.php" class="group">
|
||||
<div class="bg-white rounded-xl border border-slate-200 p-6 flex flex-col h-full transition-all duration-300 hover:shadow-lg hover:border-blue-200 shard-glow relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 w-24 h-24 bg-blue-50 -mr-12 -mt-12 rounded-full transition-transform group-hover:scale-110"></div>
|
||||
|
||||
<div class="mb-4 flex items-center justify-between relative">
|
||||
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600">
|
||||
<i data-lucide="palette" class="w-6 h-6"></i>
|
||||
</div>
|
||||
<span class="inline-flex items-center rounded-full bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">IT/디자인</span>
|
||||
</div>
|
||||
|
||||
<h3 class="text-xl font-bold text-slate-900 mb-2">라우드소싱 (LOUDSOURCING)</h3>
|
||||
<p class="text-slate-500 text-sm mb-6 flex-grow">
|
||||
국내 최대 디자인 크라우드소싱 플랫폼. 디자이너와 기업을 연결하는 혁신적인 콘테스트 기반 비즈니스 모델.
|
||||
</p>
|
||||
|
||||
<div class="flex items-center text-blue-600 text-sm font-semibold mt-auto">
|
||||
분석 리포트 보기
|
||||
<i data-lucide="arrow-right" class="w-4 h-4 ml-1 transition-transform group-hover:translate-x-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- PeopleLife Card -->
|
||||
<a href="peoplelife/index.php" class="group">
|
||||
<div class="bg-white rounded-xl border border-slate-200 p-6 flex flex-col h-full transition-all duration-300 hover:shadow-lg hover:border-blue-200 shard-glow relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 w-24 h-24 bg-indigo-50 -mr-12 -mt-12 rounded-full transition-transform group-hover:scale-110"></div>
|
||||
|
||||
<div class="mb-4 flex items-center justify-between relative">
|
||||
<div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center text-indigo-600">
|
||||
<i data-lucide="shield-check" class="w-6 h-6"></i>
|
||||
</div>
|
||||
<span class="inline-flex items-center rounded-full bg-indigo-50 px-2 py-1 text-xs font-medium text-indigo-700 ring-1 ring-inset ring-indigo-700/10">금융/GA</span>
|
||||
</div>
|
||||
|
||||
<h3 class="text-xl font-bold text-slate-900 mb-2">피플라이프 (PeopleLife)</h3>
|
||||
<p class="text-slate-500 text-sm mb-6 flex-grow">
|
||||
대한민국 대표 초대형 GA. 법인 컨설팅의 전문성을 바탕으로 O2O 플랫폼 보험클리닉을 운영하는 보험 금융 그룹.
|
||||
</p>
|
||||
|
||||
<div class="flex items-center text-indigo-600 text-sm font-semibold mt-auto">
|
||||
분석 리포트 보기
|
||||
<i data-lucide="arrow-right" class="w-4 h-4 ml-1 transition-transform group-hover:translate-x-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Looka vs Brandmark Card -->
|
||||
<a href="looka/index.php" class="group">
|
||||
<div class="bg-white rounded-xl border border-slate-200 p-6 flex flex-col h-full transition-all duration-300 hover:shadow-lg hover:border-blue-200 shard-glow relative overflow-hidden">
|
||||
<div class="absolute top-0 right-0 w-24 h-24 bg-purple-50 -mr-12 -mt-12 rounded-full transition-transform group-hover:scale-110"></div>
|
||||
|
||||
<div class="mb-4 flex items-center justify-between relative">
|
||||
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center text-purple-600">
|
||||
<i data-lucide="sparkles" class="w-6 h-6"></i>
|
||||
</div>
|
||||
<span class="inline-flex items-center rounded-full bg-purple-50 px-2 py-1 text-xs font-medium text-purple-700 ring-1 ring-inset ring-purple-700/10">AI/디자인</span>
|
||||
</div>
|
||||
|
||||
<h3 class="text-xl font-bold text-slate-900 mb-2">Looka vs Brandmark</h3>
|
||||
<p class="text-slate-500 text-sm mb-6 flex-grow">
|
||||
AI 기반 로고 디자인 툴 비교. 비용, 기능, 서비스 규모를 바탕으로 비즈니스에 최적화된 로고 제작 도구를 추천합니다.
|
||||
</p>
|
||||
|
||||
<div class="flex items-center text-purple-600 text-sm font-semibold mt-auto">
|
||||
비교 결과 보기
|
||||
<i data-lucide="arrow-right" class="w-4 h-4 ml-1 transition-transform group-hover:translate-x-1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<!-- Placeholder for future addition -->
|
||||
<div class="bg-white rounded-xl border border-dashed border-slate-300 p-6 flex flex-col items-center justify-center h-full text-slate-400 group">
|
||||
<div class="w-12 h-12 rounded-lg border border-dashed border-slate-300 flex items-center justify-center mb-4 group-hover:bg-slate-50 transition-colors">
|
||||
<i data-lucide="plus" class="w-6 h-6"></i>
|
||||
</div>
|
||||
<p class="text-sm font-medium">새로운 기업 추가 예정</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="border-t bg-white mt-20 py-10">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center text-slate-400 text-sm">
|
||||
<p>© 2026 SAM Corporate Analysis Dashboard. All rights reserved.</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// Initialize Lucide Icons
|
||||
lucide.createIcons();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
266
company/looka/index.php
Normal file
266
company/looka/index.php
Normal file
@@ -0,0 +1,266 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Looka vs Brandmark 비교 분석</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { font-family: 'Noto Sans KR', sans-serif; }
|
||||
.tab-content { display: none; }
|
||||
.tab-content.active { display: block; }
|
||||
.nav-active { background-color: #2563eb; color: white; shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); }
|
||||
.fade-in { animation: fadeIn 0.5s ease-out forwards; }
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-screen bg-gradient-to-br from-slate-50 to-indigo-50 p-6">
|
||||
<div class="max-w-5xl mx-auto">
|
||||
<!-- Header -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-8 mb-6 fade-in">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="w-16 h-16 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-xl flex items-center justify-center">
|
||||
<i data-lucide="sparkles" class="text-white w-8 h-8"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-gray-800">Looka vs Brandmark</h1>
|
||||
<p class="text-gray-500">생성형 AI 기반 로고 디자인 플랫폼 비교 분석</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-gray-600 leading-relaxed">
|
||||
디자인 전문 지식 없이도 고품질 로고와 브랜드 키트를 제작할 수 있는 대표적인 AI 디자인 툴입니다.
|
||||
Looka의 범용성과 Brandmark의 창의성을 중심으로 비즈니스 목적에 맞는 최적의 선택을 제안합니다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Summary Metrics -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
|
||||
<div class="bg-white rounded-xl shadow-md p-5 border-l-4 border-indigo-500 fade-in" style="animation-delay: 0.1s">
|
||||
<div class="flex items-center gap-2 text-indigo-600 mb-2">
|
||||
<i data-lucide="users" size="20"></i>
|
||||
<span class="text-sm font-medium">Looka 인기</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">2,000만+</p>
|
||||
<p class="text-xs text-gray-500">글로벌 압도적 1위</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-md p-5 border-l-4 border-green-500 fade-in" style="animation-delay: 0.2s">
|
||||
<div class="flex items-center gap-2 text-green-600 mb-2">
|
||||
<i data-lucide="dollar-sign" size="20"></i>
|
||||
<span class="text-sm font-medium">최저 비용</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">$20~</p>
|
||||
<p class="text-xs text-gray-500">전문가 외주 대비 저렴</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-md p-5 border-l-4 border-amber-500 fade-in" style="animation-delay: 0.3s">
|
||||
<div class="flex items-center gap-2 text-amber-600 mb-2">
|
||||
<i data-lucide="thumbs-up" size="20"></i>
|
||||
<span class="text-sm font-medium">추천 선택</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">Looka</p>
|
||||
<p class="text-xs text-gray-500">종합 완성도 9/10</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab Navigation -->
|
||||
<div class="flex gap-2 mb-6 overflow-x-auto">
|
||||
<button onclick="showTab('popular')" id="tab-popular" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap nav-active">인기 & 규모</button>
|
||||
<button onclick="showTab('pricing')" id="tab-pricing" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap bg-white text-gray-600 hover:bg-gray-100">가격 비교</button>
|
||||
<button onclick="showTab('strength')" id="tab-strength" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap bg-white text-gray-600 hover:bg-gray-100">강점 & 약점</button>
|
||||
<button onclick="showTab('recommend')" id="tab-recommend" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap bg-white text-gray-600 hover:bg-gray-100">최종 추천</button>
|
||||
</div>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 min-h-[400px]">
|
||||
|
||||
<!-- Popularity Tab -->
|
||||
<div id="popular" class="tab-content active space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="bar-chart-3" class="text-indigo-600" size="24"></i>
|
||||
인기도 및 사용자 규모
|
||||
</h2>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="bg-slate-50 border-b">
|
||||
<th class="p-4 text-left font-semibold text-slate-700">항목</th>
|
||||
<th class="p-4 text-center font-bold text-indigo-600">Looka</th>
|
||||
<th class="p-4 text-center font-semibold text-slate-700">Brandmark</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y">
|
||||
<tr>
|
||||
<td class="p-4 font-medium text-slate-600 text-center">사용자 수</td>
|
||||
<td class="p-4 text-center font-semibold text-slate-900">2,000만명 이상</td>
|
||||
<td class="p-4 text-center text-slate-500">상대적으로 적음</td>
|
||||
</tr>
|
||||
<tr class="bg-slate-50/50">
|
||||
<td class="p-4 font-medium text-slate-600 text-center">Trustpilot 리뷰</td>
|
||||
<td class="p-4 text-center font-semibold text-slate-900">14,352건</td>
|
||||
<td class="p-4 text-center text-slate-500">리뷰 거의 없음</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="p-4 font-medium text-slate-600 text-center">서비스 국가</td>
|
||||
<td class="p-4 text-center font-semibold text-slate-900">188개국</td>
|
||||
<td class="p-4 text-center text-slate-500">-</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="p-4 bg-indigo-50 rounded-xl border border-indigo-100 text-sm text-indigo-800">
|
||||
<i data-lucide="info" class="inline-block w-4 h-4 mr-1 mb-0.5"></i>
|
||||
<strong>결론:</strong> Looka가 압도적으로 더 인기 있고, 검증된 사용자 기반을 가지고 있습니다.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pricing Tab -->
|
||||
<div id="pricing" class="tab-content space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="tags" class="text-green-600" size="24"></i>
|
||||
가격 플랜 비교
|
||||
</h2>
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<div class="bg-white border rounded-xl p-5 hover:border-indigo-300 transition-colors">
|
||||
<h3 class="font-bold text-lg mb-4 text-slate-800">Looka</h3>
|
||||
<ul class="space-y-3">
|
||||
<li class="flex justify-between text-sm"><span>기본 로고 (저해상도 PNG)</span><span class="font-bold">$20</span></li>
|
||||
<li class="flex justify-between text-sm"><span>프리미엄 (고해상도 + 벡터)</span><span class="font-bold">$65</span></li>
|
||||
<li class="flex justify-between text-sm text-slate-500 italic"><span>브랜드 키트 (연간 구독)</span><span class="font-bold">$96~129/년</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-white border rounded-xl p-5 hover:border-indigo-300 transition-colors">
|
||||
<h3 class="font-bold text-lg mb-4 text-slate-800">Brandmark</h3>
|
||||
<ul class="space-y-3">
|
||||
<li class="flex justify-between text-sm"><span>기초 플랜</span><span class="font-bold">$25</span></li>
|
||||
<li class="flex justify-between text-sm"><span>디자이너 플랜 (벡터 포함)</span><span class="font-bold">$65</span></li>
|
||||
<li class="flex justify-between text-sm"><span>엔터프라이즈 플랜</span><span class="font-bold">$175</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 bg-slate-50 rounded-xl text-sm text-slate-600">
|
||||
전문가 평가에 따르면 두 서비스 모두 "심각한 브랜딩을 위해 가장 좋은 가치를 제공"하며, 특히 $65 플랜이 두 서비스 모두에서 가장 권장되는 선택입니다.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Strength Tab -->
|
||||
<div id="strength" class="tab-content space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="award" class="text-amber-600" size="24"></i>
|
||||
강점 및 약점 상세
|
||||
</h2>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<!-- Looka -->
|
||||
<div class="space-y-4">
|
||||
<div class="bg-indigo-50 p-4 rounded-xl border border-indigo-100">
|
||||
<h3 class="font-bold text-indigo-900 mb-2 flex items-center gap-2"><i data-lucide="check-circle" size="18"></i> Looka 강점</h3>
|
||||
<ul class="text-sm text-indigo-800 space-y-1">
|
||||
<li>• 압도적으로 쉬운 인터페이스 (초보자용)</li>
|
||||
<li>• 빠르고 친절한 고객 지원 (주말 응대)</li>
|
||||
<li>• 종합 브랜드 패키지 (명함, SNS 에셋 등)</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-rose-50 p-4 rounded-xl border border-rose-100">
|
||||
<h3 class="font-bold text-rose-900 mb-2 flex items-center gap-2"><i data-lucide="alert-circle" size="18"></i> Looka 약점</h3>
|
||||
<ul class="text-sm text-rose-800 space-y-1">
|
||||
<li>• 기본 패키지가 다소 빈약 (저해상도)</li>
|
||||
<li>• 커스터마이징의 세부 조정 한계</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Brandmark -->
|
||||
<div class="space-y-4">
|
||||
<div class="bg-emerald-50 p-4 rounded-xl border border-emerald-100">
|
||||
<h3 class="font-bold text-emerald-900 mb-2 flex items-center gap-2"><i data-lucide="check-circle" size="18"></i> Brandmark 강점</h3>
|
||||
<ul class="text-sm text-emerald-800 space-y-1">
|
||||
<li>• 1회 결제 로직과 무제한 수정</li>
|
||||
<li>• 더 독창적인 생성형 AI 엔진</li>
|
||||
<li>• 미니멀하고 모던한 미학 특화</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-amber-50 p-4 rounded-xl border border-amber-100">
|
||||
<h3 class="font-bold text-amber-900 mb-2 flex items-center gap-2"><i data-lucide="alert-circle" size="18"></i> Brandmark 약점</h3>
|
||||
<ul class="text-sm text-amber-800 space-y-1">
|
||||
<li>• 결과물이 때때로 지나치게 단순함</li>
|
||||
<li>• Looka 대비 제한적인 브랜드 킷</li>
|
||||
<li>• 시각적 감각이 부족하다는 평가 존재</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recommend Tab -->
|
||||
<div id="recommend" class="tab-content space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="check-square" class="text-blue-600" size="24"></i>
|
||||
상황별 최종 추천
|
||||
</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<div class="p-5 bg-gradient-to-br from-indigo-50 to-white border border-indigo-200 rounded-2xl shadow-sm">
|
||||
<h3 class="text-lg font-bold text-indigo-900 mb-3">✅ Looka를 추천하는 경우</h3>
|
||||
<ul class="text-sm text-indigo-700 space-y-2">
|
||||
<li class="flex items-start gap-2"><i data-lucide="arrow-right-circle" class="w-4 h-4 mt-0.5 flex-shrink-0"></i> 기업용 종합 마케팅 자료가 필요한 경우</li>
|
||||
<li class="flex items-start gap-2"><i data-lucide="arrow-right-circle" class="w-4 h-4 mt-0.5 flex-shrink-0"></i> 검증된 서비스와 안정적인 지원을 선호하는 경우</li>
|
||||
<li class="flex items-start gap-2"><i data-lucide="arrow-right-circle" class="w-4 h-4 mt-0.5 flex-shrink-0"></i> 디자인 경험이 전무하여 최고의 UI를 원하는 경우</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="p-5 bg-gradient-to-br from-indigo-50 to-white border border-indigo-200 rounded-2xl shadow-sm">
|
||||
<h3 class="text-lg font-bold text-indigo-900 mb-3">✅ Brandmark를 추천하는 경우</h3>
|
||||
<ul class="text-sm text-indigo-700 space-y-2">
|
||||
<li class="flex items-start gap-2"><i data-lucide="arrow-right-circle" class="w-4 h-4 mt-0.5 flex-shrink-0"></i> 1회성 결제로 평생 수정을 원하는 경우</li>
|
||||
<li class="flex items-start gap-2"><i data-lucide="arrow-right-circle" class="w-4 h-4 mt-0.5 flex-shrink-0"></i> 더욱 독창적이고 미니멀한 로고를 찾는 경우</li>
|
||||
<li class="flex items-start gap-2"><i data-lucide="arrow-right-circle" class="w-4 h-4 mt-0.5 flex-shrink-0"></i> 예산이 극도로 제한적인 경우 ($25 플랜)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 bg-slate-900 rounded-2xl p-6 text-white text-center">
|
||||
<h3 class="text-xl font-bold mb-3 flex items-center justify-center gap-2">
|
||||
<i data-lucide="lightbulb" class="text-amber-400"></i>
|
||||
Antigravity의 한 마디
|
||||
</h3>
|
||||
<p class="text-indigo-100 text-sm leading-relaxed max-w-2xl mx-auto">
|
||||
"먼저 **Looka**에서 무료로 로고를 생성해 보세요. 다운로드 전까지는 비용이 들지 않으므로 시안의 품질을 직접 확인할 수 있습니다.
|
||||
폰트나 컬러 조합이 마음에 든다면 $20 기본 패키지로 방향성을 잡고, 필요 시 프리미엄으로 업그레이드하는 전략이 가장 효율적입니다."
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-6 text-center text-sm text-gray-500">
|
||||
<p>데이터 출처: Fahimai, Trustpilot, 공식 홈페이지 등</p>
|
||||
<p>분석 기준일: 2026년 1월</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Lucide 아이콘 렌더링
|
||||
lucide.createIcons();
|
||||
|
||||
// 탭 전환 기능
|
||||
function showTab(tabId) {
|
||||
// 모든 탭 컨텐츠 숨기기
|
||||
document.querySelectorAll('.tab-content').forEach(tab => {
|
||||
tab.classList.remove('active');
|
||||
});
|
||||
// 선택된 탭 컨텐츠 보이기
|
||||
document.getElementById(tabId).classList.add('active');
|
||||
|
||||
// 탭 버튼 스타일 업데이트
|
||||
document.querySelectorAll('.tab-btn').forEach(btn => {
|
||||
btn.classList.remove('nav-active');
|
||||
btn.classList.add('bg-white', 'text-gray-600', 'hover:bg-gray-100');
|
||||
});
|
||||
const activeBtn = document.getElementById('tab-' + tabId);
|
||||
activeBtn.classList.add('nav-active');
|
||||
activeBtn.classList.remove('bg-white', 'text-gray-600', 'hover:bg-gray-100');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
426
company/loudsourcing/index.php
Normal file
426
company/loudsourcing/index.php
Normal file
@@ -0,0 +1,426 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>라우드소싱 (LOUDSOURCING) 기업분석</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { font-family: 'Noto Sans KR', sans-serif; }
|
||||
.tab-content { display: none; }
|
||||
.tab-content.active { display: block; }
|
||||
.nav-active { background-color: #2563eb; color: white; box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); }
|
||||
.fade-in { animation: fadeIn 0.5s ease-out forwards; }
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50 p-6">
|
||||
<div class="max-w-5xl mx-auto">
|
||||
<!-- Header -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-8 mb-6 fade-in">
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="w-16 h-16 bg-gradient-to-br from-blue-500 to-purple-600 rounded-xl flex items-center justify-center">
|
||||
<span class="text-white font-bold text-2xl">L</span>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-gray-800">라우드소싱 (LOUDSOURCING)</h1>
|
||||
<p class="text-gray-500">운영사: 주식회사 스터닝 (STUNNING INC.)</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-gray-600 leading-relaxed">
|
||||
국내 최대 디자인 크라우드소싱 플랫폼으로, 디자이너와 기업을 연결하는 콘테스트 기반 비즈니스 모델을 운영합니다.
|
||||
2020년 포트폴리오 플랫폼 '노트폴리오'와 합병하여 통합 크리에이티브 플랫폼으로 성장했습니다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Key Metrics -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||
<div class="bg-white rounded-xl shadow-md p-5 fade-in" style="animation-delay: 0.1s">
|
||||
<div class="flex items-center gap-2 text-blue-600 mb-2">
|
||||
<i data-lucide="users" size="20"></i>
|
||||
<span class="text-sm font-medium">등록 디자이너</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">28만명</p>
|
||||
<p class="text-xs text-gray-500">국내 디자이너 80%</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-md p-5 fade-in" style="animation-delay: 0.2s">
|
||||
<div class="flex items-center gap-2 text-green-600 mb-2">
|
||||
<i data-lucide="dollar-sign" size="20"></i>
|
||||
<span class="text-sm font-medium">2023 매출</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">64.3억</p>
|
||||
<p class="text-xs text-gray-500">연 50~60% 성장</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-md p-5 fade-in" style="animation-delay: 0.3s">
|
||||
<div class="flex items-center gap-2 text-purple-600 mb-2">
|
||||
<i data-lucide="briefcase" size="20"></i>
|
||||
<span class="text-sm font-medium">임직원 수</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">43명</p>
|
||||
<p class="text-xs text-gray-500">2025년 7월 기준</p>
|
||||
</div>
|
||||
<div class="bg-white rounded-xl shadow-md p-5 fade-in" style="animation-delay: 0.4s">
|
||||
<div class="flex items-center gap-2 text-orange-600 mb-2">
|
||||
<i data-lucide="award" size="20"></i>
|
||||
<span class="text-sm font-medium">누적 상금</span>
|
||||
</div>
|
||||
<p class="text-2xl font-bold text-gray-800">200억+</p>
|
||||
<p class="text-xs text-gray-500">콘테스트 2만건+</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab Navigation -->
|
||||
<div class="flex gap-2 mb-6 overflow-x-auto">
|
||||
<button onclick="showTab('overview')" id="tab-overview" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap nav-active">기업개요</button>
|
||||
<button onclick="showTab('financial')" id="tab-financial" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap bg-white text-gray-600 hover:bg-gray-100">재무/성장</button>
|
||||
<button onclick="showTab('history')" id="tab-history" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap bg-white text-gray-600 hover:bg-gray-100">연혁</button>
|
||||
<button onclick="showTab('competition')" id="tab-competition" class="tab-btn px-5 py-2.5 rounded-lg font-medium transition-all whitespace-nowrap bg-white text-gray-600 hover:bg-gray-100">경쟁분석</button>
|
||||
</div>
|
||||
|
||||
<!-- Tab Content -->
|
||||
<div class="bg-white rounded-2xl shadow-lg p-6 min-h-[400px]">
|
||||
<!-- Overview Tab -->
|
||||
<div id="overview" class="tab-content active space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="building-2" class="text-blue-600" size="24"></i>
|
||||
기업 개요
|
||||
</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="space-y-4">
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2">기본 정보</h3>
|
||||
<div class="space-y-2 text-sm">
|
||||
<div class="flex justify-between"><span class="text-gray-500">대표</span><span class="font-medium">김승환</span></div>
|
||||
<div class="flex justify-between"><span class="text-gray-500">설립일</span><span class="font-medium">2011년 6월</span></div>
|
||||
<div class="flex justify-between"><span class="text-gray-500">업력</span><span class="font-medium">14.2년</span></div>
|
||||
<div class="flex justify-between"><span class="text-gray-500">사업자번호</span><span class="font-medium">120-87-69298</span></div>
|
||||
<div class="flex justify-between"><span class="text-gray-500">자본금</span><span class="font-medium">1억 468만원</span></div>
|
||||
<div class="flex justify-between"><span class="text-gray-500">기업형태</span><span class="font-medium">비상장 / 중소기업</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-4">
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2">소재지</h3>
|
||||
<p class="text-sm text-gray-600">
|
||||
서울특별시 강남구 선릉로 636,<br />
|
||||
키스톤빌딩 3층 302호 (삼성동)
|
||||
</p>
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2 mt-4">운영 서비스</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<span class="px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-sm">라우드소싱</span>
|
||||
<span class="px-3 py-1 bg-purple-100 text-purple-700 rounded-full text-sm">노트폴리오</span>
|
||||
<span class="px-3 py-1 bg-green-100 text-green-700 rounded-full text-sm">스터닝 에이전시</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2 mb-4">비즈니스 모델</h3>
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<div class="bg-gradient-to-r from-blue-50 to-blue-100 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-blue-800 mb-2">🏆 콘테스트</h4>
|
||||
<p class="text-sm text-gray-600">의뢰자가 상금을 걸고 공모전 개최, 다수의 디자이너가 참여하여 경쟁</p>
|
||||
</div>
|
||||
<div class="bg-gradient-to-r from-purple-50 to-purple-100 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-purple-800 mb-2">🛒 라우드마켓</h4>
|
||||
<p class="text-sm text-gray-600">1:1 직접 의뢰 방식, 원하는 디자이너를 선택해 프로젝트 진행</p>
|
||||
</div>
|
||||
<div class="bg-gradient-to-r from-green-50 to-green-100 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-green-800 mb-2">🤝 디자이너 매칭</h4>
|
||||
<p class="text-sm text-gray-600">23만명 디자이너로부터 무료 비교견적 수령 가능</p>
|
||||
</div>
|
||||
<div class="bg-gradient-to-r from-orange-50 to-orange-100 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-orange-800 mb-2">🎯 에이전시</h4>
|
||||
<p class="text-sm text-gray-600">전담 매니저가 프로젝트 매니징, 컨시어지 서비스 제공</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2 mb-4">주요 고객사</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<?php
|
||||
$clients = ['티몬', '농협', '포스코', '삼성 테크윈', '제주도 개발공사', '바카디코리아', '잡코리아', '도미노피자', 'BC카드', 'LG그램'];
|
||||
foreach($clients as $client) {
|
||||
echo '<span class="px-3 py-1 bg-gray-100 text-gray-700 rounded-lg text-sm">'.$client.'</span>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Financial Tab -->
|
||||
<div id="financial" class="tab-content space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="trending-up" class="text-green-600" size="24"></i>
|
||||
재무 및 성장 현황
|
||||
</h2>
|
||||
|
||||
<div class="bg-gradient-to-r from-green-50 to-emerald-50 rounded-xl p-6">
|
||||
<h3 class="font-semibold text-gray-700 mb-4">매출 추이</h3>
|
||||
<div class="flex items-end justify-around h-40 mb-4">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="bg-green-400 w-16 rounded-t-lg" style="height: 51%"></div>
|
||||
<span class="text-xs mt-2 text-gray-600">2020년</span>
|
||||
<span class="text-sm font-bold">33억+</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="bg-green-500 w-16 rounded-t-lg" style="height: 100%"></div>
|
||||
<span class="text-xs mt-2 text-gray-600">2023년</span>
|
||||
<span class="text-sm font-bold">64.3억</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 text-center">연평균 50~60% 성장률 유지</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl p-6">
|
||||
<h3 class="font-semibold text-gray-700 mb-4">직원 수 변화</h3>
|
||||
<div class="flex items-end justify-around h-32 mb-4">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="bg-blue-400 w-16 rounded-t-lg" style="height: 28%"></div>
|
||||
<span class="text-xs mt-2 text-gray-600">2020년</span>
|
||||
<span class="text-sm font-bold">12명</span>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="bg-blue-500 w-16 rounded-t-lg" style="height: 100%"></div>
|
||||
<span class="text-xs mt-2 text-gray-600">2025년</span>
|
||||
<span class="text-sm font-bold">43명</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 text-center">5년간 약 3.5배 인력 확대</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2 mb-4">투자 유치 현황</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
||||
<div>
|
||||
<span class="font-medium">Series A</span>
|
||||
<span class="text-gray-500 text-sm ml-2">2020년 3월</span>
|
||||
</div>
|
||||
<span class="font-bold text-green-600">20억원</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
||||
<div>
|
||||
<span class="font-medium">Series A Bridge</span>
|
||||
<span class="text-gray-500 text-sm ml-2">2021년 9월</span>
|
||||
</div>
|
||||
<span class="font-bold text-green-600">60억원</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-4 bg-blue-50 rounded-lg border-2 border-blue-200">
|
||||
<span class="font-semibold">누적 투자금</span>
|
||||
<span class="font-bold text-blue-600 text-lg">60~80억원</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 p-4 bg-gray-100 rounded-lg text-sm text-gray-600">
|
||||
<strong>투자사:</strong> DSC 인베스트먼트, 미래에셋벤처투자, 나이스투자파트너스, KDB캐피탈, 신한캐피탈
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2 mb-4">핵심 성장 지표</h3>
|
||||
<div class="grid md:grid-cols-3 gap-4">
|
||||
<div class="text-center p-4 bg-purple-50 rounded-xl">
|
||||
<p class="text-3xl font-bold text-purple-600">3.7배</p>
|
||||
<p class="text-sm text-gray-600">MAU 증가 (2년간)</p>
|
||||
</div>
|
||||
<div class="text-center p-4 bg-blue-50 rounded-xl">
|
||||
<p class="text-3xl font-bold text-blue-600">2.5배</p>
|
||||
<p class="text-sm text-gray-600">디자이너 수 증가</p>
|
||||
</div>
|
||||
<div class="text-center p-4 bg-green-50 rounded-xl">
|
||||
<p class="text-3xl font-bold text-green-600">2.7배</p>
|
||||
<p class="text-sm text-gray-600">등록 작품 수 증가</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- History Tab -->
|
||||
<div id="history" class="tab-content space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="calendar" class="text-purple-600" size="24"></i>
|
||||
성장 연혁
|
||||
</h2>
|
||||
|
||||
<div class="relative">
|
||||
<div class="absolute left-4 top-0 bottom-0 w-0.5 bg-gradient-to-b from-blue-500 to-purple-500"></div>
|
||||
|
||||
<?php
|
||||
$history = [
|
||||
['year' => '2011', 'title' => '창업', 'desc' => '(주)라우더스 창업, 라우드소싱 론칭', 'color' => 'blue'],
|
||||
['year' => '2012', 'title' => '노트폴리오 설립', 'desc' => '디자이너 포트폴리오 커뮤니티 시작', 'color' => 'purple'],
|
||||
['year' => '2017', 'title' => '벤처기업 인증', 'desc' => '기술혁신형 벤처기업 인증 획득', 'color' => 'green'],
|
||||
['year' => '2020.03', 'title' => 'Series A 투자', 'desc' => '20억원 투자 유치', 'color' => 'blue'],
|
||||
['year' => '2020.09', 'title' => '합병 & 스터닝 설립', 'desc' => '라우드소싱 + 노트폴리오 합병', 'color' => 'purple'],
|
||||
['year' => '2021', 'title' => 'Main-Biz 인증', 'desc' => '경영혁신형 중소기업 인증', 'color' => 'green'],
|
||||
['year' => '2021.09', 'title' => 'Bridge 투자', 'desc' => '60억원 추가 투자 유치', 'color' => 'blue'],
|
||||
['year' => '2022', 'title' => '라우드마켓 출시', 'desc' => '1:1 의뢰 서비스 런칭', 'color' => 'purple'],
|
||||
['year' => '2022.하반기', 'title' => '에이전시 출시', 'desc' => '컨시어지 서비스 시작', 'color' => 'orange'],
|
||||
['year' => '2023', 'title' => '매칭 서비스', 'desc' => '디자이너 매칭 서비스 런칭', 'color' => 'green'],
|
||||
];
|
||||
foreach($history as $idx => $item) {
|
||||
$color = $item['color'];
|
||||
echo '
|
||||
<div class="relative pl-10 pb-6">
|
||||
<div class="absolute left-2 w-5 h-5 rounded-full bg-'.$color.'-500 border-4 border-white shadow"></div>
|
||||
<div class="bg-gray-50 rounded-lg p-4">
|
||||
<div class="flex items-center gap-3 mb-1">
|
||||
<span class="px-2 py-0.5 bg-'.$color.'-100 text-'.$color.'-700 rounded text-xs font-medium">
|
||||
'.$item['year'].'
|
||||
</span>
|
||||
<span class="font-semibold text-gray-800">'.$item['title'].'</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600">'.$item['desc'].'</p>
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Competition Tab -->
|
||||
<div id="competition" class="tab-content space-y-6">
|
||||
<h2 class="text-xl font-bold text-gray-800 flex items-center gap-2">
|
||||
<i data-lucide="target" class="text-orange-600" size="24"></i>
|
||||
경쟁 분석
|
||||
</h2>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="bg-gray-100">
|
||||
<th class="p-3 text-left font-semibold">구분</th>
|
||||
<th class="p-3 text-center font-semibold text-blue-600">라우드소싱</th>
|
||||
<th class="p-3 text-center font-semibold">크몽</th>
|
||||
<th class="p-3 text-center font-semibold">숨고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b">
|
||||
<td class="p-3 font-medium">특화 분야</td>
|
||||
<td class="p-3 text-center text-blue-600">디자인 전문</td>
|
||||
<td class="p-3 text-center">종합 프리랜서</td>
|
||||
<td class="p-3 text-center">생활 서비스</td>
|
||||
</tr>
|
||||
<tr class="border-b bg-gray-50">
|
||||
<td class="p-3 font-medium">핵심 방식</td>
|
||||
<td class="p-3 text-center text-blue-600">콘테스트/공모전</td>
|
||||
<td class="p-3 text-center">판매자 상품 등록</td>
|
||||
<td class="p-3 text-center">요청서 기반 견적</td>
|
||||
</tr>
|
||||
<tr class="border-b">
|
||||
<td class="p-3 font-medium">가격 결정</td>
|
||||
<td class="p-3 text-center text-blue-600">의뢰자가 상금 설정</td>
|
||||
<td class="p-3 text-center">판매자가 단가 설정</td>
|
||||
<td class="p-3 text-center">고수가 견적 제시</td>
|
||||
</tr>
|
||||
<tr class="border-b bg-gray-50">
|
||||
<td class="p-3 font-medium">수수료</td>
|
||||
<td class="p-3 text-center text-blue-600">19.7%</td>
|
||||
<td class="p-3 text-center">~20%</td>
|
||||
<td class="p-3 text-center">포인트 차감</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="p-3 font-medium">차별점</td>
|
||||
<td class="p-3 text-center text-blue-600">다수 시안 비교</td>
|
||||
<td class="p-3 text-center">빠른 매칭</td>
|
||||
<td class="p-3 text-center">지역 기반</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="font-semibold text-gray-700 border-b pb-2 mb-4">SWOT 분석</h3>
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<div class="bg-green-50 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-green-700 mb-3">💪 강점 (Strengths)</h4>
|
||||
<ul class="text-sm text-gray-600 space-y-1">
|
||||
<li>• 국내 디자이너 80% 점유율</li>
|
||||
<li>• 14년 운영 노하우</li>
|
||||
<li>• 다양한 시안 비교 가능</li>
|
||||
<li>• 노트폴리오와 시너지</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-red-50 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-red-700 mb-3">⚠️ 약점 (Weaknesses)</h4>
|
||||
<ul class="text-sm text-gray-600 space-y-1">
|
||||
<li>• 낙선 디자이너 보상 없음</li>
|
||||
<li>• 수수료 부담 (19.7%)</li>
|
||||
<li>• 콘테스트 방식 한계</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-blue-50 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-blue-700 mb-3">🚀 기회 (Opportunities)</h4>
|
||||
<ul class="text-sm text-gray-600 space-y-1">
|
||||
<li>• 18조 국내 디자인 시장</li>
|
||||
<li>• 프리랜서 경제 성장</li>
|
||||
<li>• 아이디어 콘테스트 확장</li>
|
||||
<li>• 기업 디자인 아웃소싱 증가</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-orange-50 rounded-xl p-4">
|
||||
<h4 class="font-semibold text-orange-700 mb-3">⚡ 위협 (Threats)</h4>
|
||||
<ul class="text-sm text-gray-600 space-y-1">
|
||||
<li>• AI 디자인 툴 부상</li>
|
||||
<li>• Canva, 미리캔버스 등 경쟁</li>
|
||||
<li>• 크몽, 숨고 등 플랫폼 경쟁</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gradient-to-r from-indigo-50 to-purple-50 rounded-xl p-6">
|
||||
<h3 class="font-semibold text-gray-700 mb-3">시장 규모</h3>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="text-center">
|
||||
<p class="text-4xl font-bold text-indigo-600">18조원</p>
|
||||
<p class="text-sm text-gray-600">국내 디자인 시장</p>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p class="text-4xl font-bold text-purple-600">1조원</p>
|
||||
<p class="text-sm text-gray-600">국내 프리랜서 시장</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-6 text-center text-sm text-gray-500">
|
||||
<p>데이터 출처: THE VC, 혁신의숲, 원티드, 인크루트, 잡플래닛, 나무위키 등</p>
|
||||
<p>분석 기준일: 2026년 1월</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Lucide 아이콘 렌더링
|
||||
lucide.createIcons();
|
||||
|
||||
// 탭 전환 기능
|
||||
function showTab(tabId) {
|
||||
// 모든 탭 컨텐츠 숨기기
|
||||
document.querySelectorAll('.tab-content').forEach(tab => {
|
||||
tab.classList.remove('active');
|
||||
});
|
||||
// 선택된 탭 컨텐츠 보이기
|
||||
document.getElementById(tabId).classList.add('active');
|
||||
|
||||
// 탭 버튼 스타일 업데이트
|
||||
document.querySelectorAll('.tab-btn').forEach(btn => {
|
||||
btn.classList.remove('nav-active');
|
||||
btn.classList.add('bg-white', 'text-gray-600', 'hover:bg-gray-100');
|
||||
});
|
||||
const activeBtn = document.getElementById('tab-' + tabId);
|
||||
activeBtn.classList.add('nav-active');
|
||||
activeBtn.classList.remove('bg-white', 'text-gray-600', 'hover:bg-gray-100');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
35
index.php
35
index.php
@@ -12,8 +12,7 @@
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
|
||||
<link rel="shortcut icon" href="img/favicon.png">
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<?php include_once 'lib/meta_common.php'; ?>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+KR:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script>
|
||||
tailwind.config = {
|
||||
@@ -120,17 +119,6 @@
|
||||
display: block;
|
||||
box-shadow: 0 0 50px rgba(0,0,0,0.5);
|
||||
}
|
||||
.fullscreen-close {
|
||||
position: fixed;
|
||||
top: 1.5rem;
|
||||
right: 1.5rem;
|
||||
z-index: 110;
|
||||
background: white;
|
||||
border-radius: 9999px;
|
||||
padding: 0.75rem;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Mobile touch optimization */
|
||||
.touch-manipulation {
|
||||
@@ -216,6 +204,9 @@
|
||||
<a href="creditreport/index.php" class="block px-4 py-2 text-sm text-slate-700 hover:bg-brand-50 hover:text-brand-600 font-medium">
|
||||
기업신용조회 리포트
|
||||
</a>
|
||||
<a href="company/index.php" class="block px-4 py-2 text-sm text-slate-700 hover:bg-brand-50 hover:text-brand-600 font-medium">
|
||||
기타 기업분석자료
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (isset($_SESSION['userid']) && $_SESSION['userid'] != ''): ?>
|
||||
@@ -346,10 +337,9 @@
|
||||
<!-- Modal Content injected by JS -->
|
||||
</div>
|
||||
|
||||
<!-- Full Screen Viewer Overlay -->
|
||||
<div id="fullscreen-view" onclick="closeFullscreen()">
|
||||
<div class="fullscreen-close">
|
||||
<i data-lucide="x" class="w-6 h-6 text-slate-900"></i>
|
||||
<div class="fullscreen-close btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</div>
|
||||
<img id="fullscreen-img" src="" alt="Full size view" onclick="event.stopPropagation()">
|
||||
</div>
|
||||
@@ -361,8 +351,8 @@
|
||||
<div class="bg-white rounded-2xl shadow-2xl w-full max-w-[95vw] h-[95vh] flex flex-col pointer-events-auto scale-95 opacity-0 transition-all duration-300" id="pdf-modal-card">
|
||||
<div class="sticky top-0 bg-white/90 backdrop-blur-sm p-4 border-b border-slate-100 flex justify-between items-center z-10">
|
||||
<h3 class="text-lg font-bold text-slate-900" id="pdf-modal-title">상세자료</h3>
|
||||
<button onclick="closePdfViewer()" class="w-8 h-8 rounded-full bg-slate-50 hover:bg-slate-100 flex items-center justify-center text-slate-500 transition-colors">
|
||||
<i data-lucide="x" class="w-5 h-5"></i>
|
||||
<button onclick="closePdfViewer()" class="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden">
|
||||
@@ -543,9 +533,10 @@
|
||||
|
||||
// Initial Render
|
||||
function init() {
|
||||
|
||||
renderFilters();
|
||||
renderGrid();
|
||||
// Initial Lucide icons are handled by DOMContentLoaded in meta_common.php
|
||||
// but we call it here for the dynamically rendered grid items
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
@@ -757,8 +748,8 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<h3 class="text-base sm:text-lg font-bold text-slate-900 break-keep leading-tight" style="word-break: keep-all; overflow-wrap: break-word;">${asset.title}</h3>
|
||||
</div>
|
||||
<button onclick="closeModal()" class="w-8 h-8 rounded-full bg-slate-50 hover:bg-slate-100 flex items-center justify-center text-slate-500 transition-colors">
|
||||
<i data-lucide="x" class="w-5 h-5"></i>
|
||||
<button onclick="closeModal()" class="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1064,6 +1055,6 @@
|
||||
// Initialize
|
||||
init();
|
||||
</script>
|
||||
<script src="https://player.vimeo.com/api/player.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
33
lib/meta_common.php
Normal file
33
lib/meta_common.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Metadata and Shared Styles
|
||||
* This file centralizes Tailwind CSS, Lucide Icons, React, and Babel scripts.
|
||||
*/
|
||||
?>
|
||||
<!-- Core Libraries -->
|
||||
<script src="https://cdn.tailwindcss.com?v=3.4.1"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
||||
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Ensure Lucide icons are initialized after page load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (window.lucide) {
|
||||
window.lucide.createIcons();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style type="text/tailwindcss">
|
||||
@layer components {
|
||||
/* Global Modal Close Button Style */
|
||||
.btn-close-modal {
|
||||
@apply w-10 h-10 flex items-center justify-center rounded-full bg-white shadow-lg border-2 border-slate-900 transition-all duration-200 hover:bg-red-50 hover:border-red-500 cursor-pointer pointer-events-auto;
|
||||
}
|
||||
.btn-close-modal span {
|
||||
@apply text-xl font-bold text-black group-hover:text-red-600 select-none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -11,52 +11,7 @@ if (file_exists('../session.php')) {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>수당 계산기 | SAM</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+KR:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Inter', 'Noto Sans KR', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
50: '#f0f9ff',
|
||||
100: '#e0f2fe',
|
||||
200: '#bae6fd',
|
||||
500: '#0ea5e9',
|
||||
600: '#0284c7',
|
||||
700: '#0369a1',
|
||||
900: '#0c4a6e',
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
blob: "blob 7s infinite",
|
||||
'fade-in-up': 'fadeInUp 0.8s ease-out forwards',
|
||||
},
|
||||
keyframes: {
|
||||
blob: {
|
||||
"0%": { transform: "translate(0px, 0px) scale(1)" },
|
||||
"33%": { transform: "translate(30px, -50px) scale(1.1)" },
|
||||
"66%": { transform: "translate(-20px, 20px) scale(0.9)" },
|
||||
"100%": { transform: "translate(0px, 0px) scale(1)" },
|
||||
},
|
||||
fadeInUp: {
|
||||
'0%': { opacity: '0', transform: 'translateY(20px)' },
|
||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.delay-100 { animation-delay: 100ms; }
|
||||
.delay-200 { animation-delay: 200ms; }
|
||||
.backdrop-blur-xl { backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); }
|
||||
</style>
|
||||
<?php require_once __DIR__ . '/../lib/meta_common.php'; ?>
|
||||
</head>
|
||||
<body class="bg-slate-50 text-slate-900 font-sans selection:bg-brand-200 selection:text-brand-900 overflow-x-hidden">
|
||||
|
||||
@@ -667,8 +622,8 @@ if (file_exists('../session.php')) {
|
||||
<p class="text-xs text-slate-500">안전하고 투명한 AI 서비스 이용을 위한 안내</p>
|
||||
</div>
|
||||
</div>
|
||||
<button onclick="closeTokenModal()" class="p-2 hover:bg-white rounded-xl transition-colors">
|
||||
<i data-lucide="x" class="w-6 h-6 text-slate-400"></i>
|
||||
<button onclick="closeTokenModal()" class="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -748,8 +703,8 @@ if (file_exists('../session.php')) {
|
||||
<p class="text-xs text-slate-500">패키지 구성 및 주요 기능을 확인하세요.</p>
|
||||
</div>
|
||||
</div>
|
||||
<button onclick="closeInfoModal()" class="p-2 hover:bg-white rounded-xl transition-colors">
|
||||
<i data-lucide="x" class="w-6 h-6 text-slate-400"></i>
|
||||
<button onclick="closeInfoModal()" class="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -42,17 +42,25 @@
|
||||
<!-- Fonts: Pretendard -->
|
||||
<link rel="stylesheet" as="style" crossorigin href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.8/dist/web/static/pretendard.css" />
|
||||
|
||||
<?php require_once __DIR__ . '/../lib/meta_common.php'; ?>
|
||||
|
||||
<!-- Tailwind CSS -->
|
||||
<script src="https://cdn.tailwindcss.com?v=3.4.1"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['Pretendard', 'sans-serif'],
|
||||
sans: ['Pretendard', 'Inter', 'Noto Sans KR', 'sans-serif'],
|
||||
},
|
||||
colors: {
|
||||
brand: {
|
||||
50: '#f0f9ff',
|
||||
100: '#e0f2fe',
|
||||
200: '#bae6fd',
|
||||
500: '#0ea5e9',
|
||||
600: '#0284c7',
|
||||
700: '#0369a1',
|
||||
900: '#0c4a6e',
|
||||
},
|
||||
background: 'rgb(250, 250, 250)',
|
||||
primary: {
|
||||
DEFAULT: '#2563eb', // blue-600
|
||||
@@ -66,16 +74,6 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- React & ReactDOM (Production Versions) -->
|
||||
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js?v=18.2.0"></script>
|
||||
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js?v=18.2.0"></script>
|
||||
|
||||
<!-- Babel for JSX -->
|
||||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
||||
|
||||
<!-- Icons: Lucide React (via CDN is tricky, using simple SVG icons or a library wrapper if needed. For now, using text/simple SVGs) -->
|
||||
<script src="https://unpkg.com/lucide@latest"></script>
|
||||
</head>
|
||||
<body class="bg-background text-slate-800 antialiased">
|
||||
<div id="root"></div>
|
||||
@@ -654,8 +652,8 @@
|
||||
</button>
|
||||
)}
|
||||
</h3>
|
||||
<button type="button" onClick={() => setIsModalOpen(false)} className="p-2 hover:bg-slate-200 rounded-full transition-colors text-slate-400">
|
||||
<LucideIcon name="x" className="w-6 h-6" />
|
||||
<button type="button" onClick={() => setIsModalOpen(false)} className="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -807,8 +805,8 @@
|
||||
</h3>
|
||||
<p className="text-slate-500 mt-1">이 영업파트너에게 소속된 모든 매니저 목록입니다.</p>
|
||||
</div>
|
||||
<button onClick={() => setDetailModalUser(null)} className="p-2 hover:bg-slate-200 rounded-full transition-colors text-slate-400">
|
||||
<LucideIcon name="x" className="w-6 h-6" />
|
||||
<button onClick={() => setDetailModalUser(null)} className="btn-close-modal group">
|
||||
<span>✕</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="overflow-y-auto p-8">
|
||||
|
||||
Reference in New Issue
Block a user