]> git.localhorst.tv Git - alttp.git/commitdiff
group crew by channel for multi-channel episodes
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 26 Jul 2025 10:10:09 +0000 (12:10 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 26 Jul 2025 10:10:09 +0000 (12:10 +0200)
resources/js/components/episodes/Crew.jsx
resources/js/components/episodes/CrewList.jsx [new file with mode: 0644]
resources/sass/episodes.scss

index d89acae30e0c77cf42b701984273301e6a00c3f1..f1a828954fe48405855f45f5743f68e7e5c9e850 100644 (file)
@@ -3,7 +3,7 @@ import React from 'react';
 import { Button, Col, Row } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 
-import CrewMember from './CrewMember';
+import CrewList from './CrewList';
 import Icon from '../common/Icon';
 import { compareCrew } from '../../helpers/Crew';
 import {
@@ -56,9 +56,7 @@ const Crew = ({ episode }) => {
                                        <Icon.MICROPHONE className="ms-3 me-2" title="" />
                                        {t('episodes.commentary')}
                                </div>
-                               {commentators.map(c =>
-                                       <CrewMember crew={c} key={c.id} />
-                               )}
+                               <CrewList crews={commentators} episode={episode} />
                                {onApplyRestream && canApplyForEpisode(user, episode, 'commentary') ?
                                        <div className="button-bar m-2">
                                                <Button
@@ -91,9 +89,7 @@ const Crew = ({ episode }) => {
                                        <Icon.MOUSE className="ms-3 me-2" title="" />
                                        {t('episodes.tracking')}
                                </div>
-                               {trackers.map(c =>
-                                       <CrewMember crew={c} key={c.id} />
-                               )}
+                               <CrewList crews={trackers} episode={episode} />
                                {onApplyRestream && canApplyForEpisode(user, episode, 'tracking') ?
                                        <div className="button-bar m-2">
                                                <Button
@@ -126,9 +122,7 @@ const Crew = ({ episode }) => {
                                        <Icon.MONITOR className="ms-3 me-2" title="" />
                                        {t('episodes.setup')}
                                </div>
-                               {techies.map(c =>
-                                       <CrewMember crew={c} key={c.id} />
-                               )}
+                               <CrewList crews={techies} episode={episode} />
                        </Col>
                : null}
        </Row>;
diff --git a/resources/js/components/episodes/CrewList.jsx b/resources/js/components/episodes/CrewList.jsx
new file mode 100644 (file)
index 0000000..fcc5c7d
--- /dev/null
@@ -0,0 +1,44 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+
+import CrewMember from './CrewMember';
+
+const CrewList = ({ crews, episode }) => {
+       const byChannel = React.useMemo(() => {
+               const bc = {};
+               crews.forEach((crew) => {
+                       if (!bc[crew.channel_id]) {
+                               bc[crew.channel_id] = {
+                                       channel: episode.channels.find((c) => c.id === crew.channel_id),
+                                       crews: [],
+                               };
+                       }
+                       bc[crew.channel_id].crews.push(crew);
+               });
+               return Object.entries(bc).map(([, value]) => value).filter(c => !!c.channel);
+       }, [crews, episode]);
+
+       return <div>
+               {byChannel.map(({ channel, crews }) => (
+                       <fieldset className="crew-list" key={channel.id}>
+                               {byChannel.length > 1 ?
+                                       <legend>{channel.title}</legend>
+                               : null}
+                               {crews.map((crew) => (
+                                       <CrewMember crew={crew} key={crew.id} />
+                               ))}
+                       </fieldset>
+               ))}
+       </div>;
+};
+
+CrewList.propTypes = {
+       crews: PropTypes.arrayOf(PropTypes.shape({
+       })),
+       episode: PropTypes.shape({
+               channels: PropTypes.arrayOf(PropTypes.shape({
+               })),
+       }),
+};
+
+export default CrewList;
index b76df22af37ef86a9f352ae2cdca13259669e812..c53ea10eba2f1a918594add9837b54581362fd33 100644 (file)
        }
 }
 
+.crew-list {
+       legend {
+               margin-bottom: 0;
+               font-size: 100%;
+       }
+}
+
 .crew-member {
        border: none;