]> git.localhorst.tv Git - alttp.git/commitdiff
show unconfirmed episodes to privileged users
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 29 Jul 2025 07:42:52 +0000 (09:42 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Tue, 29 Jul 2025 07:42:52 +0000 (09:42 +0200)
app/Http/Controllers/EpisodeController.php
resources/js/components/episodes/Item.jsx
resources/js/i18n/de.js
resources/js/i18n/en.js
resources/sass/episodes.scss

index 3e3fd8a7959de67657dec69b7d5d998be920cabc..1458f91d07b5c9b5668bfe6acef75834501fbdb8 100644 (file)
@@ -8,6 +8,7 @@ use App\Models\Episode;
 use App\Models\EpisodeCrew;
 use App\Models\User;
 use Carbon\Carbon;
+use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\DB;
 
@@ -228,7 +229,6 @@ class EpisodeController extends Controller {
                $episodes = Episode::with(['channels', 'event', 'players', 'players.user'])
                        ->select('episodes.*')
                        ->join('events', 'episodes.event_id', '=', 'events.id')
-                       ->where('episodes.confirmed', '=', true)
                        ->where('events.visible', '=', true)
                        ->orderBy('episodes.start', $reverse ? 'DESC' : 'ASC')
                        ->limit(1000);
@@ -240,12 +240,24 @@ class EpisodeController extends Controller {
                if (isset($validatedData['before'])) {
                        $episodes = $episodes->where('episodes.start', '<=', $validatedData['before']);
                }
+               $privIDs = $this->getUserPrivilegedEvents($request);
+               if (!empty($privIDs)) {
+                       $episodes->where(function (Builder $query) use ($privIDs) {
+                               $query->where('episodes.confirmed', '=', true);
+                               $query->orWhereIn('episodes.event_id', $privIDs);
+                       });
+               } else {
+                       $episodes->where('episodes.confirmed', '=', true);
+               }
                if (!empty($validatedData['event'])) {
                        if (isset($validatedData['eventInvert']) && $validatedData['eventInvert']) {
-                               $episodes = $episodes->whereNotIn('episodes.event_id', $validatedData['event']);
+                               $episodes->whereNotIn('episodes.event_id', $validatedData['event']);
+                               $episodes->where('events.visible', '=', true);
                        } else {
                                $episodes = $episodes->whereIn('episodes.event_id', $validatedData['event']);
                        }
+               } else {
+                       $episodes->where('events.visible', '=', true);
                }
                if (!empty($validatedData['game'])) {
                        if (isset($validatedData['gameInvert']) && $validatedData['gameInvert']) {
@@ -285,6 +297,16 @@ class EpisodeController extends Controller {
                return $episode->toJson();
        }
 
+       private function getUserPrivilegedEvents(Request $request): array {
+               if (!$request->user()) {
+                       return [];
+               }
+               return $request->user()->event_crews()
+                       ->where('role', '=', 'admin')
+                       ->pluck('event_id')
+                       ->toArray();
+       }
+
        private function validateEpisode(Request $request) {
                return $request->validate([
                        'comment' => 'string',
index 5b7bd01afb4b7052f1eb7d88f6fe5df6efc010e7..401930f8ffe7202e8ae35419b16588d27a0927e5 100644 (file)
@@ -34,6 +34,9 @@ const Item = ({ episode }) => {
        if (isActive(episode)) {
                classNames.push('is-active');
        }
+       if (!episode.confirmed) {
+               classNames.push('is-unconfirmed');
+       }
 
        const style = React.useMemo(() => {
                if (episode.event && episode.event.corner) {
@@ -55,7 +58,10 @@ const Item = ({ episode }) => {
                        <div className="episode-titlebar">
                                {episode.title || episode.event ?
                                        <h3 className="episode-title fs-5 fs-md-4">
-                                               {episode.title || episode.event.title}
+                                               {!episode.confirmed ?
+                                                       <span>{`${t('episodes.unconfirmed')} `}</span>
+                                               : null}
+                                               <span>{episode.title || episode.event.title}</span>
                                        </h3>
                                : null}
                                {episode.comment ?
@@ -146,6 +152,7 @@ Item.propTypes = {
                channels: PropTypes.arrayOf(PropTypes.shape({
                })),
                comment: PropTypes.string,
+               confirmed: PropTypes.bool,
                crew: PropTypes.arrayOf(PropTypes.shape({
                })),
                event: PropTypes.shape({
index 1c3a44a1181085dcd1c7b8c9dc223d530da89736..5b08008adb7df9a52a3e21ef75c40669545bdf8d 100644 (file)
@@ -248,6 +248,7 @@ export default {
                        startTime: '{{ date, LL LT }} Uhr',
                        title: 'Bezeichnung',
                        tracking: 'Tracking',
+                       unconfirmed: '(unbestÃĪtigt)',
                },
                error: {
                        403: {
index d9443c7c474e166242cf1f17fbc7f796963a7e63..7247360c49fcd11fb7a52907b0dd0d3c28a487c8 100644 (file)
@@ -248,6 +248,7 @@ export default {
                        startTime: '{{ date, LL LT }}',
                        title: 'Title',
                        tracking: 'Tracking',
+                       unconfirmed: '(unconfirmed)',
                },
                error: {
                        403: {
index c53ea10eba2f1a918594add9837b54581362fd33..e8ae7ed6f6d5e182926f74f38673e91c5182deeb 100644 (file)
@@ -14,6 +14,7 @@
 }
 
 .episodes-item {
+       position: relative;
        background-size: 6rem auto;
        background-repeat: no-repeat;
        background-position: left bottom;
                box-shadow: 0 0 0.25rem 0.25rem $success;
        }
 
+       &.is-unconfirmed {
+               background-color: rgba(255, 255, 255, 0.1);
+       }
+
        .episode-start {
                width: 4rem;
        }