add functionality for embedded program

This commit is contained in:
Lucas Jensen
2025-01-18 19:10:49 -08:00
parent 8c208adf4a
commit 0e150e72cc
6 changed files with 50 additions and 9 deletions

View File

@@ -30,6 +30,11 @@ body {
} }
} }
section {
margin-top: 10em;
margin-bottom: 10em;
}
.btn-primary { .btn-primary {
background-color: var(--group-info-color); background-color: var(--group-info-color);
border-color: var(--group-info-color); border-color: var(--group-info-color);

View File

@@ -1,23 +1,32 @@
import { Card, Container } from "react-bootstrap"; import { Card, Container, Image } from "react-bootstrap";
import "./Group.css"; import "./Group.css";
import EditModal from "../EditModals/EditModal"; import EditModal from "../EditModals/EditModal";
import { useState } from "react"; import { useEffect, useState } from "react";
import EditBioForm from "../Forms/Bio/BioForm"; import EditBioForm from "../Forms/Bio/BioForm";
import { faPen } from "@fortawesome/free-solid-svg-icons"; import { faPen } from "@fortawesome/free-solid-svg-icons";
import EditButton from "../Buttons/EditButton/EditButton"; import EditButton from "../Buttons/EditButton/EditButton";
import LivestreamPlayer from "../LivestreamPlayer/LivestreamPlayer"; import LivestreamPlayer from "../LivestreamPlayer/LivestreamPlayer";
import cld from "../Cld/CloudinaryConfig";
export class GroupObj { export class GroupObj {
id: number; id: number;
name: string; name: string;
bio: string; bio: string;
livestream_id: string; livestream_id: string;
livestream_program_cld_id?: string;
constructor(id: number, name: string, bio: string, livestream_id: string) { constructor(
id: number,
name: string,
bio: string,
livestream_id: string,
livestream_program_cld_id?: string,
) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.bio = bio; this.bio = bio;
this.livestream_id = livestream_id; this.livestream_id = livestream_id;
this.livestream_program_cld_id = livestream_program_cld_id;
} }
} }
@@ -30,10 +39,23 @@ interface GroupProps {
function Group(props: GroupProps) { function Group(props: GroupProps) {
const [modalShow, setModalShow] = useState(false); const [modalShow, setModalShow] = useState(false);
if (!props.group) { const [programId, setProgramId] = useState<string | undefined>(undefined);
const [programUrl, setProgramUrl] = useState<string | undefined>(undefined);
const group = props.group;
useEffect(() => {
if (group) {
setProgramId(group.livestream_program_cld_id);
}
if (programId) {
setProgramUrl(cld.image(programId).toURL());
}
}, [group, programId]);
if (!group) {
return null; return null;
} }
const group = props.group;
const EditTitle = `Edit ${group.name}'s Bio`; const EditTitle = `Edit ${group.name}'s Bio`;
@@ -65,7 +87,7 @@ function Group(props: GroupProps) {
return ( return (
<section id="about"> <section id="about">
<Container className="vh-100 d-flex align-items-center justify-content-center text-center"> <Container className="d-flex align-items-center justify-content-center text-center">
<Card className="group-info"> <Card className="group-info">
<Card.Body> <Card.Body>
<Card.Title> <Card.Title>
@@ -74,6 +96,17 @@ function Group(props: GroupProps) {
{group.livestream_id && ( {group.livestream_id && (
<LivestreamPlayer livestreamId={group.livestream_id} /> <LivestreamPlayer livestreamId={group.livestream_id} />
)} )}
{group.livestream_id && group.livestream_program_cld_id && (
<Container className="d-flex align-items-center justify-content-center flex-column">
<a href={programUrl} target="_blank">
<Image
src={programUrl}
className="img-fluid"
alt="A PDF of the program fo the current livestream"
/>
</a>
</Container>
)}
{props.token && EditIcon} {props.token && EditIcon}
<Card.Text className="lead group-bio">{group.bio}</Card.Text> <Card.Text className="lead group-bio">{group.bio}</Card.Text>
</Card.Body> </Card.Body>

View File

@@ -6,5 +6,4 @@
#musicians { #musicians {
padding-top: 70px; padding-top: 70px;
margin-top: -70px; margin-top: -70px;
margin-bottom: 400px;
} }

View File

@@ -15,5 +15,4 @@ hr {
#events { #events {
padding-top: 70px; padding-top: 70px;
margin-top: -70px; margin-top: -70px;
margin-bottom: 400px;
} }

View File

@@ -39,6 +39,7 @@ export const getRoot = async (): Promise<TheGrapefruitsDuoAPI> => {
response.data.group.name, response.data.group.name,
response.data.group.bio, response.data.group.bio,
response.data.group.livestream_id, response.data.group.livestream_id,
response.data.group.livestream_program_cld_id,
), ),
response.data.musicians.map( response.data.musicians.map(
(musician: MusicianObj) => (musician: MusicianObj) =>
@@ -110,6 +111,7 @@ export const getGroup = async (): Promise<GroupObj> => {
response.data.name, response.data.name,
response.data.bio, response.data.bio,
response.data.livestream_id, response.data.livestream_id,
response.data.livestream_program_cld_id,
); );
}; };
@@ -152,10 +154,11 @@ export const patchGroup = async (
livestream_id: string, livestream_id: string,
name: string, name: string,
user_token: string, user_token: string,
livestream_program_cld_id?: string,
): Promise<GroupObj> => { ): Promise<GroupObj> => {
const response = await api.patch( const response = await api.patch(
`/group/`, `/group/`,
{ id, bio, livestream_id, name }, { id, bio, livestream_id, name, livestream_program_cld_id },
{ headers: { Authorization: `Bearer ${user_token}` } }, { headers: { Authorization: `Bearer ${user_token}` } },
); );
return new GroupObj( return new GroupObj(
@@ -163,6 +166,7 @@ export const patchGroup = async (
response.data.name, response.data.name,
response.data.bio, response.data.bio,
response.data.livestream_id, response.data.livestream_id,
response.data.livestream_program_cld_id,
); );
}; };

View File

@@ -6,4 +6,5 @@ class Group(BaseModel):
name: str name: str
bio: str bio: str
livestream_id: str = "" livestream_id: str = ""
livestream_program_cld_id: Optional[str] = None # not a FK! references a cloudinary ID
id: Optional[int] = None id: Optional[int] = None