202508131442
文字公告
This commit is contained in:
parent
2a1ed6e188
commit
993a965878
@ -8,7 +8,6 @@ enum TextAdColors: string
|
||||
{
|
||||
use HasLabels;
|
||||
|
||||
case Black = 'black';
|
||||
case White = 'white';
|
||||
case Red = 'red';
|
||||
case Green = 'green';
|
||||
@ -17,7 +16,6 @@ enum TextAdColors: string
|
||||
public function labels(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::Black => '黑色',
|
||||
self::White => '白色',
|
||||
self::Red => '紅色',
|
||||
self::Green => '綠色',
|
||||
|
67
app/Jobs/ExportSqliteBroadcastJob.php
Normal file
67
app/Jobs/ExportSqliteBroadcastJob.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\BroadcastTemplate;
|
||||
use App\Services\SqliteExportService;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExportSqliteBroadcastJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $timeout = 600;
|
||||
|
||||
protected ?int $branchId;
|
||||
|
||||
public function __construct(?int $branchId = null)
|
||||
{
|
||||
$this->branchId = $branchId;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$sqlitePath = storage_path('app/database/tempBroadcastTemplate.sqlite');
|
||||
|
||||
if (!file_exists(dirname($sqlitePath))) {
|
||||
mkdir(dirname($sqlitePath), 0755, true);
|
||||
}
|
||||
|
||||
if (!file_exists($sqlitePath)) {
|
||||
file_put_contents($sqlitePath, '');
|
||||
}
|
||||
$connectionName = 'tempsqlite_' . md5($sqlitePath . microtime());
|
||||
config(["database.connections.{$connectionName}" => [
|
||||
'driver' => 'sqlite',
|
||||
'database' => $sqlitePath,
|
||||
'prefix' => '',
|
||||
]]);
|
||||
|
||||
$exporter = new SqliteExportService($connectionName);
|
||||
$exporter->exportMultiple([
|
||||
'broadcast_templates' => [
|
||||
'query' => fn () => DB::table('broadcast_templates'),
|
||||
'tableSchema' => function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('content')->comment('廣告公告');
|
||||
$table->enum('color', ['white', 'red', 'green','blue'])->default('white')->comment('顯示顏色');
|
||||
$table->boolean('is_active')->default(true); // 啟用狀態
|
||||
$table->timestamps();
|
||||
},
|
||||
'transformer' => fn ($row) => [
|
||||
'content' => $row->content,
|
||||
'color' => $row->color,
|
||||
'is_active' => $row->is_active,
|
||||
'created_at' => $row->created_at,
|
||||
'updated_at' => $row->updated_at,
|
||||
],
|
||||
],
|
||||
|
||||
]);
|
||||
SendSqliteFileJob::dispatch($sqlitePath, $this->branchId);
|
||||
}
|
||||
}
|
136
app/Livewire/Forms/BroadcastTemplateForm.php
Normal file
136
app/Livewire/Forms/BroadcastTemplateForm.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Forms;
|
||||
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
use Livewire\Component;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use App\Models\BroadcastTemplate;
|
||||
use App\Enums\TextAdColors;
|
||||
|
||||
|
||||
class BroadcastTemplateForm extends Component
|
||||
{
|
||||
use WireUiActions;
|
||||
|
||||
protected $listeners = ['openModal','closeModal', 'deleteBroadcast'];
|
||||
|
||||
public bool $canCreate;
|
||||
public bool $canEdit;
|
||||
public bool $canDelect;
|
||||
|
||||
public bool $showModal = false;
|
||||
public ?int $textId = null;
|
||||
|
||||
public array $colorOptions =[];
|
||||
|
||||
public array $fields = [
|
||||
'content' =>'',
|
||||
'color' => 'white',
|
||||
'is_active' => true,
|
||||
];
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'fields.content' => 'required|string|max:255',
|
||||
'fields.color' => ['required',new Enum(TextAdColors::class)],
|
||||
'fields.is_active' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->colorOptions = collect(TextAdColors::cases())->map(fn ($color) => [
|
||||
'name' => $color->labels(),
|
||||
'value' => $color->value,
|
||||
])->toArray();
|
||||
$this->canCreate = Auth::user()?->can('broadcast-edit') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('broadcast-edit') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('broadcast-delete') ?? false;
|
||||
}
|
||||
|
||||
public function openModal($id = null)
|
||||
{
|
||||
$this->resetFields();
|
||||
|
||||
if ($id) {
|
||||
$text = BroadcastTemplate::findOrFail($id);
|
||||
$this->textId = $text->id;
|
||||
$this->fields = $text->only(array_keys($this->fields));
|
||||
}
|
||||
|
||||
$this->showModal = true;
|
||||
}
|
||||
|
||||
public function closeModal()
|
||||
{
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$validated = $this->validate($this->rules());
|
||||
if ($this->textId) {
|
||||
if ($this->canEdit) {
|
||||
$text = BroadcastTemplate::findOrFail($this->textId);
|
||||
$text->update($this->fields);
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '文字公告已更新',
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
if ($this->canCreate) {
|
||||
$text = BroadcastTemplate::create($this->fields);
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '文字公告已新增',
|
||||
]);
|
||||
}
|
||||
}
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
$this->dispatch('pg:eventRefresh-broadcast-table');
|
||||
}
|
||||
|
||||
public function deleteBroadcast($id)
|
||||
{
|
||||
if ($this->canDelect) {
|
||||
BroadcastTemplate::findOrFail($id)->delete();
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => '成功',
|
||||
'description' => '文字公告已刪除',
|
||||
]);
|
||||
|
||||
$this->dispatch('pg:eventRefresh-broadcast-table');
|
||||
}
|
||||
}
|
||||
|
||||
public function resetFields()
|
||||
{
|
||||
foreach ($this->fields as $key => $value) {
|
||||
if ($key == 'color') {
|
||||
$this->fields[$key] = 'white';
|
||||
} else if($key == 'is_active'){
|
||||
$this->fields[$key] = true;
|
||||
} else {
|
||||
$this->fields[$key] = '';
|
||||
}
|
||||
}
|
||||
$this->textId = null;
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.forms.broadcast-template-form');
|
||||
}
|
||||
}
|
212
app/Livewire/Tables/BroadcastTemplateTable.php
Normal file
212
app/Livewire/Tables/BroadcastTemplateTable.php
Normal file
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Tables;
|
||||
|
||||
use App\Enums\TextAdColors;
|
||||
use App\Models\BroadcastTemplate;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use PowerComponents\LivewirePowerGrid\Button;
|
||||
use PowerComponents\LivewirePowerGrid\Column;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\Filter;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\PowerGrid;
|
||||
use PowerComponents\LivewirePowerGrid\PowerGridFields;
|
||||
use PowerComponents\LivewirePowerGrid\PowerGridComponent;
|
||||
use PowerComponents\LivewirePowerGrid\Traits\WithExport;
|
||||
use PowerComponents\LivewirePowerGrid\Components\SetUp\Exportable;
|
||||
use PowerComponents\LivewirePowerGrid\Facades\Rule;
|
||||
use Livewire\Attributes\On;
|
||||
use WireUi\Traits\WireUiActions;
|
||||
|
||||
final class BroadcastTemplateTable extends PowerGridComponent
|
||||
{
|
||||
public string $tableName = 'broadcast-table';
|
||||
|
||||
public bool $canCreate;
|
||||
public bool $canEdit;
|
||||
public bool $canDownload;
|
||||
public bool $canDelect;
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
config(['livewire-powergrid.filter' => 'outside']);
|
||||
$this->canCreate = Auth::user()?->can('broadcast-create') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('broadcast-edit') ?? false;
|
||||
$this->canDownload=Auth::user()?->can('broadcast-delete') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('broadcast-delete') ?? false;
|
||||
}
|
||||
|
||||
public function setUp(): array
|
||||
{
|
||||
if($this->canDownload || $this->canDelect){
|
||||
$this->showCheckBox();
|
||||
}
|
||||
$actions = [];
|
||||
if($this->canDownload){
|
||||
$actions[]=PowerGrid::exportable(fileName: $this->tableName.'-file')
|
||||
->type(Exportable::TYPE_XLS, Exportable::TYPE_CSV);
|
||||
}
|
||||
$header = PowerGrid::header()->showSoftDeletes()->showToggleColumns();
|
||||
$header->includeViewOnTop('livewire.headers.broadcast-template');
|
||||
$actions[]=$header;
|
||||
$actions[]=PowerGrid::footer()->showPerPage()->showRecordCount();
|
||||
|
||||
return $actions;
|
||||
}
|
||||
public function header(): array
|
||||
{
|
||||
$actions = [];
|
||||
if ($this->canDelect) {
|
||||
$actions[]=Button::add('bulk-delete')
|
||||
->slot('Bulk delete (<span x-text="window.pgBulkActions.count(\'' . $this->tableName . '\')"></span>)')
|
||||
->icon('solid-trash',['id' => 'my-custom-icon-id', 'class' => 'font-bold'])
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatch('bulkDelete.' . $this->tableName, []);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
public function datasource(): Builder
|
||||
{
|
||||
return BroadcastTemplate::query();
|
||||
}
|
||||
|
||||
public function relationSearch(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function fields(): PowerGridFields
|
||||
{
|
||||
return PowerGrid::fields()
|
||||
->add('id')
|
||||
->add('content')
|
||||
->add(
|
||||
'content_short',
|
||||
fn (BroadcastTemplate $model) =>
|
||||
'<span title="' . e($model->content) . '">' . e(Str::limit($model->content, 50)) . '</span>'
|
||||
)
|
||||
->add('color')
|
||||
->add('color_str', function (BroadcastTemplate $model) {
|
||||
if ($this->canEdit) {
|
||||
return Blade::render(
|
||||
'<x-select-dropdown type="occurrence" :options=$options :modelId=$modelId :fieldName=$fieldName :selected=$selected/>',
|
||||
[
|
||||
'options' => TextAdColors::options(),
|
||||
'modelId' => intval($model->id),
|
||||
'fieldName'=>'color',
|
||||
'selected' => $model->color->value
|
||||
]
|
||||
);
|
||||
}
|
||||
// 沒有權限就顯示對應的文字
|
||||
|
||||
return $model->color->labelPowergridFilter(); // 假設 label() 會回傳顯示文字
|
||||
} )
|
||||
->add('is_active')
|
||||
->add('created_at');
|
||||
}
|
||||
|
||||
public function columns(): array
|
||||
{
|
||||
$column=[];
|
||||
$column[] = Column::make(__('broadcast-templates.id'), 'id');
|
||||
$column[] = Column::make(__('broadcast-templates.content'), 'content_short', 'broadcast-templates.content')->sortable()->searchable();
|
||||
$column[] = Column::make(__('broadcast-templates.color'),'color_str', 'text-ads.color')->searchable();
|
||||
$column[] = Column::make(__('broadcast-templates.is_active'), 'is_active')->toggleable(hasPermission: $this->canEdit, trueLabel: 'yes', falseLabel: 'no');
|
||||
$column[] = Column::make(__('broadcast-templates.created_at'), 'created_at')->sortable()->searchable();
|
||||
$column[] = Column::action(__('broadcast-templates.actions'));
|
||||
return $column;
|
||||
}
|
||||
|
||||
public function filters(): array
|
||||
{
|
||||
return [
|
||||
];
|
||||
}
|
||||
#[On('bulkDelete.{tableName}')]
|
||||
public function bulkDelete(): void
|
||||
{
|
||||
$this->js('alert(window.pgBulkActions.get(\'' . $this->tableName . '\'))');
|
||||
if($this->checkboxValues){
|
||||
foreach ($this->checkboxValues as $id) {
|
||||
$template = BroadcastTemplate::find($id);
|
||||
if ($template) {
|
||||
$template->delete();
|
||||
}
|
||||
}
|
||||
$this->js('window.pgBulkActions.clearAll()'); // clear the count on the interface.
|
||||
}
|
||||
}
|
||||
#[On('selectChanged')]
|
||||
public function selectChanged($value,$fieldName, $modelId): void
|
||||
{
|
||||
//dd($value,$fieldName, $modelId);
|
||||
if (in_array($fieldName, ['color'])) {
|
||||
$this->noUpdated($modelId,$fieldName,$value);
|
||||
}
|
||||
}
|
||||
#[On('onUpdatedEditable')]
|
||||
public function onUpdatedEditable($id, $field, $value): void
|
||||
{
|
||||
if (in_array($field,[
|
||||
''
|
||||
]) && $this->canEdit) {
|
||||
$this->noUpdated($id,$field,$value);
|
||||
}
|
||||
}
|
||||
#[On('onUpdatedToggleable')]
|
||||
public function onUpdatedToggleable($id, $field, $value): void
|
||||
{
|
||||
if (in_array($field,['is_active']) && $this->canEdit) {
|
||||
$this->noUpdated($id,$field,$value);
|
||||
}
|
||||
}
|
||||
private function noUpdated($id,$field,$value){
|
||||
$template = BroadcastTemplate::find($id);
|
||||
if ($template) {
|
||||
$template->{$field} = $value;
|
||||
$template->save(); // 明確觸發 saving
|
||||
}
|
||||
$this->notification()->send([
|
||||
'icon' => 'success',
|
||||
'title' => $id.'.'.__('broadcast.'.$field).':'.$value,
|
||||
'description' => '已經寫入',
|
||||
]);
|
||||
}
|
||||
|
||||
public function actions(BroadcastTemplate $row): array
|
||||
{
|
||||
$actions = [];
|
||||
if ($this->canEdit) {
|
||||
$actions[]=Button::add('edit')
|
||||
->slot(__('broadcast-templates.edit'))
|
||||
->icon('solid-pencil-square')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('forms.broadcast-template-form', 'openModal', ['id' => $row->id]);
|
||||
}
|
||||
if($this->canDelect){
|
||||
$actions[]=Button::add('delete')
|
||||
->slot(__('broadcast-templates.delete'))
|
||||
->icon('solid-trash')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('forms.broadcast-template-form', 'deleteBroadcast', ['id' => $row->id]);
|
||||
}
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/*
|
||||
public function actionRules($row): array
|
||||
{
|
||||
return [
|
||||
// Hide button edit for ID 1
|
||||
Rule::button('edit')
|
||||
->when(fn($row) => $row->id === 1)
|
||||
->hide(),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
18
app/Models/BroadcastTemplate.php
Normal file
18
app/Models/BroadcastTemplate.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BroadcastTemplate extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'content',
|
||||
'color',
|
||||
'is_active',
|
||||
];
|
||||
protected $casts = [
|
||||
'color' => \App\Enums\TextAdColors::class,
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
20
app/Models/TextBroadcast.php
Normal file
20
app/Models/TextBroadcast.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TextBroadcast extends Model
|
||||
{
|
||||
protected $fillable = ['template_id', 'content', 'target_type'];
|
||||
|
||||
public function rooms()
|
||||
{
|
||||
return $this->belongsToMany(Room::class, 'text_broadcast_room');
|
||||
}
|
||||
|
||||
public function template()
|
||||
{
|
||||
return $this->belongsTo(BroadcastTemplate::class);
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ return new class extends Migration
|
||||
Schema::create('text_ads', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('content')->comment('廣告內容');
|
||||
$table->enum('color', ['black','white', 'red', 'green','blue'])->default('black')->comment('顯示顏色');
|
||||
$table->enum('color', ['white', 'red', 'green','blue'])->default('white')->comment('顯示顏色');
|
||||
$table->integer('duration')->default(1)->comment('播放間隔時間(分鐘)');
|
||||
$table->boolean('is_active')->default(true); // 啟用狀態
|
||||
$table->timestamps();
|
||||
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('broadcast_templates', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->text('content')->comment('公告內容'); // e.g., "親愛的 **name**,歡迎光臨!"
|
||||
$table->enum('color', ['white', 'red', 'green','blue'])->default('white')->comment('顯示顏色');
|
||||
$table->boolean('is_active')->default(true); // 啟用狀態
|
||||
$table->timestamps();
|
||||
});
|
||||
Schema::create('text_broadcasts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('template_id')->nullable()->constrained('broadcast_templates')->nullOnDelete();
|
||||
$table->text('content'); // Final content with variables replaced
|
||||
$table->enum('target_type', ['all', 'rooms'])->default('all');
|
||||
$table->timestamps();
|
||||
});
|
||||
Schema::create('text_broadcast_room', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('text_broadcast_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('room_id')->constrained()->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('text_broadcast_room');
|
||||
Schema::dropIfExists('text_broadcasts');
|
||||
Schema::dropIfExists('broadcast_templates');
|
||||
}
|
||||
};
|
58
database/seeders/BroadcastTemplateSeeder.php
Normal file
58
database/seeders/BroadcastTemplateSeeder.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\Models\BroadcastTemplate;
|
||||
use App\Enums\TextAdColors;
|
||||
|
||||
class BroadcastTemplateSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$txs = [
|
||||
[
|
||||
'content' => '親愛的 **name**,祝你生日快樂!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**room_name** 歡迎您蒞臨本店,祝您有美好的一天!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**name** 拾獲您的證件,請至櫃台領取',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**name** 請移動你的愛車,謝謝!!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**name** 祝你生日快樂!!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**name** 櫃台有您訪客!!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**room_name** 警察臨檢不便之處敬請原諒!!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**name** 您的愛車被拖吊了!!',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
[
|
||||
'content' => '**name** 請移動您的愛車,謝謝',
|
||||
'color' => TextAdColors::White,
|
||||
],
|
||||
];
|
||||
foreach ($txs as $tx) {
|
||||
BroadcastTemplate::create([
|
||||
'content' => $tx['content'],
|
||||
'color' => $tx['color'],
|
||||
'is_active' => true,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ class DatabaseSeeder extends Seeder
|
||||
CreateAdminUserSeeder::class,
|
||||
TextAdPermissionSeeder::class,
|
||||
TextAdSeeder::class,
|
||||
BroadcastTemplateSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ class TextAdPermissionSeeder extends Seeder
|
||||
'text-ad-create',
|
||||
'text-ad-edit',
|
||||
'text-ad-delete',
|
||||
'broadcast-list',
|
||||
'broadcast-create',
|
||||
'broadcast-edit',
|
||||
'broadcast-delete',
|
||||
];
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
|
27
resources/lang/zh-tw/broadcast-templates.php
Normal file
27
resources/lang/zh-tw/broadcast-templates.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'management' => '文字公告管理',
|
||||
'list' => '文字公告列表',
|
||||
'CreateNew' => '新增文字公告',
|
||||
'EditArtist' => '編輯文字公告',
|
||||
'ImportData' => '滙入文字公告',
|
||||
'create_edit' => '新增 / 編輯',
|
||||
'create' => '新增',
|
||||
'edit' => '編輯',
|
||||
'delete' => '刪除',
|
||||
'id' => '編號',
|
||||
'name' => '主題',
|
||||
'content' => '內容',
|
||||
'description' => '描述',
|
||||
'color' => '顏色',
|
||||
'duration' => '播放間隔時間(分鐘)',
|
||||
'is_active' => '是否推播',
|
||||
'created_at' =>'建立於',
|
||||
|
||||
|
||||
'actions' => '操作',
|
||||
'view' => '查看',
|
||||
'submit' => '提交',
|
||||
'cancel' => '取消',
|
||||
];
|
@ -0,0 +1,6 @@
|
||||
|
||||
<x-layouts.admin>
|
||||
<x-wireui:notifications/>
|
||||
<livewire:tables.broadcast-template-table />
|
||||
<livewire:forms.broadcast-template-form />
|
||||
</x-layouts.admin>
|
@ -0,0 +1,23 @@
|
||||
<x-wireui:modal-card title="{{ $textId ? __('broadcast-templates.EditArtist') : __('broadcast-templates.CreateNew') }}" blur wire:model.defer="showModal">
|
||||
<div class="space-y-4">
|
||||
<x-wireui:input label="{{__('broadcast-templates.content')}}" wire:model.defer="fields.content" />
|
||||
<x-wireui:select
|
||||
label="{{__('broadcast-templates.color')}}"
|
||||
wire:model.defer="fields.color"
|
||||
placeholder="{{__('broadcast-templates.select_color')}}"
|
||||
:options="$colorOptions"
|
||||
option-label="name"
|
||||
option-value="value"
|
||||
/>
|
||||
|
||||
<x-wireui:toggle label="{{__('broadcast-templates.is_active')}}" wire:model.defer="fields.is_active" />
|
||||
</div>
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{__('broadcast-templates.cancel')}}" wire:click="closeModal" />
|
||||
<x-wireui:button primary label="{{__('broadcast-templates.submit')}}" wire:click="save" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-wireui:modal-card>
|
||||
|
@ -0,0 +1,10 @@
|
||||
<x-admin.section-header title="{{ __('broadcast-templates.list') }}">
|
||||
@if ($canCreate)
|
||||
<x-wireui:button
|
||||
wire:click="$dispatchTo('forms.broadcast-template-form', 'openModal')"
|
||||
icon="plus"
|
||||
label="{{ __('broadcast-templates.CreateNew') }}"
|
||||
class="bg-blue-600 text-white"
|
||||
/>
|
||||
@endif
|
||||
</x-admin.section-header>
|
@ -1,10 +0,0 @@
|
||||
<x-admin.section-header title="{{ __('broadcasts.list') }}">
|
||||
@if ($canCreate)
|
||||
<x-wireui:button
|
||||
wire:click="$dispatchTo('forms.broadcast-form', 'openModal')"
|
||||
icon="plus"
|
||||
label="{{ __('broadcasts.CreateNew') }}"
|
||||
class="bg-blue-600 text-white"
|
||||
/>
|
||||
@endif
|
||||
</x-admin.section-header>
|
@ -17,6 +17,7 @@ new class extends Component
|
||||
['label' => 'Room', 'route' => 'admin.rooms', 'icon' => 'building-library', 'permission' => 'room-list'],
|
||||
['label' => 'RoomGrid', 'route' => 'admin.room-grids', 'icon' => 'film', 'permission' => 'room-list'],
|
||||
['label' => 'TextAd', 'route' => 'admin.text-ads', 'icon' => 'megaphone', 'permission' => 'text-ad-list'],
|
||||
['label' => 'BroadcastTemplate', 'route' => 'admin.broadcast-templates', 'icon' => 'megaphone', 'permission' => 'broadcast-list'],
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -31,4 +31,5 @@ Route::middleware(['auth'])->prefix('admin')->name('admin.')->group(function ()
|
||||
Route::get('/rooms', function () {return view('livewire.admin.rooms');})->name('rooms');
|
||||
Route::get('/room-grids', function () {return view('livewire.admin.room-grids');})->name('room-grids');
|
||||
Route::get('/text-ads', function () {return view('livewire.admin.text-ads');})->name('text-ads');
|
||||
Route::get('/broadcast-templates', function () {return view('livewire.admin.broadcast-templates');})->name('broadcast-templates');
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user