initial commit
This commit is contained in:
63
client/src/Musicians/Musician/Bio/Bio.tsx
Normal file
63
client/src/Musicians/Musician/Bio/Bio.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import EditButton from "../../../Buttons/EditButton/EditButton";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Col, Card, Container } from "react-bootstrap";
|
||||
import EditBioForm from "../../../Forms/Bio/BioForm";
|
||||
import EditModal from "../../../EditModals/EditModal";
|
||||
import { MusicianObj } from "../Musician";
|
||||
import { faPen } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
interface BioProps {
|
||||
musician: MusicianObj;
|
||||
textPosition: string;
|
||||
onBioChange: () => void;
|
||||
setMusician: React.Dispatch<React.SetStateAction<MusicianObj>>;
|
||||
token: string;
|
||||
}
|
||||
|
||||
function MusicianBio(props: BioProps) {
|
||||
const [modalShow, setModalShow] = useState(false);
|
||||
const EditTitle = `Edit ${props.musician.name}'s Bio`;
|
||||
|
||||
useEffect(() => {
|
||||
props.setMusician(props.musician);
|
||||
}, [props]);
|
||||
|
||||
const Editable = (
|
||||
<Container>
|
||||
<EditButton
|
||||
setModalShow={setModalShow}
|
||||
faIcon={faPen}
|
||||
actionName=" Bio"
|
||||
/>
|
||||
<EditModal
|
||||
show={modalShow}
|
||||
onHide={() => setModalShow(false)}
|
||||
title={EditTitle}
|
||||
entity={props.musician}
|
||||
form={
|
||||
<EditBioForm
|
||||
entity={props.musician}
|
||||
hideModal={setModalShow}
|
||||
onBioChange={props.onBioChange}
|
||||
setMusician={props.setMusician}
|
||||
token={props.token}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
|
||||
return (
|
||||
<Col md={6} key="bioCard">
|
||||
<Card className={`${props.textPosition}`}>
|
||||
<Card.Header className="display-6">{props.musician.name}</Card.Header>
|
||||
<Card.Body>
|
||||
{props.token && Editable}
|
||||
<Card.Text>{props.musician.bio}</Card.Text>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
|
||||
export default MusicianBio;
|
||||
0
client/src/Musicians/Musician/Headshot/Headshot.css
Normal file
0
client/src/Musicians/Musician/Headshot/Headshot.css
Normal file
64
client/src/Musicians/Musician/Headshot/Headshot.tsx
Normal file
64
client/src/Musicians/Musician/Headshot/Headshot.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { faUpload } from "@fortawesome/free-solid-svg-icons";
|
||||
import EditButton from "../../../Buttons/EditButton/EditButton";
|
||||
import { Col, Container, Image } from "react-bootstrap";
|
||||
import HeadshotUpload from "../../../Forms/HeadshotUpload/HeadshotUploadForm";
|
||||
import EditModal from "../../../EditModals/EditModal";
|
||||
import { useState } from "react";
|
||||
import { MusicianObj } from "../Musician";
|
||||
import "./Headshot.css";
|
||||
|
||||
export interface HeadshotProps {
|
||||
src: string;
|
||||
musician: MusicianObj;
|
||||
onHeadshotChange?: () => void;
|
||||
setMusician?: React.Dispatch<React.SetStateAction<MusicianObj>>;
|
||||
token: string;
|
||||
}
|
||||
|
||||
function Headshot(props: HeadshotProps) {
|
||||
const [modalShow, setModalShow] = useState(false);
|
||||
|
||||
const EditableHeadshot = (
|
||||
<Container>
|
||||
<EditButton
|
||||
setModalShow={setModalShow}
|
||||
faIcon={faUpload}
|
||||
actionName=" Headshot"
|
||||
/>
|
||||
<EditModal
|
||||
show={modalShow}
|
||||
onHide={() => setModalShow(false)}
|
||||
title="Edit Headshot"
|
||||
entity={props.musician}
|
||||
form={
|
||||
<HeadshotUpload
|
||||
currentHeadshot={props.src}
|
||||
musician={props.musician}
|
||||
onHeadshotChange={props?.onHeadshotChange}
|
||||
hideModal={setModalShow}
|
||||
setMusician={props?.setMusician}
|
||||
token={props.token}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
|
||||
return (
|
||||
<Col
|
||||
key="headshot"
|
||||
className="d-flex align-items-center justify-content-center position-relative"
|
||||
>
|
||||
<Container className="d-flex align-items-center justify-content-center flex-column">
|
||||
<Image
|
||||
src={props.src}
|
||||
className="img-fluid rounded-circle"
|
||||
alt={props.musician.name}
|
||||
/>
|
||||
{props.token && EditableHeadshot}
|
||||
</Container>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
|
||||
export default Headshot;
|
||||
9
client/src/Musicians/Musician/Musician.css
Normal file
9
client/src/Musicians/Musician/Musician.css
Normal file
@@ -0,0 +1,9 @@
|
||||
.musician-container {
|
||||
margin-bottom: 6rem;
|
||||
padding-top: 70px;
|
||||
margin-top: -70px;
|
||||
}
|
||||
/*
|
||||
.musician-card {
|
||||
background-color: transparent !important;
|
||||
} */
|
||||
68
client/src/Musicians/Musician/Musician.tsx
Normal file
68
client/src/Musicians/Musician/Musician.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Container, Row } from "react-bootstrap";
|
||||
import cld from "../../Cld/CloudinaryConfig";
|
||||
import "./Musician.css";
|
||||
import Headshot from "./Headshot/Headshot";
|
||||
import MusicianBio from "./Bio/Bio";
|
||||
import { useState } from "react";
|
||||
|
||||
export class MusicianObj {
|
||||
id: number;
|
||||
name: string;
|
||||
bio: string;
|
||||
headshot_id: string;
|
||||
|
||||
constructor(id: number, name: string, bio: string, headshot_id: string) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.bio = bio;
|
||||
this.headshot_id = headshot_id;
|
||||
}
|
||||
}
|
||||
|
||||
export interface MusicianProps {
|
||||
musician: MusicianObj;
|
||||
onBioChange: () => void;
|
||||
onHeadshotChange?: () => void;
|
||||
token: string;
|
||||
}
|
||||
|
||||
function Musician(props: MusicianProps) {
|
||||
const [musician, setMusician] = useState<MusicianObj>(props.musician);
|
||||
const textPosition = musician.id % 2 === 0 ? "text-end" : "text-start";
|
||||
const image = cld.image(musician.headshot_id);
|
||||
const imgUrl = image.toURL();
|
||||
const musicianID = musician.name.split(" ").join("-").toLowerCase();
|
||||
const key = `musician-${musician.id}`;
|
||||
|
||||
const bioCard = (
|
||||
<MusicianBio
|
||||
key={key}
|
||||
musician={musician}
|
||||
textPosition={textPosition}
|
||||
onBioChange={props.onBioChange}
|
||||
setMusician={setMusician}
|
||||
token={props.token}
|
||||
/>
|
||||
);
|
||||
|
||||
const headshot = (
|
||||
<Headshot
|
||||
src={imgUrl}
|
||||
key="headshot"
|
||||
musician={musician}
|
||||
onHeadshotChange={props?.onHeadshotChange}
|
||||
setMusician={setMusician}
|
||||
token={props.token}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Container id={musicianID} className="musician-container">
|
||||
<Row className="row-spacing">
|
||||
{musician.id % 2 === 0 ? [bioCard, headshot] : [headshot, bioCard]}
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export default Musician;
|
||||
10
client/src/Musicians/Musicians.css
Normal file
10
client/src/Musicians/Musicians.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.musicians-title {
|
||||
color: var(--group-info-color);
|
||||
margin-bottom: 6rem;
|
||||
}
|
||||
|
||||
#musicians {
|
||||
padding-top: 70px;
|
||||
margin-top: -70px;
|
||||
margin-bottom: 400px;
|
||||
}
|
||||
47
client/src/Musicians/Musicians.tsx
Normal file
47
client/src/Musicians/Musicians.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useState } from "react";
|
||||
import Musician, { MusicianObj } from "./Musician/Musician";
|
||||
import { Col, Container } from "react-bootstrap";
|
||||
import "./Musicians.css";
|
||||
|
||||
interface MusiciansProps {
|
||||
musicians: MusicianObj[];
|
||||
setMusicians: React.Dispatch<React.SetStateAction<MusicianObj[]>>;
|
||||
token: string;
|
||||
}
|
||||
|
||||
function Musicians(props: MusiciansProps) {
|
||||
const [update, setUpdate] = useState<boolean>(false);
|
||||
const musicians = props.musicians;
|
||||
|
||||
const handleBioChange = () => {
|
||||
setUpdate(!update);
|
||||
};
|
||||
const handleHeadshotChange = () => {
|
||||
setUpdate(!update);
|
||||
};
|
||||
|
||||
const musicianList = musicians.map((musician) => (
|
||||
<Musician
|
||||
key={musician.id}
|
||||
musician={musician}
|
||||
onBioChange={handleBioChange}
|
||||
onHeadshotChange={handleHeadshotChange}
|
||||
token={props.token}
|
||||
/>
|
||||
));
|
||||
|
||||
return (
|
||||
<section id="musicians">
|
||||
<Col>
|
||||
<Container>
|
||||
<h3 className="display-3 text-end musicians-title">
|
||||
Meet the Musicians
|
||||
</h3>
|
||||
</Container>
|
||||
{musicianList}
|
||||
</Col>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export default Musicians;
|
||||
Reference in New Issue
Block a user