feat: [academy] 프론트엔드 개발 백과사전 SVG 이미지 + 도움말 풍선 추가
- 섹션별 SVG 일러스트 10개를 주요 위치에 삽입 (5~10.svg) - 도움말 풍선(?) 트리거 8개 추가 (핵심 개념 설명) - toggleBalloon() JavaScript 함수 및 외부 클릭 닫기 구현
This commit is contained in:
@@ -84,6 +84,82 @@
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* 도움말 풍선 */
|
||||
.help-balloon-trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background: #ede9fe;
|
||||
color: #7c3aed;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
border: 1.5px solid #c4b5fd;
|
||||
vertical-align: middle;
|
||||
margin-left: 4px;
|
||||
transition: all 0.15s ease;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
.help-balloon-trigger:hover {
|
||||
background: #7c3aed;
|
||||
color: white;
|
||||
border-color: #6d28d9;
|
||||
}
|
||||
.help-balloon {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: calc(100% + 10px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%) scale(0.95);
|
||||
background: #1e293b;
|
||||
color: #f1f5f9;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 1.6;
|
||||
padding: 10px 14px;
|
||||
border-radius: 10px;
|
||||
max-width: 300px;
|
||||
min-width: 200px;
|
||||
width: max-content;
|
||||
white-space: normal;
|
||||
word-break: keep-all;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||
z-index: 40;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease, transform 0.15s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
.help-balloon::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: 7px solid transparent;
|
||||
border-top-color: #1e293b;
|
||||
}
|
||||
.help-balloon-trigger.is-active .help-balloon {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) scale(1);
|
||||
pointer-events: auto;
|
||||
}
|
||||
/* 풍선이 왼쪽으로 넘치지 않도록 */
|
||||
.help-balloon-trigger.is-active .help-balloon.balloon-right {
|
||||
left: auto;
|
||||
right: -10px;
|
||||
transform: scale(1);
|
||||
}
|
||||
.help-balloon-trigger.is-active .help-balloon.balloon-right::after {
|
||||
left: auto;
|
||||
right: 14px;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* 코드 블록 스타일 */
|
||||
.code-block {
|
||||
background: #1e1e2e;
|
||||
@@ -122,19 +198,10 @@
|
||||
<p class="text-sm" style="color: #cbd5e1;">HTML, CSS, JavaScript부터 프레임워크, 성능 최적화까지 — 비개발자도 이해하는 프론트엔드 가이드</p>
|
||||
</div>
|
||||
<div class="shrink-0" style="width: 240px; padding: 1.5rem;">
|
||||
<div class="overflow-hidden rounded-xl flex items-center justify-center" style="background: rgba(139,92,246,0.15); height: 160px;">
|
||||
<svg style="width: 120px; height: 120px;" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="15" y="20" width="90" height="65" rx="6" stroke="#c4b5fd" stroke-width="2.5" fill="none"/>
|
||||
<rect x="25" y="30" width="35" height="8" rx="2" fill="#a78bfa" opacity="0.6"/>
|
||||
<rect x="25" y="42" width="55" height="5" rx="1.5" fill="#7c3aed" opacity="0.4"/>
|
||||
<rect x="25" y="50" width="45" height="5" rx="1.5" fill="#7c3aed" opacity="0.3"/>
|
||||
<rect x="25" y="58" width="50" height="5" rx="1.5" fill="#7c3aed" opacity="0.2"/>
|
||||
<rect x="65" y="30" width="18" height="18" rx="3" fill="#8b5cf6" opacity="0.5"/>
|
||||
<line x1="15" y1="72" x2="105" y2="72" stroke="#c4b5fd" stroke-width="1.5"/>
|
||||
<circle cx="60" cy="78" r="2.5" fill="#c4b5fd"/>
|
||||
<rect x="40" y="85" width="40" height="4" rx="2" fill="#c4b5fd" opacity="0.5"/>
|
||||
<text x="60" y="105" text-anchor="middle" fill="#c4b5fd" font-size="10" font-family="monospace"></></text>
|
||||
</svg>
|
||||
<div class="overflow-hidden rounded-xl">
|
||||
<img src="{{ asset('images/academy/frontend-dev/1.svg') }}" alt="코드 에디터와 브라우저 프리뷰"
|
||||
class="w-full rounded-xl cursor-pointer academy-img-hover"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -229,6 +296,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
프론트엔드 vs 백엔드
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">프론트엔드는 사용자의 브라우저에서 실행되는 코드(HTML, CSS, JS)이고, 백엔드는 서버에서 실행되는 코드(PHP, Python 등)다. 둘은 API를 통해 데이터를 주고받는다.</span></span>
|
||||
</h3>
|
||||
<div class="bg-purple-50 rounded-lg p-5 border border-purple-100 mb-4">
|
||||
<p class="text-sm text-purple-900 leading-relaxed">
|
||||
@@ -294,13 +362,20 @@
|
||||
<p class="text-yellow-700">전기 배선<br>스위치를 누르면 조명이 켜진다</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-purple-50 rounded-lg p-4 border border-purple-100">
|
||||
<div class="bg-purple-50 rounded-lg p-4 border border-purple-100 mb-4">
|
||||
<p class="text-xs text-purple-800 leading-relaxed">
|
||||
<strong>SAM 시스템의 프론트엔드:</strong>
|
||||
SAM도 프론트엔드와 백엔드로 분리되어 있다. MNG(관리자 웹)는 Blade + HTMX로, React 앱은 Next.js로 화면을 구성하고,
|
||||
API 서버(Laravel)가 데이터를 처리한다.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mb-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/2.svg') }}" alt="프론트엔드 vs 백엔드 비교 다이어그램"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">프론트엔드와 백엔드 — 식당의 홀과 주방</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -413,6 +488,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
시맨틱 태그
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">시맨틱(Semantic)은 "의미를 가진"이라는 뜻이다. <div> 대신 <header>, <nav>, <main> 등을 사용하면 검색엔진과 스크린리더가 페이지 구조를 이해할 수 있다.</span></span>
|
||||
</h3>
|
||||
<p class="text-sm text-gray-700 mb-3">
|
||||
시맨틱(Semantic) 태그는 "의미가 있는" 태그다. <code><div></code>만 쓰면 검색엔진이나 스크린리더가 내용을 이해하기 어렵다.
|
||||
@@ -443,6 +519,13 @@
|
||||
브라우저는 HTML을 읽어 위와 같은 트리(나무) 구조로 변환한다. 이를 <strong>DOM(Document Object Model)</strong>이라 한다.
|
||||
</p>
|
||||
</div>
|
||||
<div class="mb-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/3.svg') }}" alt="HTML DOM 트리 구조 다이어그램"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">DOM 트리 — HTML 문서의 구조</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -462,6 +545,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
선택자와 박스모델
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">선택자(Selector)는 "어떤 HTML 요소에 스타일을 적용할지" 지정하는 규칙이다. 박스모델은 모든 요소가 content → padding → border → margin 4겹 상자로 구성된다는 개념이다.</span></span>
|
||||
</h3>
|
||||
<div class="bg-amber-50 rounded-lg p-4 border border-amber-100 mb-4">
|
||||
<p class="font-semibold text-amber-800 mb-2">비유: 인테리어 디자인</p>
|
||||
@@ -495,11 +579,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/4.svg') }}" alt="CSS 박스모델 다이어그램"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 300px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-6 text-center">CSS 박스모델 — margin, border, padding, content</p>
|
||||
|
||||
<!-- 3-2. Flexbox와 Grid -->
|
||||
<div id="css-layout" class="scroll-mt-20 mb-4">
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
Flexbox와 Grid
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">Flexbox는 한 방향(가로 또는 세로)으로 요소를 나열할 때 사용하고, Grid는 가로+세로 2차원으로 배치할 때 사용한다. SAM에서는 Tailwind CSS의 flex/grid 클래스를 활용한다.</span></span>
|
||||
</h3>
|
||||
<p class="text-sm text-gray-700 mb-3">
|
||||
현대 CSS 레이아웃의 두 기둥이다. 요소를 가로/세로로 배치하는 강력한 도구다.
|
||||
@@ -581,6 +674,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
DOM 조작과 비동기 통신
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">DOM 조작은 JavaScript로 화면의 내용을 동적으로 변경하는 것이다. 비동기 통신(fetch)은 페이지 새로고침 없이 서버에서 데이터를 가져오는 기술이다.</span></span>
|
||||
</h3>
|
||||
<p class="text-sm text-gray-700 mb-3">
|
||||
JavaScript는 DOM(문서 객체)을 조작하여 화면을 동적으로 변경할 수 있다.
|
||||
@@ -602,6 +696,15 @@
|
||||
<code>fetch()</code>, <code>async/await</code>, <code>Promise</code>가 이 역할을 한다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- SVG 일러스트: JavaScript 이벤트 흐름 -->
|
||||
<div class="mt-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/5.svg') }}" alt="JavaScript 이벤트 흐름과 DOM 조작"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">JavaScript 이벤트 처리와 DOM 조작 흐름</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -621,6 +724,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
프레임워크 vs 라이브러리
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">프레임워크는 전체 구조를 제공하고 개발자가 그 안에서 코드를 작성한다. 라이브러리는 필요한 기능만 골라 쓸 수 있는 도구 모음이다.</span></span>
|
||||
</h3>
|
||||
<div class="bg-amber-50 rounded-lg p-4 border border-amber-100 mb-4">
|
||||
<p class="font-semibold text-amber-800 mb-2">비유: 반조립 가구 vs 공구 세트</p>
|
||||
@@ -720,6 +824,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SVG 일러스트: 프레임워크 비교 -->
|
||||
<div class="mt-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/6.svg') }}" alt="프레임워크 비교: React, Vue, Angular"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">React / Vue / Angular 비교와 SAM 아키텍처</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -738,6 +851,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
브레이크포인트와 모바일 퍼스트
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">브레이크포인트는 화면 너비에 따라 레이아웃이 바뀌는 기준점이다. 모바일 퍼스트는 작은 화면부터 디자인한 후 큰 화면으로 확장하는 접근법이다.</span></span>
|
||||
</h3>
|
||||
<div class="bg-amber-50 rounded-lg p-4 border border-amber-100 mb-4">
|
||||
<p class="font-semibold text-amber-800 mb-2">비유: 물은 그릇 모양에 따라 변한다</p>
|
||||
@@ -823,6 +937,15 @@
|
||||
— 이 한 줄이 없으면 모바일에서 데스크톱 크기로 축소되어 보인다. 모든 반응형 페이지의 필수 태그다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- SVG 일러스트: 반응형 디자인 -->
|
||||
<div class="mt-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/7.svg') }}" alt="반응형 디자인: 모바일, 태블릿, 데스크톱"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">모바일 / 태블릿 / 데스크톱 반응형 레이아웃</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -841,6 +964,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
렌더링 파이프라인
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">렌더링 파이프라인은 브라우저가 HTML/CSS/JS 코드를 화면의 픽셀로 변환하는 일련의 처리 과정이다.</span></span>
|
||||
</h3>
|
||||
<div class="bg-amber-50 rounded-lg p-4 border border-amber-100 mb-4">
|
||||
<p class="font-semibold text-amber-800 mb-2">비유: 통역사</p>
|
||||
@@ -917,6 +1041,15 @@
|
||||
</p>
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<!-- SVG 일러스트: 브라우저 렌더링 파이프라인 -->
|
||||
<div class="mt-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/8.svg') }}" alt="브라우저 렌더링 파이프라인"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">HTML 코드가 화면의 픽셀로 변환되는 6단계 과정</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -935,6 +1068,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
REST API와 HTTP 메서드
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">REST API는 URL과 HTTP 메서드(GET/POST/PUT/DELETE)를 조합하여 서버 자원을 조작하는 규약이다. 웹에서 가장 널리 쓰이는 API 설계 방식이다.</span></span>
|
||||
</h3>
|
||||
<div class="bg-amber-50 rounded-lg p-4 border border-amber-100 mb-4">
|
||||
<p class="font-semibold text-amber-800 mb-2">비유: 식당의 주문서</p>
|
||||
@@ -1047,6 +1181,15 @@
|
||||
SAM React 앱은 <code>api.sam-erp.com</code>의 API 서버와 통신한다. MNG에서는 HTMX가 서버에 요청을 보내고 HTML 조각을 받아 화면을 업데이트한다.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- SVG 일러스트: API 요청과 응답 -->
|
||||
<div class="mt-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/9.svg') }}" alt="API 요청과 응답 흐름"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">프론트엔드와 백엔드 간 API 요청/응답 흐름</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1065,6 +1208,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
핵심 도구와 개발 흐름
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">프론트엔드 개발에는 코드 에디터(VS Code), 패키지 관리자(npm), 버전 관리(Git), 번들러(Vite) 등 여러 도구를 조합하여 사용한다.</span></span>
|
||||
</h3>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 text-xs mb-4">
|
||||
<div class="bg-blue-50 rounded-lg p-4 border border-blue-200">
|
||||
@@ -1133,6 +1277,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SVG 일러스트: 개발 워크플로우 -->
|
||||
<div class="mt-5 bg-gray-50 rounded-xl p-4 border flex justify-center academy-img-wrap">
|
||||
<img src="{{ asset('images/academy/frontend-dev/10.svg') }}" alt="개발 워크플로우"
|
||||
class="rounded-lg cursor-pointer academy-img-hover"
|
||||
style="max-height: 320px; width: auto;"
|
||||
onclick="openLightbox(this)">
|
||||
</div>
|
||||
<p class="text-xs text-gray-400 mb-4 text-center">코드 작성부터 배포까지 — 개발 워크플로우</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1151,6 +1304,7 @@
|
||||
<h3 class="text-lg font-semibold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<span class="w-2 h-2 bg-purple-400 rounded-full"></span>
|
||||
Lighthouse와 Core Web Vitals
|
||||
<span class="help-balloon-trigger" onclick="toggleBalloon(this)">?<span class="help-balloon">Lighthouse는 Google이 제공하는 웹 성능 측정 도구이다. Core Web Vitals는 LCP(로딩 속도), FID(반응 속도), CLS(레이아웃 안정성) 3가지 핵심 지표이다.</span></span>
|
||||
</h3>
|
||||
<p class="text-sm text-gray-700 mb-3">
|
||||
<strong>Lighthouse</strong>는 Google이 제공하는 웹 성능 측정 도구다.
|
||||
@@ -1339,6 +1493,28 @@ function hidePreview() {
|
||||
closeLightbox();
|
||||
}
|
||||
});
|
||||
|
||||
// 도움말 풍선 토글
|
||||
window.toggleBalloon = function(el) {
|
||||
var wasActive = el.classList.contains('is-active');
|
||||
// 모든 열린 풍선 닫기
|
||||
document.querySelectorAll('.help-balloon-trigger.is-active').forEach(function(t) {
|
||||
t.classList.remove('is-active');
|
||||
});
|
||||
// 클릭한 풍선만 토글
|
||||
if (!wasActive) {
|
||||
el.classList.add('is-active');
|
||||
}
|
||||
};
|
||||
|
||||
// 풍선 외부 클릭 시 닫기
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!e.target.closest('.help-balloon-trigger')) {
|
||||
document.querySelectorAll('.help-balloon-trigger.is-active').forEach(function(t) {
|
||||
t.classList.remove('is-active');
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user