Files
Gnuboard7/templates/_bundled/sirsoft-basic/layouts/_user_base.json
T
2026-04-01 10:30:52 +09:00

1484 lines
87 KiB
JSON

{
"version": "1.0.0",
"layout_name": "_user_base",
"meta": {
"title": "$t:user.base_layout_title",
"description": "$t:user.base_layout_description",
"is_base": true,
"seo": {
"enabled": false,
"data_sources": ["boards"],
"vars": {
"site_name": "$core_settings:general.site_name"
},
"og": {
"type": "website"
}
}
},
"globalHeaders": [
{
"pattern": "/api/modules/sirsoft-ecommerce/*",
"headers": {
"X-Cart-Key": "{{_global.cartKey}}"
}
},
{
"pattern": "/api/auth/*",
"headers": {
"X-Cart-Key": "{{_global.cartKey}}"
}
}
],
"transition_overlay": {
"enabled": true,
"style": "spinner",
"target": "main_content_area",
"spinner": {
"component": "PageLoading"
}
},
"init_actions": [
{
"handler": "initTheme"
},
{
"handler": "initCartKey"
},
{
"handler": "loadFromLocalStorage",
"params": {
"key": "g7_preferred_currency",
"stateKey": "preferredCurrency",
"defaultValue": "KRW"
}
},
{
"handler": "setState",
"params": {
"target": "global",
"shopBase": "{{_global.modules?.['sirsoft-ecommerce']?.basic_info?.no_route ? '' : ('/' + (_global.modules?.['sirsoft-ecommerce']?.basic_info?.route_path ?? 'shop'))}}"
}
}
],
"data_sources": [
{
"id": "boards",
"type": "api",
"endpoint": "/api/modules/sirsoft-board/boards/board-menu",
"method": "GET",
"auto_fetch": true,
"loading_strategy": "progressive",
"fallback": { "data": [] }
},
{
"id": "current_user",
"type": "api",
"endpoint": "/api/auth/user",
"method": "GET",
"auto_fetch": true,
"auth_required": true,
"loading_strategy": "progressive",
"initGlobal": "currentUser",
"fallback": { "data": [] },
"errorHandling": {
"401": {
"comment": "비회원의 /api/auth/user 401은 정상 — fallback 사용, 레이아웃 에러 핸들링으로 전파 방지",
"handler": "suppress"
}
}
},
{
"id": "cart",
"type": "api",
"endpoint": "/api/modules/sirsoft-ecommerce/cart/count",
"method": "GET",
"auto_fetch": true,
"auth_mode": "optional",
"loading_strategy": "progressive",
"headers": {
"X-Cart-Key": "{{_global.cartKey}}"
},
"initGlobal": {
"key": "cartCount",
"path": "count"
},
"fallback": { "data": { "count": 0 } }
}
],
"components": [
{
"id": "global_toast",
"type": "composite",
"name": "Toast",
"props": {
"toasts": "{{_global.toasts}}",
"position": "bottom-center",
"duration": 5000
}
},
{
"id": "page_transition_indicator",
"type": "composite",
"name": "PageTransitionIndicator"
},
{
"id": "user_layout_root",
"type": "basic",
"name": "Div",
"props": {
"className": "min-h-screen flex flex-col bg-gray-50 dark:bg-gray-900"
},
"children": [
{
"comment": "=== 모바일 오버레이 (사이드 메뉴 열릴 때) ===",
"id": "mobile_overlay",
"type": "basic",
"name": "Div",
"if": "{{false}}",
"props": {
"className": "fixed inset-0 z-40 bg-black/50"
},
"responsive": {
"portable": {
"if": "{{_global.mobileMenuOpen}}"
}
},
"actions": [
{
"type": "click",
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
}
]
},
{
"comment": "=== 모바일 헤더 (툴바) - 데스크톱에서 숨김 ===",
"id": "mobile_header",
"type": "basic",
"name": "Div",
"props": {
"className": "hidden"
},
"responsive": {
"portable": {
"props": {
"className": "flex items-center justify-between h-14 px-4 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 sticky top-0 z-30"
}
}
},
"children": [
{
"comment": "모바일 헤더 좌측 - 로고",
"id": "mobile_header_left",
"type": "basic",
"name": "Button",
"props": {
"className": "flex items-center cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "navigate",
"params": {
"path": "/"
}
}
],
"children": [
{
"type": "basic",
"name": "Div",
"if": "{{_global.settings?.general?.site_logo_url}}",
"children": [
{
"type": "basic",
"name": "Img",
"props": {
"src": "{{_global.settings?.general?.site_logo_url}}",
"alt": "{{_global.settings?.general?.site_name ?? 'Site'}}",
"className": "h-8 w-auto"
}
}
]
},
{
"type": "basic",
"name": "Div",
"if": "{{!_global.settings?.general?.site_logo_url}}",
"props": {
"className": "flex items-center justify-center w-8 h-8 bg-black dark:bg-white rounded-lg"
},
"children": [
{
"type": "basic",
"name": "Span",
"props": {
"className": "text-white dark:text-black font-bold text-sm"
},
"text": "N"
}
]
}
]
},
{
"comment": "모바일 헤더 우측 - 액션 버튼들",
"id": "mobile_header_right",
"type": "basic",
"name": "Div",
"props": {
"className": "flex items-center gap-1"
},
"children": [
{
"comment": "다크모드 전환",
"id": "mobile_theme_btn",
"type": "composite",
"name": "ThemeToggle",
"props": {
"autoText": "$t:common.theme.auto",
"lightText": "$t:common.theme.light",
"darkText": "$t:common.theme.dark"
}
},
{
"comment": "장바구니",
"id": "mobile_cart_btn",
"type": "basic",
"name": "Button",
"props": {
"className": "p-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg relative cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "navigate",
"params": {
"path": "{{_global.shopBase}}/cart"
}
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "shopping-cart",
"className": "w-5 h-5"
}
},
{
"type": "basic",
"name": "Span",
"if": "{{_global.cartCount > 0}}",
"props": {
"className": "absolute -top-1 -right-1 w-5 h-5 bg-red-500 text-white text-xs font-bold rounded-full flex items-center justify-center"
},
"text": "{{_global.cartCount > 99 ? '99+' : _global.cartCount}}"
}
]
},
{
"comment": "알림",
"id": "mobile_notification_btn",
"type": "basic",
"name": "Button",
"if": "{{_global.currentUser?.uuid}}",
"props": {
"className": "p-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg relative"
},
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "bell",
"className": "w-5 h-5"
}
},
{
"type": "basic",
"name": "Span",
"if": "{{_global.notificationCount > 0}}",
"props": {
"className": "absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"
}
}
]
},
{
"comment": "사용자 아이콘 (로그인 시) / 로그인 버튼",
"id": "mobile_user_btn",
"type": "basic",
"name": "Button",
"props": {
"className": "p-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "navigate",
"params": {
"path": "{{_global.currentUser ? '/mypage' : '/login'}}"
}
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "user",
"className": "w-5 h-5"
}
}
]
},
{
"comment": "햄버거 메뉴 버튼",
"id": "mobile_menu_toggle",
"type": "basic",
"name": "Button",
"props": {
"className": "p-2 text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg"
},
"actions": [
{
"type": "click",
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": "{{!_global.mobileMenuOpen}}"
}
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "menu",
"className": "w-5 h-5"
}
}
]
}
]
}
]
},
{
"comment": "=== 모바일 사이드 메뉴 (MobileNav 드로어) ===",
"id": "mobile_nav_drawer",
"type": "basic",
"name": "Div",
"props": {
"className": "hidden"
},
"responsive": {
"portable": {
"props": {
"className": "{{_global.mobileMenuOpen ? 'translate-x-0' : 'translate-x-full'}} fixed inset-y-0 right-0 z-50 w-80 max-w-full transition-transform duration-300 bg-white dark:bg-gray-800 shadow-xl overflow-y-auto"
}
}
},
"children": [
{
"comment": "드로어 헤더 - 닫기 버튼",
"type": "basic",
"name": "Div",
"props": {
"className": "flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700"
},
"children": [
{
"type": "basic",
"name": "Span",
"props": {
"className": "font-semibold text-gray-900 dark:text-white"
},
"text": "$t:user.menu"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "p-2 text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg"
},
"actions": [
{
"type": "click",
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "x",
"className": "w-5 h-5"
}
}
]
}
]
},
{
"comment": "검색바",
"type": "basic",
"name": "Div",
"props": {
"className": "p-4"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "relative"
},
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "search",
"className": "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400"
}
},
{
"type": "basic",
"name": "Input",
"props": {
"type": "text",
"placeholder": "$t:user.search_placeholder",
"className": "w-full pl-10 pr-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white text-sm focus:ring-2 focus:ring-blue-500"
}
}
]
}
]
},
{
"comment": "로그인된 사용자 정보 - 아코디언 토글",
"type": "basic",
"name": "Div",
"if": "{{_global.currentUser?.uuid}}",
"props": {
"className": "px-4 pb-4 border-b border-gray-200 dark:border-gray-700"
},
"children": [
{
"comment": "사용자 프로필 버튼 (아코디언 토글)",
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center gap-3 p-3 bg-gray-50 dark:bg-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "setState",
"params": {
"target": "global",
"mobileUserMenuOpen": "{{!_global.mobileUserMenuOpen}}"
}
}
],
"children": [
{
"type": "composite",
"name": "Avatar",
"props": {
"avatar": "{{_global.currentUser?.avatar}}",
"name": "{{_global.currentUser?.name ?? '?'}}",
"size": "md"
}
},
{
"type": "basic",
"name": "Div",
"props": {
"className": "flex-1 min-w-0 text-left"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "font-medium text-gray-900 dark:text-white truncate"
},
"text": "{{_global.currentUser?.name}}"
},
{
"type": "basic",
"name": "Div",
"props": {
"className": "text-sm text-gray-500 dark:text-gray-400 truncate"
},
"text": "{{_global.currentUser?.email}}"
}
]
},
{
"comment": "아코디언 화살표 아이콘",
"type": "basic",
"name": "Icon",
"props": {
"name": "chevron-down",
"className": "{{_global.mobileUserMenuOpen ? 'rotate-180' : ''}} w-5 h-5 text-gray-400 transition-transform duration-200"
}
}
]
},
{
"comment": "아코디언 펼침 영역 - 부드러운 애니메이션",
"type": "basic",
"name": "Div",
"props": {
"className": "overflow-hidden transition-all duration-300 ease-in-out {{_global.mobileUserMenuOpen ? 'max-h-screen opacity-100 mt-2' : 'max-h-0 opacity-0 mt-0'}}"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "overflow-hidden min-h-0 py-2 bg-gray-100 dark:bg-gray-700/50 rounded-lg"
},
"children": [
{
"comment": "관리자 메뉴 (is_admin일 때만) - 하이퍼링크로 전체 페이지 새로고침",
"type": "basic",
"name": "A",
"if": "{{_global.currentUser?.is_admin}}",
"props": {
"href": "/admin",
"className": "w-full flex items-center justify-start gap-3 px-4 py-2.5 text-blue-600 dark:text-blue-400 hover:bg-gray-200 dark:hover:bg-gray-600 font-medium"
},
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "settings",
"className": "w-4 h-4"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:common.admin_menu"
}
]
},
{
"comment": "마이페이지",
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-start gap-3 px-4 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600 cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false,
"mobileUserMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/mypage"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "user",
"className": "w-4 h-4"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:common.mypage"
}
]
},
{
"comment": "주문 내역",
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-start gap-3 px-4 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600 cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false,
"mobileUserMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/mypage/orders"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "shopping-bag",
"className": "w-4 h-4"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:mypage.tabs.orders"
}
]
},
{
"comment": "위시리스트",
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-start gap-3 px-4 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600 cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false,
"mobileUserMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/mypage/wishlist"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "heart",
"className": "w-4 h-4"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:mypage.tabs.wishlist"
}
]
},
{
"comment": "언어 선택 (여러 언어 지원 시)",
"type": "basic",
"name": "Div",
"if": "{{$locales.length > 1}}",
"props": {
"className": "mt-2 pt-2 border-t border-gray-200 dark:border-gray-600"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "px-4 py-1 text-xs font-medium text-gray-500 dark:text-gray-400 uppercase"
},
"text": "$t:common.language"
},
{
"type": "basic",
"name": "Div",
"iteration": {
"source": "{{$locales}}",
"item_var": "loc"
},
"children": [
{
"type": "basic",
"name": "Button",
"props": {
"className": "{{loc === $locale ? 'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400' : 'text-gray-700 dark:text-gray-300'}} w-full flex items-center justify-start gap-3 px-4 py-2 hover:bg-gray-200 dark:hover:bg-gray-600 cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "setLocale",
"target": "{{loc}}"
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "globe",
"className": "w-4 h-4"
}
},
{
"type": "basic",
"name": "Span",
"text": "{{loc === 'ko' ? '한국어' : loc === 'en' ? 'English' : loc}}"
}
]
}
]
}
]
},
{
"comment": "로그아웃 버튼",
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center gap-3 px-4 py-2.5 mt-2 pt-2 border-t border-gray-200 dark:border-gray-600 text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "logout",
"onSuccess": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false,
"mobileUserMenuOpen": false
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "log-out",
"className": "w-4 h-4"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:auth.logout"
}
]
}
]
}
]
}
]
},
{
"comment": "비로그인 상태 - 로그인/회원가입 버튼",
"type": "basic",
"name": "Div",
"if": "{{!_global.currentUser?.uuid}}",
"props": {
"className": "px-4 pb-4 border-b border-gray-200 dark:border-gray-700"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "flex gap-2"
},
"children": [
{
"type": "basic",
"name": "Button",
"props": {
"className": "flex-1 py-2.5 text-center bg-gray-900 dark:bg-white text-white dark:text-gray-900 rounded-lg font-medium text-sm cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/login"
}
}
]
}
],
"text": "$t:auth.login"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "flex-1 py-2.5 text-center border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg font-medium text-sm cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/register"
}
}
]
}
],
"text": "$t:auth.register_link"
}
]
}
]
},
{
"comment": "메뉴 섹션 - 홈",
"type": "basic",
"name": "Div",
"props": {
"className": "p-4"
},
"children": [
{
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-start gap-3 px-3 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg font-medium cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "home",
"className": "w-5 h-5"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:user.nav.home"
}
]
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-start gap-3 px-3 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/boards/popular"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "flame",
"className": "w-5 h-5 text-orange-500"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:user.nav.popular"
}
]
}
]
},
{
"comment": "메뉴 섹션 - 게시판",
"type": "basic",
"name": "Div",
"props": {
"className": "px-4 pb-4"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2 px-3"
},
"text": "$t:user.nav.boards"
},
{
"type": "basic",
"name": "Div",
"iteration": {
"source": "{{boards.data ?? []}}",
"item_var": "board"
},
"children": [
{
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-between px-3 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/board/{{board.slug}}"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Span",
"text": "{{board.name}}"
},
{
"type": "basic",
"name": "Span",
"if": "{{board.post_count > 0}}",
"props": {
"className": "text-xs text-gray-500 dark:text-gray-400"
},
"text": "{{board.post_count}}"
}
]
}
]
}
]
},
{
"comment": "메뉴 섹션 - 쇼핑",
"type": "basic",
"name": "Div",
"props": {
"className": "px-4 pb-4 border-b border-gray-200 dark:border-gray-700"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2 px-3"
},
"text": "$t:user.nav.shop"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-start gap-3 px-3 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "{{_global.shopBase}}/products"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "shopping-bag",
"className": "w-5 h-5"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:user.nav.products"
}
]
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "w-full flex items-center justify-between px-3 py-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "{{_global.shopBase}}/cart"
}
}
]
}
],
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "flex items-center gap-3"
},
"children": [
{
"type": "basic",
"name": "Icon",
"props": {
"name": "shopping-cart",
"className": "w-5 h-5"
}
},
{
"type": "basic",
"name": "Span",
"text": "$t:user.nav.cart"
}
]
},
{
"type": "basic",
"name": "Span",
"if": "{{_global.cartCount > 0}}",
"props": {
"className": "px-2 py-0.5 bg-red-500 text-white text-xs font-bold rounded-full"
},
"text": "{{_global.cartCount}}"
}
]
}
]
},
{
"comment": "메뉴 섹션 - 정보/정책",
"type": "basic",
"name": "Div",
"props": {
"className": "px-4 py-4 border-b border-gray-200 dark:border-gray-700"
},
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "grid grid-cols-2 gap-x-4"
},
"children": [
{
"type": "basic",
"name": "Div",
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2"
},
"text": "$t:user.footer.info"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "block w-full py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white text-left cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/page/about"
}
}
]
}
],
"text": "$t:user.footer.about"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "block w-full py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white text-left cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/page/faq"
}
}
]
}
],
"text": "$t:user.footer.faq"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "block w-full py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white text-left cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/page/contact"
}
}
]
}
],
"text": "$t:user.footer.contact"
}
]
},
{
"type": "basic",
"name": "Div",
"children": [
{
"type": "basic",
"name": "Div",
"props": {
"className": "text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2"
},
"text": "$t:user.footer.policy"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "block w-full py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white text-left cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/page/terms"
}
}
]
}
],
"text": "$t:user.footer.terms"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "block w-full py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white text-left cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/page/privacy"
}
}
]
}
],
"text": "$t:user.footer.privacy"
},
{
"type": "basic",
"name": "Button",
"props": {
"className": "block w-full py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white text-left cursor-pointer"
},
"actions": [
{
"type": "click",
"handler": "sequence",
"actions": [
{
"handler": "setState",
"params": {
"target": "global",
"mobileMenuOpen": false
}
},
{
"handler": "navigate",
"params": {
"path": "/page/refund"
}
}
]
}
],
"text": "$t:user.footer.refund"
}
]
}
]
}
]
}
]
},
{
"comment": "=== 데스크톱 헤더 (Header 컴포넌트) - 모바일에서 숨김 ===",
"id": "desktop_header",
"type": "composite",
"name": "Header",
"props": {
"logo": "{{_global.settings?.general?.site_logo_url}}",
"siteName": "{{_global.settings?.general?.site_name ?? 'Site'}}",
"user": "{{_global.currentUser}}",
"cartCount": "{{_global.cartCount ?? 0}}",
"notificationCount": "{{_global.notificationCount ?? 0}}",
"shopBase": "{{_global.shopBase ?? '/shop'}}",
"boards": "{{boards.data ?? []}}",
"maxVisibleBoards": 5,
"availableLocales": "{{$locales}}",
"currentLocale": "{{$locale}}",
"className": "hidden"
},
"responsive": {
"desktop": {
"props": { "className": "block" }
}
}
},
{
"comment": "=== 메인 콘텐츠 영역 ===",
"id": "main_content_area",
"type": "basic",
"name": "Div",
"props": {
"className": "flex-1"
},
"children": [
{
"id": "main_content",
"type": "layout",
"name": "Container",
"slot": "content",
"props": {
"className": "min-h-fit px-4"
},
"responsive": {
"desktop": {
"props": {
"className": "min-h-fit max-w-7xl mx-auto px-8"
}
}
},
"children": []
}
]
},
{
"comment": "=== 푸터 (Footer 컴포넌트) ===",
"id": "footer",
"type": "composite",
"name": "Footer",
"props": {
"siteName": "{{_global.settings?.general?.site_name ?? 'Site'}}",
"siteDescription": "{{_global.settings?.general?.site_description ?? ''}}",
"copyrightText": "$t:footer.copyright|siteName={{_global.settings?.general?.site_name ?? '그누보드7'}}",
"socialLinks": {
"github": "{{_global.settings?.social?.github}}",
"twitter": "{{_global.settings?.social?.twitter}}",
"discord": "{{_global.settings?.social?.discord}}"
}
}
}
]
}
]
}