관리자 환경설정이 값을 저장은 하지만 실제 동작에는 닿지 않던 결함군을 정리했다. 설정 화면(min/max)·저장 검증(FormRequest)·런타임 적용(Service) 세 계층이 각자 리터럴을 들고 있어 서로 조용히 갈라지던 것이 공통 원인이다. 경계값 SSoT 도입: - config/core.php `settings_limits` 를 단일 출처로 두고, FormRequest 는 이 값으로 규칙을 만들고 화면은 설정 응답의 `_meta.limits` 로 같은 값을 받아 바인딩한다. - 게시판·이커머스도 각 모듈 config 의 limits 를 동일 구조로 노출한다. 적용되지 않던 정책을 실제로 적용: - 비밀번호 최소 길이·특수문자 필수(신규 지정 7개 경로. 로그인은 제외 — 정책을 올렸을 때 기존 회원이 자기 계정에 접근조차 못 하는 데드락을 막기 위함) - 계정 잠금 시간 0 = 무한대(전용 컬럼 분리. timestamp 상한과 NULL 규약 때문에 기존 컬럼 재사용이 불가능하다) + 관리자 수동 해제 경로 - 업로드 최대 크기·허용 확장자, 게시판 첨부 개수·댓글 깊이, 페이지 첨부 정책, 장바구니 수량·구매 한도, 마일리지 사용 한도, 주문 부가세 파생 결함: - 큐 Job(sync 드라이버)이 진행 중인 요청의 Request 바인딩을 덮어써, 뒤이어 실행되는 훅 리스너가 헤더를 잃고 조용히 건너뛰었다. Job 이 원 바인딩을 복원하도록 고치고, 전송 헤더가 필요한 리스너는 동기 실행으로 선언한다. - 확장 업데이트 실패 시 상태만 되돌리고 상태 캐시를 비우지 않아, 그 확장의 관리자 화면만 캐시 TTL(기본 하루) 동안 404 로 남았다. 실패 경로에도 무효화를 대칭으로 두고, 빈 목록 자체를 캐시하지 않는다. - 글 작성 시 첨부 파일이 Service 로 전달되지 않아 검증·권한은 통과하고 첨부만 사라졌다. - 환경설정 저장 실패 안내가 내부 설정 키를 그대로 노출했다(105개 항목에 라벨 부여). 재발 방지: - audit 룰 3종(레이아웃 경계 리터럴 / FormRequest 경계 불일치 / Service 재클램프) - 테스트 실행 범위 강제 훅(check-test-scope) - 트러블슈팅 사례 2건(큐 Job 요청 오염 / 확장 상태 캐시 고착) 공개 이슈: gnuboard/g7
1376 lines
53 KiB
JSON
1376 lines
53 KiB
JSON
{
|
|
"version": "1.0.0",
|
|
"layout_name": "admin_user_detail",
|
|
"permissions": [
|
|
"core.users.read"
|
|
],
|
|
"extends": "_admin_base",
|
|
"meta": {
|
|
"title": "$t:admin.users.detail.page_title",
|
|
"description": "$t:admin.users.detail.page_description"
|
|
},
|
|
"data_sources": [
|
|
{
|
|
"id": "user",
|
|
"label_key": "$t:editor.data_source.user",
|
|
"type": "api",
|
|
"endpoint": "/api/admin/users/{{route?.id}}",
|
|
"method": "GET",
|
|
"auto_fetch": true,
|
|
"auth_required": true
|
|
}
|
|
],
|
|
"errorHandling": {
|
|
"403": {
|
|
"handler": "showErrorPage",
|
|
"params": {
|
|
"target": "content"
|
|
}
|
|
},
|
|
"404": {
|
|
"handler": "showErrorPage",
|
|
"params": {
|
|
"target": "content"
|
|
}
|
|
}
|
|
},
|
|
"state": {
|
|
"activeTab": "basic_info"
|
|
},
|
|
"slots": {
|
|
"content": [
|
|
{
|
|
"id": "user_detail_content",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "admin-page-content"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "page_header",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "page-header-fullbleed"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-between"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "H1",
|
|
"props": {
|
|
"className": "page-title"
|
|
},
|
|
"text": "$t:admin.users.detail.page_title"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "P",
|
|
"props": {
|
|
"className": "page-description"
|
|
},
|
|
"text": "$t:admin.users.detail.page_description_with_info|name={{user?.data?.name ?? ''}}|email={{user?.data?.email ?? ''}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "header_back_button",
|
|
"type": "basic",
|
|
"name": "Button",
|
|
"props": {
|
|
"className": "flex-center gap-2 btn btn-secondary"
|
|
},
|
|
"actions": [
|
|
{
|
|
"type": "click",
|
|
"handler": "navigateBack"
|
|
}
|
|
],
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "arrow-left",
|
|
"className": "text-base"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"text": "$t:common.back"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "header_edit_button",
|
|
"type": "basic",
|
|
"name": "Button",
|
|
"props": {
|
|
"disabled": "{{user?.data?.abilities?.can_update !== true}}",
|
|
"className": "flex-center gap-2 px-4 py-2 bg-blue-600 dark:bg-blue-500 text-white rounded-lg hover:bg-blue-700 dark:hover:bg-blue-600 font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
|
},
|
|
"actions": [
|
|
{
|
|
"type": "click",
|
|
"handler": "navigate",
|
|
"params": {
|
|
"path": "/admin/users/{{route?.id}}/edit",
|
|
"mergeQuery": true,
|
|
"query": {}
|
|
}
|
|
}
|
|
],
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "pencil",
|
|
"className": "text-base"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"text": "$t:admin.users.detail.edit"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "header_unlock_button",
|
|
"type": "basic",
|
|
"name": "Button",
|
|
"if": "{{user?.data?.is_locked === true}}",
|
|
"props": {
|
|
"disabled": "{{user?.data?.abilities?.can_update !== true}}",
|
|
"className": "flex-center gap-2 btn btn-warning"
|
|
},
|
|
"actions": [
|
|
{
|
|
"type": "click",
|
|
"handler": "apiCall",
|
|
"auth_required": true,
|
|
"target": "/api/admin/users/{{route?.id}}/unlock",
|
|
"params": {
|
|
"method": "POST"
|
|
},
|
|
"onSuccess": [
|
|
{
|
|
"handler": "refetchDataSource",
|
|
"params": {
|
|
"dataSourceId": "user"
|
|
}
|
|
},
|
|
{
|
|
"handler": "toast",
|
|
"params": {
|
|
"type": "success",
|
|
"message": "$t:admin.users.detail.unlock_success"
|
|
}
|
|
}
|
|
],
|
|
"onError": [
|
|
{
|
|
"handler": "toast",
|
|
"params": {
|
|
"type": "error",
|
|
"message": "{{error.message}}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "unlock",
|
|
"className": "text-base"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"text": "$t:admin.users.detail.unlock"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "user_detail_tabs",
|
|
"type": "composite",
|
|
"name": "TabNavigationScroll",
|
|
"props": {
|
|
"className": "sticky-tab-nav tab-nav-default",
|
|
"activeTabId": "{{_local.activeTab ?? 'basic_info'}}",
|
|
"enableScrollSpy": true,
|
|
"scrollSpyOffset": 56,
|
|
"sectionIdPrefix": "",
|
|
"tabs": [
|
|
{
|
|
"id": "basic_info",
|
|
"label": "$t:admin.users.detail.tabs.basic_info"
|
|
},
|
|
{
|
|
"id": "contact_info",
|
|
"label": "$t:admin.users.detail.tabs.contact_info"
|
|
},
|
|
{
|
|
"id": "location_info",
|
|
"label": "$t:admin.users.detail.tabs.location_info"
|
|
},
|
|
{
|
|
"id": "profile_memo",
|
|
"label": "$t:admin.users.detail.tabs.profile_memo"
|
|
},
|
|
{
|
|
"id": "activity_info",
|
|
"label": "$t:admin.users.detail.tabs.activity_info"
|
|
},
|
|
{
|
|
"id": "consent_info",
|
|
"label": "$t:admin.users.detail.tabs.consent_info"
|
|
}
|
|
]
|
|
},
|
|
"actions": [
|
|
{
|
|
"type": "change",
|
|
"handler": "setState",
|
|
"params": {
|
|
"target": "local",
|
|
"activeTab": "{{$event.value}}"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "user_api_error",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"if": "{{_dataSourceErrors?.user}}",
|
|
"props": {
|
|
"className": "alert-danger"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-3"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "triangle-exclamation",
|
|
"className": "text-xl text-red-600 dark:text-red-400 flex-shrink-0"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "text-error-strong"
|
|
},
|
|
"text": "$t:admin.users.detail.error_loading_user"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "P",
|
|
"props": {
|
|
"className": "text-error-soft mt-1"
|
|
},
|
|
"text": "{{_dataSourceErrors?.user?.message ?? '$t:common.error_occurred'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "section_basic_info",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"id": "basic_info",
|
|
"className": "admin-card"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2 mb-4"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "user",
|
|
"className": "text-secondary text-xl"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "section-heading"
|
|
},
|
|
"text": "$t:admin.users.form.sections.basic_info"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "row-stack"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_uuid",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "UUID"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm font-mono"
|
|
},
|
|
"text": "{{user?.data?.uuid ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_name",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.name"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.name ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_nickname",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.nickname"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.nickname ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_roles",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.role"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex flex-wrap gap-1"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"iteration": {
|
|
"source": "user?.data?.roles ?? []",
|
|
"item_var": "role"
|
|
},
|
|
"props": {
|
|
"className": "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200"
|
|
},
|
|
"text": "{{role.name}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_status",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.status"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"props": {
|
|
"className": "{{user?.data?.status_variant === 'success' ? 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' : user?.data?.status_variant === 'secondary' ? 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200' : user?.data?.status_variant === 'danger' ? 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' : 'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200'}}"
|
|
},
|
|
"text": "{{user?.data?.status_label ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_email_verified",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.detail.email_verification"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-1"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"condition": "{{user?.data?.email_verified_at}}",
|
|
"props": {
|
|
"name": "check-circle",
|
|
"className": "text-base text-green-500"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.email_verified_at ? '$t:admin.users.form.fields.email_verified' : '$t:admin.users.detail.not_verified'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "section_contact_info",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"id": "contact_info",
|
|
"className": "admin-card"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2 mb-4"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "envelope",
|
|
"className": "text-secondary text-xl"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "section-heading"
|
|
},
|
|
"text": "$t:admin.users.form.sections.contact_info"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "row-stack"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_email",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.email"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.email ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_homepage",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.homepage"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.homepage ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_mobile",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.mobile"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.mobile ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_phone",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.phone"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.phone ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "section_location_info",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"id": "location_info",
|
|
"className": "admin-card"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2 mb-4"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "map-pin",
|
|
"className": "text-secondary text-xl"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "section-heading"
|
|
},
|
|
"text": "$t:admin.users.form.sections.location_info"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "row-stack"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_country",
|
|
"if": false,
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.country"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.country_name ?? user?.data?.country ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_language",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.language"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"if": "{{user?.data?.language}}",
|
|
"props": {
|
|
"className": "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-200"
|
|
},
|
|
"text": "{{user?.data?.language_label ?? user?.data?.language ?? '-'}}"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"if": "{{!user?.data?.language}}",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "-"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_timezone",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.timezone"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.timezone ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_address",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.address"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.zipcode || user?.data?.address || user?.data?.address_detail ? ((user?.data?.zipcode ? '(' + user.data.zipcode + ') ' : '') + (user?.data?.address ?? '') + (user?.data?.address_detail ? ' ' + user.data.address_detail : '')) : '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "section_profile_memo",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"id": "profile_memo",
|
|
"className": "admin-card"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2 mb-4"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "user-circle",
|
|
"className": "text-secondary text-xl"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "section-heading"
|
|
},
|
|
"text": "$t:admin.users.form.sections.profile_memo"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "row-stack"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_signature",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.signature"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.signature ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_bio",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.bio"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm whitespace-pre-line"
|
|
},
|
|
"text": "{{user?.data?.bio ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_admin_memo",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.admin_memo"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm whitespace-pre-line"
|
|
},
|
|
"text": "{{user?.data?.admin_memo ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "section_activity_info",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"id": "activity_info",
|
|
"className": "admin-card"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2 mb-4"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "clock",
|
|
"className": "text-secondary text-xl"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "section-heading"
|
|
},
|
|
"text": "$t:admin.users.form.sections.activity_info"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "row-stack"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_created_at",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.created_at"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.created_at ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_last_login_at",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.last_login_at"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.last_login_at ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_lock_status",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.lock_status"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"if": "{{user?.data?.locked_permanently === true}}",
|
|
"props": {
|
|
"className": "text-error-soft text-sm"
|
|
},
|
|
"text": "$t:admin.users.detail.locked_permanently_value"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"if": "{{user?.data?.locked_permanently !== true && user?.data?.is_locked === true}}",
|
|
"props": {
|
|
"className": "text-error-soft text-sm"
|
|
},
|
|
"text": "$t:admin.users.detail.locked_until_value|until={{user?.data?.locked_until ?? ''}}"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"if": "{{user?.data?.is_locked !== true}}",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "$t:admin.users.detail.not_locked_value"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_ip_address",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.form.fields.ip_address"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.ip_address ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_withdrawn_at",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.detail.withdrawn_at"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.withdrawn_at ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_blocked_at",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.detail.blocked_at"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.blocked_at ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "section_consent_info",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"id": "consent_info",
|
|
"className": "admin-card"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "flex-center gap-2 mb-4"
|
|
},
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Icon",
|
|
"props": {
|
|
"name": "file-contract",
|
|
"className": "text-secondary text-xl"
|
|
}
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "H3",
|
|
"props": {
|
|
"className": "section-heading"
|
|
},
|
|
"text": "$t:admin.users.detail.consent_history"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "grid-2col-responsive"
|
|
},
|
|
"children": [
|
|
{
|
|
"id": "field_terms_consent",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.detail.consent_type.terms"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.terms_consent?.agreed_at ?? '-'}}"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "field_privacy_consent",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"children": [
|
|
{
|
|
"type": "basic",
|
|
"name": "Label",
|
|
"props": {
|
|
"className": "text-label-subtle block font-medium mb-1"
|
|
},
|
|
"text": "$t:admin.users.detail.consent_type.privacy"
|
|
},
|
|
{
|
|
"type": "basic",
|
|
"name": "Span",
|
|
"props": {
|
|
"className": "text-primary text-sm"
|
|
},
|
|
"text": "{{user?.data?.privacy_consent?.agreed_at ?? '-'}}"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"id": "extension_tab_content",
|
|
"type": "basic",
|
|
"name": "Div",
|
|
"props": {
|
|
"className": "tab-content mt-6"
|
|
},
|
|
"comment": "확장(모듈/플러그인)이 inject_props로 탭을 추가하고 append_child로 섹션 콘텐츠를 주입하는 영역"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"transition_overlay": {
|
|
"wait_for": [
|
|
"user"
|
|
]
|
|
}
|
|
}
|