krgm.so-manager-dev.com/resources/views/admin/news/add.blade.php
你的名字 77d3cc2ec3
All checks were successful
Deploy main / deploy (push) Successful in 22s
【最新ニュース登録】画面修正
2025-10-02 10:00:15 +09:00

204 lines
9.1 KiB
PHP

@extends('layouts.app')
@section('title', 'ニュース新規作成')
@section('content')
{{-- コンテンツヘッダー(パンくず) --}}
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-lg-6"><h1 class="m-0 text-dark">新規</h1></div>
<div class="col-lg-6">
<ol class="breadcrumb float-sm-right text-sm">
<li class="breadcrumb-item"><a href="{{ route('home') }}">ホーム</a></li>
<li class="breadcrumb-item"><a href="{{ route('news') }}">最新ニュース登録</a></li>
<li class="breadcrumb-item active">新規</li>
</ol>
</div>
</div>
</div>
</div>
<section class="content">
<div class="container-fluid">
{{-- バリデーションエラー表示 --}}
@if ($errors->any())
<div class="alert alert-danger"><ul class="mb-0">@foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach</ul></div>
@endif
{{-- 成功メッセージ表示 --}}
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
{{-- 入力フォーム --}}
<div class="card">
<div class="card-body">
<form method="post" action="{{ route('news_add') }}" id="news-add-form">
@csrf
{{-- 基本情報 --}}
<div class="form-group">
<label>ニュース内容 <span class="text-danger">*</span></label>
<textarea name="news" class="form-control" rows="8" required>{{ old('news') }}</textarea>
</div>
<div class="form-group">
<label>公開日時 <span class="text-danger">*</span></label>
<input type="text" name="open_datetime" class="form-control" placeholder="YYYY-MM-DD HH:MM:SS"
value="{{ old('open_datetime') }}" required>
</div>
<div class="form-group">
<label>リンクURL</label>
<input type="text" name="link_url" class="form-control" value="{{ old('link_url') }}">
</div>
{{-- 画像操作ボタン行:左=画像1、右=画像2 --}}
<div class="row mb-3">
<div class="col-md-6 mb-2">
<div class="btn-group">
<button type="button" class="btn btn-default" id="btn-image1-upload">画像1アップロード</button>
<button type="button" class="btn btn-default" id="btn-image1-clear">画像1削除</button>
</div>
<input type="file" id="file-image1" accept="image/*" class="d-none">
</div>
<div class="col-md-6 mb-2">
<div class="btn-group">
<button type="button" class="btn btn-default" id="btn-image2-upload">画像2アップロード</button>
<button type="button" class="btn btn-default" id="btn-image2-clear">画像2削除</button>
</div>
<input type="file" id="file-image2" accept="image/*" class="d-none">
</div>
</div>
{{-- 画像ボックス:左=画像1、右=画像2 --}}
<div class="row">
<div class="col-md-6">
<div class="imgbox mb-3">
<div class="imgbox-title">画像1</div>
<div class="mb-2">
<label class="small text-muted d-block mb-1">画像1URLスペース</label>
<input type="text" name="image1_filename" id="image1_url" class="form-control" placeholder="http(s)://..." value="{{ old('image1_filename') }}">
</div>
<div>
<label class="small text-muted d-block mb-1">画像1表示スペース</label>
<div class="imgbox-preview">
<img id="image1_preview" src="{{ old('image1_filename') }}" alt="" style="display: {{ old('image1_filename') ? 'block' : 'none' }};">
<span id="image1_placeholder" class="text-muted" style="display: {{ old('image1_filename') ? 'none' : 'block' }};">プレビューなし</span>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="imgbox mb-3">
<div class="imgbox-title">画像2</div>
<div class="mb-2">
<label class="small text-muted d-block mb-1">画像2URLスペース</label>
<input type="text" name="image2_filename" id="image2_url" class="form-control" placeholder="http(s)://..." value="{{ old('image2_filename') }}">
</div>
<div>
<label class="small text-muted d-block mb-1">画像2表示スペース</label>
<div class="imgbox-preview">
<img id="image2_preview" src="{{ old('image2_filename') }}" alt="" style="display: {{ old('image2_filename') ? 'block' : 'none' }};">
<span id="image2_placeholder" class="text-muted" style="display: {{ old('image2_filename') ? 'none' : 'block' }};">プレビューなし</span>
</div>
</div>
</div>
</div>
</div>
{{-- 表示モード(デフォルト:非表示) --}}
<div class="form-group mt-3">
<label class="d-block">表示モード <span class="text-danger">*</span></label>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_draft" value="2" required
@checked(old('mode','0')=='2')>
<label class="form-check-label" for="mode_draft">下書き(非表示)</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_public" value="1"
@checked(old('mode','0')=='1')>
<label class="form-check-label" for="mode_public">公開</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_auto" value="3"
@checked(old('mode','0')=='3')>
<label class="form-check-label" for="mode_auto">自動公開</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="mode" id="mode_hidden" value="0"
@checked(old('mode','0')=='0')>
<label class="form-check-label" for="mode_hidden">非表示</label>
</div>
</div>
<div class="text-right">
<a href="{{ route('news') }}" class="btn btn-default">戻る</a>
<!-- 変更点: class="register" を付与して app.js の汎用確認を使用 -->
<button type="button" class="btn btn-default register" id="register-btn">登録</button>
</div>
</form>
</div>
</div>
</div>
</section>
@endsection
@push('styles')
<style>
/* 画像ボックスの体裁 */
.imgbox { border:1px solid #ced4da; border-radius:.25rem; }
.imgbox-title { background:#f4f6f9; border-bottom:1px solid #ced4da; padding:.5rem .75rem; font-weight:600; }
.imgbox-preview {
border:1px solid #ced4da; border-radius:.25rem; background:#f8f9fa;
height:200px; display:flex; align-items:center; justify-content:center; overflow:hidden;
}
.imgbox-preview img { max-width:100%; max-height:100%; display:block; }
</style>
@endpush
@push('scripts')
<script>
// 画像プレビュー系のみ(確認ダイアログは app.js に委譲)
(function(){
function bindUrlPreview(urlId, imgId, phId) {
const url = document.getElementById(urlId);
const img = document.getElementById(imgId);
const ph = document.getElementById(phId);
if (!url || !img || !ph) return;
function update(){
const v = (url.value || '').trim();
if (v) { img.src = v; img.style.display='block'; ph.style.display='none'; }
else { img.removeAttribute('src'); img.style.display='none'; ph.style.display='block'; }
}
url.addEventListener('input', update); update();
}
function bindUpload(btnId, fileId, urlId, imgId, phId, clearBtnId){
const btn = document.getElementById(btnId);
const file= document.getElementById(fileId);
const url = document.getElementById(urlId);
const img = document.getElementById(imgId);
const ph = document.getElementById(phId);
const clr = document.getElementById(clearBtnId);
if (!btn || !file || !url || !img || !ph || !clr) return;
btn.addEventListener('click', ()=> file.click());
file.addEventListener('change', ()=>{
const f = file.files && file.files[0]; if (!f) return;
const reader = new FileReader();
reader.onload = e => { img.src = e.target.result; img.style.display='block'; ph.style.display='none'; };
reader.readAsDataURL(f);
});
clr.addEventListener('click', ()=>{
file.value=''; url.value='';
img.removeAttribute('src'); img.style.display='none'; ph.style.display='block';
});
}
bindUrlPreview('image1_url','image1_preview','image1_placeholder');
bindUrlPreview('image2_url','image2_preview','image2_placeholder');
bindUpload('btn-image1-upload','file-image1','image1_url','image1_preview','image1_placeholder','btn-image1-clear');
bindUpload('btn-image2-upload','file-image2','image2_url','image2_preview','image2_placeholder','btn-image2-clear');
})();
</script>
@endpush