mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 23:18:10 +00:00
fix(#12): correct mispelled word recipe
fix(#12): correct mispelled word recipe
This commit is contained in:
parent
302730c81e
commit
f530875210
17 changed files with 93 additions and 46 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
[](https://github.com/usetrmnl/byos_laravel/actions/workflows/test.yml)
|
[](https://github.com/usetrmnl/byos_laravel/actions/workflows/test.yml)
|
||||||
|
|
||||||
TRMNL BYOS Laravel is a self-hostable implementation of a TRMNL server, built with Laravel.
|
TRMNL BYOS Laravel is a self-hostable implementation of a TRMNL server, built with Laravel.
|
||||||
It enables you to manage TRMNL devices, generate screens dynamically, and can act as a proxy for the native cloud service (native plugins, receipts).
|
It enables you to manage TRMNL devices, generate screens dynamically, and can act as a proxy for the native cloud service (native plugins, recipes).
|
||||||
Inspired by [usetrmnl/byos_sinatra](https://github.com/usetrmnl/byos_sinatra).
|
Inspired by [usetrmnl/byos_sinatra](https://github.com/usetrmnl/byos_sinatra).
|
||||||
|
|
||||||
If you are looking for a Laravel package designed to streamline the development of both public and private TRMNL plugins, check out [bnussbau/trmnl-laravel](https://github.com/bnussbau/laravel-trmnl).
|
If you are looking for a Laravel package designed to streamline the development of both public and private TRMNL plugins, check out [bnussbau/trmnl-laravel](https://github.com/bnussbau/laravel-trmnl).
|
||||||
|
|
@ -116,10 +116,10 @@ Login with user / password `admin@example.com` / `admin@example.com`
|
||||||
|
|
||||||
### Demo Plugins
|
### Demo Plugins
|
||||||
|
|
||||||
Run the ExampleReceiptsSeeder to seed the database with example plugins:
|
Run the ExampleRecipesSeeder to seed the database with example plugins:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
php artisan db:seed --class=ExampleReceiptsSeeder
|
php artisan db:seed --class=ExampleRecipesSeeder
|
||||||
```
|
```
|
||||||
|
|
||||||
* Zen Quotes
|
* Zen Quotes
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Console\Commands;
|
|
||||||
|
|
||||||
use Database\Seeders\ExampleReceiptsSeeder;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Illuminate\Contracts\Console\PromptsForMissingInput;
|
|
||||||
|
|
||||||
class ExampleReceiptsSeederCommand extends Command implements PromptsForMissingInput
|
|
||||||
{
|
|
||||||
protected $signature = 'receipts:seed {user_id}';
|
|
||||||
|
|
||||||
protected $description = 'Seed example receipts';
|
|
||||||
|
|
||||||
public function handle(ExampleReceiptsSeeder $seeder): void
|
|
||||||
{
|
|
||||||
$user_id = $this->argument('user_id');
|
|
||||||
$seeder->run($user_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
20
app/Console/Commands/ExampleRecipesSeederCommand.php
Normal file
20
app/Console/Commands/ExampleRecipesSeederCommand.php
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Database\Seeders\ExampleRecipesSeeder;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Contracts\Console\PromptsForMissingInput;
|
||||||
|
|
||||||
|
class ExampleRecipesSeederCommand extends Command implements PromptsForMissingInput
|
||||||
|
{
|
||||||
|
protected $signature = 'recipes:seed {user_id}';
|
||||||
|
|
||||||
|
protected $description = 'Seed example recipes';
|
||||||
|
|
||||||
|
public function handle(ExampleRecipesSeeder $seeder): void
|
||||||
|
{
|
||||||
|
$user_id = $this->argument('user_id');
|
||||||
|
$seeder->run($user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
// Correct the typo in render_markup_view for all plugin UUIDs
|
||||||
|
$pluginUuids = [
|
||||||
|
'9e46c6cf-358c-4bfe-8998-436b3a207fec', // ÖBB Departures
|
||||||
|
'3b046eda-34e9-4232-b935-c33b989a284b', // Weather
|
||||||
|
'21464b16-5f5a-4099-a967-f5c915e3da54', // Zen Quotes
|
||||||
|
'8d472959-400f-46ee-afb2-4a9f1cfd521f', // This Day in History
|
||||||
|
'4349fdad-a273-450b-aa00-3d32f2de788d', // Home Assistant
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($pluginUuids as $uuid) {
|
||||||
|
DB::table('plugins')
|
||||||
|
->where('uuid', $uuid)
|
||||||
|
->update([
|
||||||
|
'render_markup_view' => DB::raw("REPLACE(render_markup_view, 'receipts.', 'recipes.')"),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// Revert the typo correction if needed
|
||||||
|
$pluginUuids = [
|
||||||
|
'9e46c6cf-358c-4bfe-8998-436b3a207fec', // ÖBB Departures
|
||||||
|
'3b046eda-34e9-4232-b935-c33b989a284b', // Weather
|
||||||
|
'21464b16-5f5a-4099-a967-f5c915e3da54', // Zen Quotes
|
||||||
|
'8d472959-400f-46ee-afb2-4a9f1cfd521f', // This Day in History
|
||||||
|
'4349fdad-a273-450b-aa00-3d32f2de788d', // Home Assistant
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($pluginUuids as $uuid) {
|
||||||
|
DB::table('plugins')
|
||||||
|
->where('uuid', $uuid)
|
||||||
|
->update([
|
||||||
|
'render_markup_view' => DB::raw("REPLACE(render_markup_view, 'recipes.', 'receipts.')"),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -33,7 +33,7 @@ class DatabaseSeeder extends Seeder
|
||||||
// Plugin::factory(3)->create();
|
// Plugin::factory(3)->create();
|
||||||
|
|
||||||
$this->call([
|
$this->call([
|
||||||
ExampleReceiptsSeeder::class,
|
ExampleRecipesSeeder::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Database\Seeders;
|
||||||
use App\Models\Plugin;
|
use App\Models\Plugin;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class ExampleReceiptsSeeder extends Seeder
|
class ExampleRecipesSeeder extends Seeder
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Run the database seeds.
|
* Run the database seeds.
|
||||||
|
|
@ -24,7 +24,7 @@ class ExampleReceiptsSeeder extends Seeder
|
||||||
'polling_verb' => 'get',
|
'polling_verb' => 'get',
|
||||||
'polling_header' => null,
|
'polling_header' => null,
|
||||||
'render_markup' => null,
|
'render_markup' => null,
|
||||||
'render_markup_view' => 'receipts.train',
|
'render_markup_view' => 'recipes.train',
|
||||||
'detail_view_route' => null,
|
'detail_view_route' => null,
|
||||||
'icon_url' => null,
|
'icon_url' => null,
|
||||||
'flux_icon_name' => 'train-front',
|
'flux_icon_name' => 'train-front',
|
||||||
|
|
@ -43,7 +43,7 @@ class ExampleReceiptsSeeder extends Seeder
|
||||||
'polling_verb' => 'get',
|
'polling_verb' => 'get',
|
||||||
'polling_header' => null,
|
'polling_header' => null,
|
||||||
'render_markup' => null,
|
'render_markup' => null,
|
||||||
'render_markup_view' => 'receipts.weather',
|
'render_markup_view' => 'recipes.weather',
|
||||||
'detail_view_route' => null,
|
'detail_view_route' => null,
|
||||||
'icon_url' => null,
|
'icon_url' => null,
|
||||||
'flux_icon_name' => 'sun',
|
'flux_icon_name' => 'sun',
|
||||||
|
|
@ -62,7 +62,7 @@ class ExampleReceiptsSeeder extends Seeder
|
||||||
'polling_verb' => 'get',
|
'polling_verb' => 'get',
|
||||||
'polling_header' => null,
|
'polling_header' => null,
|
||||||
'render_markup' => null,
|
'render_markup' => null,
|
||||||
'render_markup_view' => 'receipts.zen',
|
'render_markup_view' => 'recipes.zen',
|
||||||
'detail_view_route' => null,
|
'detail_view_route' => null,
|
||||||
'icon_url' => null,
|
'icon_url' => null,
|
||||||
'flux_icon_name' => 'chat-bubble-bottom-center',
|
'flux_icon_name' => 'chat-bubble-bottom-center',
|
||||||
|
|
@ -81,7 +81,7 @@ class ExampleReceiptsSeeder extends Seeder
|
||||||
'polling_verb' => 'get',
|
'polling_verb' => 'get',
|
||||||
'polling_header' => null,
|
'polling_header' => null,
|
||||||
'render_markup' => null,
|
'render_markup' => null,
|
||||||
'render_markup_view' => 'receipts.day-in-history',
|
'render_markup_view' => 'recipes.day-in-history',
|
||||||
'detail_view_route' => null,
|
'detail_view_route' => null,
|
||||||
'icon_url' => null,
|
'icon_url' => null,
|
||||||
'flux_icon_name' => 'calendar',
|
'flux_icon_name' => 'calendar',
|
||||||
|
|
@ -100,7 +100,7 @@ class ExampleReceiptsSeeder extends Seeder
|
||||||
'polling_verb' => 'get',
|
'polling_verb' => 'get',
|
||||||
'polling_header' => 'Authorization: Bearer YOUR_API_KEY',
|
'polling_header' => 'Authorization: Bearer YOUR_API_KEY',
|
||||||
'render_markup' => null,
|
'render_markup' => null,
|
||||||
'render_markup_view' => 'receipts.home-assistant',
|
'render_markup_view' => 'recipes.home-assistant',
|
||||||
'detail_view_route' => null,
|
'detail_view_route' => null,
|
||||||
'icon_url' => null,
|
'icon_url' => null,
|
||||||
'flux_icon_name' => 'thermometer',
|
'flux_icon_name' => 'thermometer',
|
||||||
|
|
@ -21,8 +21,8 @@
|
||||||
Devices
|
Devices
|
||||||
</flux:navbar.item>
|
</flux:navbar.item>
|
||||||
<flux:navbar.item icon="puzzle-piece" href="{{ route('plugins.index') }}" wire:navigate
|
<flux:navbar.item icon="puzzle-piece" href="{{ route('plugins.index') }}" wire:navigate
|
||||||
:current="request()->routeIs(['plugins.index', 'plugins.markup', 'plugins.api', 'plugins.receipt'])">
|
:current="request()->routeIs(['plugins.index', 'plugins.markup', 'plugins.api', 'plugins.recipe'])">
|
||||||
Plugins & Receipts
|
Plugins & Recipes
|
||||||
</flux:navbar.item>
|
</flux:navbar.item>
|
||||||
<flux:navbar.item icon="play" href="{{ route('playlists.index') }}" wire:navigate
|
<flux:navbar.item icon="play" href="{{ route('playlists.index') }}" wire:navigate
|
||||||
:current="request()->routeIs('playlists.index')">
|
:current="request()->routeIs('playlists.index')">
|
||||||
|
|
@ -102,7 +102,7 @@
|
||||||
</flux:navbar.item>
|
</flux:navbar.item>
|
||||||
<flux:navbar.item icon="puzzle-piece" href="{{ route('plugins.index') }}" wire:navigate
|
<flux:navbar.item icon="puzzle-piece" href="{{ route('plugins.index') }}" wire:navigate
|
||||||
:current="request()->routeIs('plugins.index')" class="m-2">
|
:current="request()->routeIs('plugins.index')" class="m-2">
|
||||||
Plugins & Receipts
|
Plugins & Recipes
|
||||||
</flux:navbar.item>
|
</flux:navbar.item>
|
||||||
<flux:navbar.item icon="play" href="{{ route('playlists.index') }}" wire:navigate
|
<flux:navbar.item icon="play" href="{{ route('playlists.index') }}" wire:navigate
|
||||||
:current="request()->routeIs('playlists.index')" class="m-2">
|
:current="request()->routeIs('playlists.index')" class="m-2">
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ new class extends Component {
|
||||||
<tr>
|
<tr>
|
||||||
<th class="py-3 px-3 first:pl-0 last:pr-0 text-left text-sm font-medium text-zinc-800 dark:text-white"
|
<th class="py-3 px-3 first:pl-0 last:pr-0 text-left text-sm font-medium text-zinc-800 dark:text-white"
|
||||||
data-flux-column>
|
data-flux-column>
|
||||||
<div class="whitespace-nowrap flex">Plugin / Receipt</div>
|
<div class="whitespace-nowrap flex">Plugin / Recipe</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="py-3 px-3 first:pl-0 last:pr-0 text-left text-sm font-medium text-zinc-800 dark:text-white"
|
<th class="py-3 px-3 first:pl-0 last:pr-0 text-left text-sm font-medium text-zinc-800 dark:text-white"
|
||||||
data-flux-column>
|
data-flux-column>
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@ new class extends Component {
|
||||||
|
|
||||||
public function seedExamplePlugins(): void
|
public function seedExamplePlugins(): void
|
||||||
{
|
{
|
||||||
// \Artisan::call('db:seed', ['--class' => 'ExampleReceiptsSeeder']);
|
// \Artisan::call('db:seed', ['--class' => 'ExampleRecipesSeeder']);
|
||||||
\Artisan::call(\App\Console\Commands\ExampleReceiptsSeederCommand::class, ['user_id' => auth()->id()]);
|
\Artisan::call(\App\Console\Commands\ExampleRecipesSeederCommand::class, ['user_id' => auth()->id()]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,20 +71,20 @@ new class extends Component {
|
||||||
<div class="py-12">
|
<div class="py-12">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h2 class="text-2xl font-semibold dark:text-gray-100">Plugins & Receipts</h2>
|
<h2 class="text-2xl font-semibold dark:text-gray-100">Plugins & Recipes</h2>
|
||||||
|
|
||||||
<flux:button.group>
|
<flux:button.group>
|
||||||
<flux:modal.trigger name="add-plugin">
|
<flux:modal.trigger name="add-plugin">
|
||||||
<flux:button icon="plus" variant="primary">Add Receipt</flux:button>
|
<flux:button icon="plus" variant="primary">Add Recipe</flux:button>
|
||||||
</flux:modal.trigger>
|
</flux:modal.trigger>
|
||||||
|
|
||||||
<flux:dropdown>
|
<flux:dropdown>
|
||||||
<flux:button icon="chevron-down" variant="primary"></flux:button>
|
<flux:button icon="chevron-down" variant="primary"></flux:button>
|
||||||
<flux:menu>
|
<flux:menu>
|
||||||
<flux:menu.item icon="beaker" wire:click="seedExamplePlugins">Seed Example Receipts</flux:menu.item>
|
<flux:menu.item icon="beaker" wire:click="seedExamplePlugins">Seed Example Recipes</flux:menu.item>
|
||||||
{{-- <flux:menu.separator/>--}}
|
{{-- <flux:menu.separator/>--}}
|
||||||
{{-- <flux:modal.trigger name="import-receipt">--}}
|
{{-- <flux:modal.trigger name="import-recipe">--}}
|
||||||
{{-- <flux:menu.item icon="paper-clip">Import Receipt ZIP File</flux:menu.item>--}}
|
{{-- <flux:menu.item icon="paper-clip">Import Recipe ZIP File</flux:menu.item>--}}
|
||||||
{{-- </flux:modal.trigger>--}}
|
{{-- </flux:modal.trigger>--}}
|
||||||
{{-- <flux:menu.separator/>--}}
|
{{-- <flux:menu.separator/>--}}
|
||||||
{{-- <flux:modal.trigger name="add-native-plugin">--}}
|
{{-- <flux:modal.trigger name="add-native-plugin">--}}
|
||||||
|
|
@ -100,7 +100,7 @@ new class extends Component {
|
||||||
<flux:modal name="add-plugin" class="md:w-96">
|
<flux:modal name="add-plugin" class="md:w-96">
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<flux:heading size="lg">Add Receipt</flux:heading>
|
<flux:heading size="lg">Add Recipe</flux:heading>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form wire:submit="addPlugin">
|
<form wire:submit="addPlugin">
|
||||||
|
|
@ -142,7 +142,7 @@ new class extends Component {
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<flux:spacer/>
|
<flux:spacer/>
|
||||||
<flux:button type="submit" variant="primary">Create Receipt</flux:button>
|
<flux:button type="submit" variant="primary">Create Recipe</flux:button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -152,7 +152,7 @@ new class extends Component {
|
||||||
@foreach($plugins as $plugin)
|
@foreach($plugins as $plugin)
|
||||||
<div
|
<div
|
||||||
class="rounded-xl border bg-white dark:bg-stone-950 dark:border-stone-800 text-stone-800 shadow-xs">
|
class="rounded-xl border bg-white dark:bg-stone-950 dark:border-stone-800 text-stone-800 shadow-xs">
|
||||||
<a href="{{ ($plugin['detail_view_route']) ? route($plugin['detail_view_route']) : route('plugins.receipt', ['plugin' => $plugin['id']]) }}"
|
<a href="{{ ($plugin['detail_view_route']) ? route($plugin['detail_view_route']) : route('plugins.recipe', ['plugin' => $plugin['id']]) }}"
|
||||||
class="block">
|
class="block">
|
||||||
<div class="flex items-center space-x-4 px-10 py-8">
|
<div class="flex items-center space-x-4 px-10 py-8">
|
||||||
<flux:icon name="{{$plugin['flux_icon_name'] ?? 'puzzle-piece'}}"
|
<flux:icon name="{{$plugin['flux_icon_name'] ?? 'puzzle-piece'}}"
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ HTML;
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h2 class="text-2xl font-semibold dark:text-gray-100">{{$plugin->name}}
|
<h2 class="text-2xl font-semibold dark:text-gray-100">{{$plugin->name}}
|
||||||
<flux:badge size="sm" class="ml-2">Receipt</flux:badge>
|
<flux:badge size="sm" class="ml-2">Recipe</flux:badge>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<flux:button.group>
|
<flux:button.group>
|
||||||
|
|
@ -20,7 +20,7 @@ Route::middleware(['auth'])->group(function () {
|
||||||
|
|
||||||
Volt::route('plugins', 'plugins.index')->name('plugins.index');
|
Volt::route('plugins', 'plugins.index')->name('plugins.index');
|
||||||
|
|
||||||
Volt::route('plugins/receipt/{plugin}', 'plugins.receipt')->name('plugins.receipt');
|
Volt::route('plugins/recipe/{plugin}', 'plugins.recipe')->name('plugins.recipe');
|
||||||
Volt::route('plugins/markup', 'plugins.markup')->name('plugins.markup');
|
Volt::route('plugins/markup', 'plugins.markup')->name('plugins.markup');
|
||||||
Volt::route('plugins/api', 'plugins.api')->name('plugins.api');
|
Volt::route('plugins/api', 'plugins.api')->name('plugins.api');
|
||||||
Volt::route('playlists', 'playlists.index')->name('playlists.index');
|
Volt::route('playlists', 'playlists.index')->name('playlists.index');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue