功能:留言板新建留言改为弹窗形式,并新增用户选择下拉列表
- GuestbookController::index() 追加传入 $users 用户名列表 - 顶部内联展开表单改为居中 Modal 弹窗,带遮罩层和过渡动画 - 收件人从普通文本输入改为下拉选择器(含全部注册用户) - 悄悄话改为 toggle 开关样式 - 增加顶级渐变色标题栏
This commit is contained in:
@@ -58,7 +58,13 @@ class GuestbookController extends Controller
|
||||
// 获取收件人默认值 (比如点击他人名片的"写私信"转跳过来)
|
||||
$defaultTo = $request->input('to', '');
|
||||
|
||||
return view('guestbook.index', compact('messages', 'tab', 'defaultTo'));
|
||||
// 获取所有用户名列表(供写信弹窗的收件人选择器使用)
|
||||
$users = User::where('username', '!=', $user->username)
|
||||
->orderBy('username')
|
||||
->pluck('username');
|
||||
|
||||
return view('guestbook.index', compact('messages', 'tab', 'defaultTo', 'users'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,43 +30,102 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- 写信/留言表单区 (Alpine 控制显隐) --}}
|
||||
<div x-show="showWriteForm" x-collapse class="bg-indigo-50/50 border-b border-indigo-100 shadow-sm relative z-10">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
|
||||
<form action="{{ route('guestbook.store') }}" method="POST" class="space-y-4">
|
||||
{{-- 弹窗遮罩层 --}}
|
||||
<div x-show="showWriteForm" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100" x-transition:leave="transition ease-in duration-150"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
||||
class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4"
|
||||
@click.self="showWriteForm = false" style="display: none;">
|
||||
|
||||
{{-- 对话框 --}}
|
||||
<div x-show="showWriteForm" x-transition:enter="transition ease-out duration-200"
|
||||
x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 scale-100"
|
||||
x-transition:leave-end="opacity-0 scale-95"
|
||||
class="bg-white rounded-2xl shadow-2xl w-full max-w-xl overflow-hidden">
|
||||
|
||||
{{-- 弹窗头部 --}}
|
||||
<div class="bg-gradient-to-r from-indigo-600 to-indigo-500 px-6 py-4 flex justify-between items-center">
|
||||
<div class="flex items-center space-x-2">
|
||||
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z">
|
||||
</path>
|
||||
</svg>
|
||||
<h3 class="text-white font-bold text-lg">撰写留言</h3>
|
||||
</div>
|
||||
<button @click="showWriteForm = false" class="text-white/70 hover:text-white transition">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- 表单内容 --}}
|
||||
<form action="{{ route('guestbook.store') }}" method="POST" class="p-6 space-y-5">
|
||||
@csrf
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="flex-1">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">接收人 (留空或填"大家"表示公共留言)</label>
|
||||
<input type="text" name="towho" x-model="towho" placeholder="系统自动处理"
|
||||
class="w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||
</div>
|
||||
<div class="flex items-center h-full pt-6">
|
||||
<label
|
||||
class="flex items-center space-x-2 text-sm text-gray-700 cursor-pointer bg-pink-50 px-3 py-2 rounded-md hover:bg-pink-100 transition border border-pink-100">
|
||||
<input type="checkbox" name="secret" value="1"
|
||||
class="rounded text-pink-500 focus:ring-pink-500 w-4 h-4">
|
||||
<span class="font-bold text-pink-700">🔒 悄悄话 (仅双方可见)</span>
|
||||
</label>
|
||||
|
||||
{{-- 收件人选择 --}}
|
||||
<div>
|
||||
<label class="block text-sm font-semibold text-gray-700 mb-2">
|
||||
📬 收件人
|
||||
<span class="font-normal text-gray-400 ml-1">(留空则为公共留言)</span>
|
||||
</label>
|
||||
<div class="relative">
|
||||
<select name="towho" x-model="towho"
|
||||
class="w-full border-gray-200 rounded-xl py-2.5 px-4 focus:ring-indigo-500 focus:border-indigo-500 text-sm appearance-none bg-gray-50 pr-10">
|
||||
<option value="">🌍 公共留言(所有人可见)</option>
|
||||
@foreach ($users as $uname)
|
||||
<option value="{{ $uname }}" :selected="towho === '{{ $uname }}'">👤
|
||||
{{ $uname }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="pointer-events-none absolute inset-y-0 right-3 flex items-center">
|
||||
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M19 9l-7 7-7-7"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 您您话开关 --}}
|
||||
<label class="flex items-center space-x-3 cursor-pointer group">
|
||||
<div class="relative">
|
||||
<input type="checkbox" name="secret" value="1" class="sr-only peer">
|
||||
<div class="w-10 h-6 bg-gray-200 rounded-full peer-checked:bg-pink-500 transition-colors"></div>
|
||||
<div
|
||||
class="absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full shadow transition-transform peer-checked:translate-x-4">
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-sm font-medium text-gray-700 group-hover:text-pink-600 transition-colors">🔒
|
||||
您您话(仅双方可见)</span>
|
||||
</label>
|
||||
|
||||
{{-- 正文 --}}
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">正文内容 <span
|
||||
class="text-red-500">*</span></label>
|
||||
<textarea name="text_body" x-ref="textBody" rows="3" required
|
||||
class="w-full border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||
<label class="block text-sm font-semibold text-gray-700 mb-2">
|
||||
📝 留言内容 <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<textarea name="text_body" x-ref="textBody" rows="5" required
|
||||
class="w-full border-gray-200 rounded-xl p-4 focus:ring-indigo-500 focus:border-indigo-500 text-sm bg-gray-50 resize-none"
|
||||
placeholder="相逢何必曾相识,留下您的足迹吧..."></textarea>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
{{-- 操作按钮 --}}
|
||||
<div class="flex justify-end space-x-3 pt-2">
|
||||
<button type="button" @click="showWriteForm = false"
|
||||
class="px-5 py-2.5 text-sm font-medium text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-xl transition">
|
||||
取消
|
||||
</button>
|
||||
<button type="submit"
|
||||
class="bg-indigo-600 hover:bg-indigo-700 text-white py-2 px-6 rounded-md shadow flex items-center font-bold">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
class="px-6 py-2.5 text-sm font-bold text-white bg-indigo-600 hover:bg-indigo-700 rounded-xl shadow-md hover:shadow-lg transition-all transform hover:-translate-y-0.5 flex items-center">
|
||||
<svg class="w-4 h-4 mr-1.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
|
||||
</svg>
|
||||
发送
|
||||
发送飞鸽
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -166,7 +225,8 @@
|
||||
<button
|
||||
@click="showWriteForm = true; towho = '{{ $msg->who }}'; setTimeout(() => $refs.textBody.focus(), 100); window.scrollTo({top:0, behavior:'smooth'})"
|
||||
class="text-xs text-indigo-500 hover:text-indigo-700 font-medium flex items-center transition">
|
||||
<svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg class="w-3 h-3 mr-1" fill="none" stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"></path>
|
||||
</svg>
|
||||
@@ -181,7 +241,8 @@
|
||||
<span class="text-6xl drop-shadow-sm mb-6">📭</span>
|
||||
<h3 class="text-xl font-bold text-gray-800 tracking-wide">暂无信件</h3>
|
||||
<p class="mt-3 text-gray-400">这里是空空如也的荒原。</p>
|
||||
<button @click="showWriteForm = true; towho = ''; setTimeout(() => $refs.textBody.focus(), 100)"
|
||||
<button
|
||||
@click="showWriteForm = true; towho = ''; setTimeout(() => $refs.textBody.focus(), 100)"
|
||||
class="mt-8 bg-indigo-50 hover:bg-indigo-100 text-indigo-600 font-bold py-2.5 px-6 rounded-xl transition-colors border border-indigo-100/50">
|
||||
来抢沙发留言吧!
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user