Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions app/Livewire/Forms/Kiosk/SettingsForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ class SettingsForm extends Form
#[Validate('required|int|between:0,6')]
public int $week_start = Carbon::SUNDAY;

#[Validate('required|string|in:light,dark,system')]
public string $appearance = 'dark';

#[Validate('required|string|in:landscape,portrait')]
public string $layout = 'landscape';

#[Validate([
'address' => 'required|array',
'address.*' => 'required',
Expand All @@ -32,15 +38,17 @@ class SettingsForm extends Form
'long' => '',
];

public function load(Team $team)
public function load(Team $team): void
{
$this->editingTeam = $team;
$this->timezone = $team->timezone;
$this->week_start = $team->week_start;
$this->appearance = $team->appearance;
$this->layout = $team->layout;
$this->address = $team->address ?? $this->address;
}

public function save()
public function save(): void
{
$data = $this->validate();

Expand Down
11 changes: 10 additions & 1 deletion app/Models/Team.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\SoftDeletes;

#[Fillable(['name', 'slug', 'is_personal', 'address', 'timezone', 'week_start'])]
#[Fillable([
'name',
'slug',
'is_personal',
'address',
'timezone',
'week_start',
'appearance',
'layout',
])]
class Team extends Model
{
/** @use HasFactory<TeamFactory> */
Expand Down
2 changes: 2 additions & 0 deletions database/factories/TeamFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public function definition(): array
'is_personal' => false,
'timezone' => 'America/Chicago',
'week_start' => Carbon::SUNDAY,
'appearance' => 'dark',
'layout' => 'landscape',
];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('teams', function (Blueprint $table): void {
$table->string('appearance')->default('dark')->after('address');
$table->string('layout')->default('landscape')->after('appearance');
});
}

public function down(): void
{
Schema::table('teams', function (Blueprint $table): void {
$table->dropColumns(['appearance', 'layout']);
});
}
};
40 changes: 20 additions & 20 deletions public/fonts-manifest.dev.json

Large diffs are not rendered by default.

17 changes: 14 additions & 3 deletions resources/views/layouts/kiosk.blade.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="dark">
<html
lang="{{ str_replace('_', '-', app()->getLocale()) }}"
@class(['dark' => auth()->user()->currentTeam->appearance === 'dark'])
data-kiosk-appearance="{{ auth()->user()->currentTeam->appearance }}"
>
<head>
@include('layouts.partials.head')
@include('layouts.partials.head', ['fixedAppearance' => auth()->user()->currentTeam->appearance])
</head>
<body class="min-h-screen bg-white dark:bg-zinc-800">
<body
@class([
'bg-white dark:bg-zinc-800',
'h-screen w-screen overflow-hidden' => auth()->user()->currentTeam->layout === 'landscape',
'fixed top-0 left-[100vw] h-[100vw] w-[100vh] origin-top-left rotate-90 overflow-hidden' => auth()->user()->currentTeam->layout === 'portrait',
])
data-kiosk-layout="{{ auth()->user()->currentTeam->layout }}"
>
<x-kiosk.sidebar>
<livewire:kiosk.weather-tile />
<x-kiosk.sidebar.item icon="calendar" :href="route('kiosk.calendar')" :current="request()->routeIs('kiosk.calendar')" wire:navigate>{{ __('Calendar') }}</x-kiosk.sidebar.item>
Expand Down
25 changes: 24 additions & 1 deletion resources/views/layouts/partials/head.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,28 @@
@endproduction

@vite(['resources/css/app.css', 'resources/js/app.js'])
@fluxAppearance
@if (isset($fixedAppearance))
<style>
:root.dark {
color-scheme: dark;
}
</style>
<script>
(() => {
const appearance = @js($fixedAppearance);

const applyAppearance = () => {
const dark = appearance === 'dark'
|| (appearance === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);

document.documentElement.classList.toggle('dark', dark);
};

window.Flux = { applyAppearance };
applyAppearance();
})();
</script>
@else
@fluxAppearance
@endif
@stack('head')
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
<div>
<form wire:submit="save" class="space-y-6 p-6 lg:p-8">
<flux:select wire:model="form.timezone" :label="__('Timezone')" variant="listbox">
@foreach (DateTimeZone::listIdentifiers() as $timezoneOption)
<flux:select.option value="{{ $timezoneOption }}">{{ str_replace('_', ' ', $timezoneOption) }}</flux:select.option>
@endforeach
</flux:select>
<div class="grid gap-6 sm:grid-cols-2">
<flux:select wire:model="form.timezone" :label="__('Timezone')" variant="listbox" searchable>
@foreach (DateTimeZone::listIdentifiers() as $timezoneOption)
<flux:select.option value="{{ $timezoneOption }}">{{ str_replace('_', ' ', $timezoneOption) }}</flux:select.option>
@endforeach
</flux:select>

<flux:select wire:model="form.week_start" :label="__('Calendar Week Start')" variant="listbox" searchable>
<flux:select.option value="0">{{ __('Sunday') }}</flux:select.option>
<flux:select.option value="1">{{ __('Monday') }}</flux:select.option>
<flux:select.option value="2">{{ __('Tuesday') }}</flux:select.option>
<flux:select.option value="3">{{ __('Wednesday') }}</flux:select.option>
<flux:select.option value="4">{{ __('Thursday') }}</flux:select.option>
<flux:select.option value="5">{{ __('Friday') }}</flux:select.option>
<flux:select.option value="6">{{ __('Saturday') }}</flux:select.option>
</flux:select>

<flux:radio.group wire:model="form.appearance" :label="__('Appearance')" variant="segmented">
<flux:radio value="light" icon="sun">{{ __('Light') }}</flux:radio>
<flux:radio value="dark" icon="moon">{{ __('Dark') }}</flux:radio>
<flux:radio value="system" icon="computer-desktop">{{ __('System') }}</flux:radio>
</flux:radio.group>

<flux:select wire:model="form.week_start" :label="__('Calendar Week Start')" variant="listbox">
<flux:select.option value="0">{{ __('Sunday') }}</flux:select.option>
<flux:select.option value="1">{{ __('Monday') }}</flux:select.option>
<flux:select.option value="2">{{ __('Tuesday') }}</flux:select.option>
<flux:select.option value="3">{{ __('Wednesday') }}</flux:select.option>
<flux:select.option value="4">{{ __('Thursday') }}</flux:select.option>
<flux:select.option value="5">{{ __('Friday') }}</flux:select.option>
<flux:select.option value="6">{{ __('Saturday') }}</flux:select.option>
</flux:select>
<flux:radio.group wire:model="form.layout" :label="__('Layout')" variant="segmented">
<flux:radio value="portrait">{{ __('Portrait') }}</flux:radio>
<flux:radio value="landscape">{{ __('Landscape') }}</flux:radio>
</flux:radio.group>
</div>

<flux:field>
<flux:label>Address for Weather</flux:label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
{
public SettingsForm $form;

public function mount()
public function mount(): void
{
$this->form->load(Auth::user()->currentTeam);
}

public function save()
public function save(): void
{
$this->form->save();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
'name' => 'Straw Hats',
'timezone' => 'Asia/Tokyo',
'week_start' => Carbon::MONDAY,
'appearance' => 'light',
'layout' => 'landscape',
]);

$user = User::factory()->memberOf($team)->create();
Expand All @@ -27,7 +29,9 @@
->test('pages::kiosk.configure.settings')
->assertOk()
->assertSet('form.timezone', 'Asia/Tokyo')
->assertSet('form.week_start', Carbon::MONDAY);
->assertSet('form.week_start', Carbon::MONDAY)
->assertSet('form.appearance', 'light')
->assertSet('form.layout', 'landscape');
})->group('smoke');

test('can change kiosk settings', function () {
Expand All @@ -43,6 +47,8 @@
->test('pages::kiosk.configure.settings')
->set('form.timezone', 'America/Sao_Paulo')
->set('form.week_start', Carbon::SUNDAY)
->set('form.appearance', 'system')
->set('form.layout', 'landscape')
->set('form.address', [
'address' => '123 Grand Line',
'city' => 'East Blue',
Expand All @@ -56,7 +62,9 @@

expect($team->fresh())
->timezone->toBe('America/Sao_Paulo')
->week_start->toBe(Carbon::SUNDAY);
->week_start->toBe(Carbon::SUNDAY)
->appearance->toBe('system')
->layout->toBe('landscape');
});

test('options must be valid', function () {
Expand All @@ -66,8 +74,10 @@
->test('pages::kiosk.configure.settings')
->set('form.timezone', 'Not/AZone')
->set('form.week_start', 15)
->set('form.appearance', 'sepia')
->set('form.layout', 'footer')
->call('save')
->assertHasErrors(['form.timezone', 'form.week_start']);
->assertHasErrors(['form.timezone', 'form.week_start', 'form.appearance', 'form.layout']);
});

describe('device management', function () {
Expand Down
2 changes: 1 addition & 1 deletion resources/views/pages/kiosk/⚡calendar/calendar.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="flex h-dvh flex-col overflow-hidden" wire:poll.600s>
<div class="flex h-full flex-col overflow-hidden" wire:poll.600s>
<div class="flex shrink-0 flex-col gap-3 border-b border-zinc-200 px-5 py-4 dark:border-zinc-700 sm:flex-row sm:items-center sm:justify-between">
<x-ui.clock :timezone="auth()->user()->currentTeam->timezone"/>

Expand Down
34 changes: 34 additions & 0 deletions resources/views/pages/kiosk/⚡calendar/calendar.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,40 @@
->assertOk();
})->group('smoke');

test('uses the team layout to orient the kiosk viewport', function (string $layout, string $expectedClasses) {
$team = Team::factory()->create(['layout' => $layout]);
$user = User::factory()->memberOf($team)->create();

actingAs($user)
->get(route('kiosk.calendar'))
->assertOk()
->assertSee('data-kiosk-layout="' . $layout . '"', false)
->assertSee($expectedClasses, false);
})->with([
'landscape' => ['landscape', 'h-screen w-screen overflow-hidden'],
'portrait' => ['portrait', 'fixed top-0 left-[100vw] h-[100vw] w-[100vh] origin-top-left rotate-90 overflow-hidden'],
]);

test('uses the team appearance for the kiosk color scheme', function (string $appearance, bool $isDark) {
$team = Team::factory()->create(['appearance' => $appearance]);
$user = User::factory()->memberOf($team)->create();

$response = actingAs($user)
->get(route('kiosk.calendar'))
->assertOk()
->assertSee('data-kiosk-appearance="' . $appearance . '"', false)
->assertSee('const appearance = \'' . $appearance . '\';', false)
->assertDontSee('window.localStorage.getItem(\'flux.appearance\')', false);

$isDark
? $response->assertSee('class="dark"', false)
: $response->assertDontSee('class="dark"', false);
})->with([
'light' => ['light', false],
'dark' => ['dark', true],
'system' => ['system', false],
]);

test('can view events from feed', function () {
Http::allowStrayRequests(['https://calendar.google.com/calendar/ical/*']);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section class="flex min-h-[calc(100vh-4rem)] items-center justify-center p-6">
<section class="flex min-h-full items-center justify-center p-6">
<div class="w-full max-w-3xl rounded-lg border border-zinc-200 bg-white p-8 text-center dark:border-zinc-700 dark:bg-zinc-900">
<flux:icon name="clipboard-document-list" class="mx-auto mb-4 size-10 text-zinc-400" />
<flux:heading size="xl">{{ __('Chore Chart') }}</flux:heading>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/pages/kiosk/⚡lists/lists.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section class="flex min-h-[calc(100vh-4rem)] items-center justify-center p-6">
<section class="flex min-h-full items-center justify-center p-6">
<div class="w-full max-w-3xl rounded-lg border border-zinc-200 bg-white p-8 text-center dark:border-zinc-700 dark:bg-zinc-900">
<flux:icon name="queue-list" class="mx-auto mb-4 size-10 text-zinc-400" />
<flux:heading size="xl">{{ __('Lists') }}</flux:heading>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section class="flex min-h-[calc(100vh-4rem)] items-center justify-center p-6">
<section class="flex min-h-full items-center justify-center p-6">
<div class="w-full max-w-3xl rounded-lg border border-zinc-200 bg-white p-8 text-center dark:border-zinc-700 dark:bg-zinc-900">
<flux:icon name="cooking-pot" class="mx-auto mb-4 size-10 text-zinc-400" />
<flux:heading size="xl">{{ __('Meal Planning') }}</flux:heading>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/pages/kiosk/⚡routines/routines.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section class="flex min-h-[calc(100vh-4rem)] items-center justify-center p-6">
<section class="flex min-h-full items-center justify-center p-6">
<div class="w-full max-w-3xl rounded-lg border border-zinc-200 bg-white p-8 text-center dark:border-zinc-700 dark:bg-zinc-900">
<flux:icon name="arrow-path-rounded-square" class="mx-auto mb-4 size-10 text-zinc-400" />
<flux:heading size="xl">{{ __('Routines') }}</flux:heading>
Expand Down
Loading