Files
gtsit/app/Views/admin/posts/form.php
2026-08-18 10:53:58 +09:00

62 lines
7.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<header class="admin-page-heading">
<div><span>CONTENTS</span><h1><?= $post ? '글 수정' : '새 글 작성' ?></h1><p>초안으로 저장하거나 공개 상태로 게시합니다.</p></div>
</header>
<?php if (!empty($mediaExperiment)): ?><div class="admin-experiment-notice"><strong>테스트 기능</strong><span>여러 대표 이미지와 본문 이미지는 테스트 경로의 초안 미리보기에서만 확인합니다. 확인 전 운영 공개는 제한됩니다.</span></div><?php endif; ?>
<?php if ($errors): ?><div class="admin-error" role="alert"><strong>입력 내용을 확인해 주세요.</strong><ul><?php foreach ($errors as $error): ?><li><?= e($error) ?></li><?php endforeach; ?></ul></div><?php endif; ?>
<form class="admin-form" method="post" enctype="multipart/form-data" action="<?= $post ? '/admin/posts/' . e($post['id']) . '/edit' : '/admin/posts/new' ?>">
<?= csrf_field() ?>
<label>제목 <span>*</span><input name="title" value="<?= old('title', $post['title'] ?? '') ?>" required maxlength="200"></label>
<div class="admin-field-grid">
<label>게시글 URL<?php if ($post): ?><input value="/blog/post-<?= e($post['id']) ?>" readonly aria-describedby="post-url-help"><?php else: ?><input value="저장 시 자동 생성" readonly aria-describedby="post-url-help"><?php endif; ?><small id="post-url-help"><?= $post ? '게시글 번호를 기준으로 자동 관리됩니다.' : '저장 후 post-글번호 형식으로 생성됩니다.' ?></small></label>
<label>카테고리<select name="category"><?php $currentCategory=$_POST['category']??$post['category']??'네트워크'; foreach(['네트워크','키폰시스템','CCTV','시공사례'] as $option): ?><option<?= $currentCategory===$option?' selected':'' ?>><?= e($option) ?></option><?php endforeach; ?></select></label>
</div>
<label>목록 요약<textarea name="excerpt" rows="3" maxlength="500"><?= old('excerpt', $post['excerpt'] ?? '') ?></textarea></label>
<?php if (!empty($mediaExperiment)): ?>
<?php
$galleryImages = $post['gallery_images'] ?? [];
$inlineImages = $post['inline_images'] ?? [];
$nextInlineToken = 1;
foreach ($inlineImages as $inlineImage) $nextInlineToken = max($nextInlineToken, (int) $inlineImage['token'] + 1);
?>
<fieldset class="admin-upload-field" data-media-upload="gallery">
<legend>대표 이미지 슬라이드</legend>
<p>최대 6장 · 2장 이상이면 글 상단에서 5초 간격으로 자동 슬라이드됩니다.</p>
<?php if ($galleryImages): ?><div class="admin-media-list"><?php foreach ($galleryImages as $image): ?><article class="admin-media-item"><img src="<?= e($image['file_path']) ?>" alt=""><div><label>대체 텍스트<input name="media_alt[<?= e($image['id']) ?>]" value="<?= e($image['alt_text']) ?>" maxlength="255" required></label><label class="admin-media-delete"><input type="checkbox" name="delete_images[]" value="<?= e($image['id']) ?>"> 이 이미지 삭제</label></div></article><?php endforeach; ?></div><?php endif; ?>
<label>이미지 파일<input type="file" name="gallery_images[]" accept="image/jpeg,image/png,image/webp" multiple data-media-files><small>JPG, PNG, WebP · 파일당 최대 8MB · 최대 6000×6000px</small></label>
<div class="admin-new-media-list" data-media-list aria-live="polite"></div>
</fieldset>
<div class="admin-body-source" data-body-source><label>본문 <span>*</span><textarea name="body" rows="16" required data-post-body><?= old('body', $post['body'] ?? '') ?></textarea><small>JavaScript를 사용할 수 없을 때는 빈 줄로 문단을 나누고 이미지 위치 토큰을 사용합니다.</small></label></div>
<section class="admin-block-editor" data-block-editor data-next-token="<?= e($nextInlineToken) ?>" aria-labelledby="block-editor-title">
<header><div><h2 id="block-editor-title">본문 편집</h2><p>텍스트 문단과 이미지만 사용해 글의 구성을 정리합니다.</p></div><span>본문 이미지 최대 10장</span></header>
<div class="admin-block-list" data-block-list></div>
<div class="admin-block-editor-actions"><button class="button button-secondary" type="button" data-add-text>문단 추가</button><button class="button button-primary" type="button" data-add-image>이미지 추가</button></div>
<p class="admin-block-help">이미지는 JPG, PNG, WebP 형식으로 파일당 8MB·6000×6000px까지 등록할 수 있습니다.</p>
<div data-delete-bin></div>
<div data-inline-media-inventory hidden><?php foreach ($inlineImages as $image): ?><span data-existing-inline data-id="<?= e($image['id']) ?>" data-token="<?= e($image['token']) ?>" data-path="<?= e(url($image['file_path'])) ?>" data-alt="<?= e($image['alt_text']) ?>"></span><?php endforeach; ?></div>
</section>
<?php else: ?>
<fieldset class="admin-upload-field">
<legend>대표 이미지</legend>
<?php if (!empty($post['image_path'])): ?><img src="<?= e($post['image_path']) ?>" alt="<?= e($post['image_alt']) ?>"><p>새 파일을 선택하면 현재 대표 이미지가 교체됩니다.</p><?php endif; ?>
<label>이미지 파일<input type="file" name="image" accept="image/jpeg,image/png,image/webp"><small>JPG, PNG, WebP · 최대 8MB · 최대 6000×6000px</small></label>
<label>대체 텍스트<input name="image_alt" value="<?= old('image_alt', $post['image_alt'] ?? '') ?>" maxlength="255"><small>이미지 내용을 간단히 설명합니다. 이미지를 등록할 때 필수입니다.</small></label>
</fieldset>
<label>본문 <span>*</span><textarea name="body" rows="16" required><?= old('body', $post['body'] ?? '') ?></textarea><small>빈 줄을 기준으로 문단이 구분됩니다.</small></label>
<?php endif; ?>
<div class="admin-field-grid"><label>작성자<input name="author" value="<?= old('author', $post['author'] ?? config('app.legal_name')) ?>" maxlength="100"></label><label>공개 상태<select name="status"><option value="draft"<?= ($_POST['status']??$post['status']??'draft')==='draft'?' selected':'' ?>>초안</option><option value="published"<?= ($_POST['status']??$post['status']??'draft')==='published'?' selected':'' ?>>공개</option></select></label></div>
<div class="admin-form-actions"><button class="button button-primary" type="submit">저장하기</button><?php if (!empty($mediaExperiment)): ?><button class="button button-secondary" type="button" data-open-live-preview>작성 내용 미리보기</button><?php endif; ?><a class="button button-secondary" href="/admin/posts">취소</a></div>
</form>
<?php if (!empty($mediaExperiment)): ?>
<dialog class="admin-live-preview" data-live-preview aria-labelledby="live-preview-title">
<div class="admin-live-preview-shell">
<header><div><span>LIVE PREVIEW</span><h2 id="live-preview-title">작성 내용 미리보기</h2><p>현재 입력 상태를 저장하지 않고 확인합니다.</p></div><button type="button" data-close-live-preview aria-label="미리보기 닫기">×</button></header>
<article class="admin-live-preview-article">
<div class="admin-live-preview-meta"><span data-preview-category></span><strong data-preview-title></strong><small data-preview-author></small></div>
<section class="admin-live-preview-gallery" data-preview-gallery hidden><div data-preview-gallery-main></div><div data-preview-gallery-thumbs></div><p data-preview-gallery-count></p></section>
<div class="admin-live-preview-body" data-preview-body></div>
</article>
</div>
</dialog>
<?php endif; ?>
<?php if ($post): ?><form class="danger-zone" method="post" action="/admin/posts/<?= e($post['id']) ?>/delete" onsubmit="return confirm('이 글을 삭제할까요? 삭제 후 목록에 표시되지 않습니다.');"><?= csrf_field() ?><div><strong>글 삭제</strong><p>게시글을 복구 가능한 삭제 상태로 전환합니다.</p></div><button type="submit">삭제</button></form><?php endif; ?>