Skip to content
This repository has been archived by the owner on Jun 17, 2023. It is now read-only.

Commit

Permalink
extracted presentation components out of listings
Browse files Browse the repository at this point in the history
  • Loading branch information
dominicfarr committed Nov 6, 2022
1 parent 79ada71 commit 79d54fb
Show file tree
Hide file tree
Showing 11 changed files with 451 additions and 97 deletions.
19 changes: 16 additions & 3 deletions src/api/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,25 @@ const collaboration = (listing, influencer) => {
};
};

const maxTwoDigits = (n) => {
let result = faker.random.numeric(2);
while (result > n) {
result = faker.random.numeric(2);
}

return result;
};

const capitalise = (s) => {
return s.charAt(0).toUpperCase() + s.toLowerCase().slice(1);
};

const listing = () => {
return {
id: uuid(),
title: faker.random.words(),
creativeGuidance: faker.random.words(10),
name: `${faker.word.noun()} ${faker.word.noun()}`,
title: capitalise(faker.random.words(maxTwoDigits(18))),
creativeGuidance: capitalise(faker.random.words(10)),
name: capitalise(faker.random.words(maxTwoDigits(18))),
image: faker.image.food(300, 300, true),
values: randomSelection(
VALUES,
Expand Down
16 changes: 15 additions & 1 deletion src/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import { ProposalStep3 } from "../presentation/proposal/ProposalStep3";
import { ProposalStep4 } from "../presentation/proposal/ProposalStep4";
import { Values } from "../presentation/values/Values";
import { YourDetails } from "../presentation/YourDetails";
import { Dev } from "../test/Dev";
import Dev from "../test/Dev";
import { AllCollaborations } from "./collaborations/AllCollaborations";
import { CollaborationList } from "./collaborations/CollaborationList";
import { Dashboard } from "./Dashboard";
import HomePage from "./HomePage";
Expand Down Expand Up @@ -97,6 +98,19 @@ function App() {
path="dashboard"
element={<Dashboard userType={userType(user)} />}
/>
<Route path="collaborations" element={<AllCollaborations />} />
<Route
path="collaborations/applied"
element={<CollaborationList state="APPLIED" />}
/>
<Route
path="collaborations/approved"
element={<CollaborationList state="APPROVED" />}
/>
<Route
path="collaborations/rejected"
element={<CollaborationList state="REJECTED" />}
/>
<Route path="listings" element={<AllListings />} />
<Route path="listings/new" element={<NewCollaborationProposal />} />
<Route path="listings/view/:id" element={<ProposalView />} />
Expand Down
131 changes: 131 additions & 0 deletions src/containers/collaborations/AllCollaborations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight";
import { Avatar, Box, IconButton, Paper, Typography } from "@mui/material";
import React from "react";
import { useSearchParams } from "react-router-dom";
import { collaborations as data, influencers, listings } from "../../api/data";
import { CollaborationsStateCounts } from "../../presentation/CollaborationsStateCounts";

export const AllCollaborations = () => {
const [collaborations, setCollaborations] = React.useState([]);
let [searchParams] = useSearchParams();
React.useEffect(() => {
setCollaborations(
data.filter((c) => {
let filter = searchParams.get("filter");
if (filter) {
return c.state.toLowerCase() === filter;
}

return c;
})
);
}, [searchParams]);

const handleClick = (c) => {
console.log(c);
};

return (
<Paper variant="outlined" sx={{ p: 2 }}>
<CollaborationsStateCounts
pb={1}
collaborations={data}
queryType
active={searchParams.get("filter")}
/>
{collaborations
.sort((a, b) => {
if (a.state < b.state) return -1;
if (a.state > b.state) return 1;
return 0;
})
.map((c) => {
const influencer = influencers.find((i) => i.id === c.influencer);
const listing = listings.find((l) => l.id === c.listing);

return (
<React.Fragment key={c.id}>
<Box
display="flex"
gap={3}
pb={1}
justifyItems="center"
alignItems="center"
border={0}
>
<Avatar
src={influencer.image}
title={`${influencer.givenName} ${influencer.familyName}`}
/>
<Box
border={0}
sx={{
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
flexGrow={1}
>
<Typography
sx={{
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
{listing.title}
</Typography>
<Typography
sx={{
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
{listing.name}
</Typography>
</Box>

<IconButton onClick={() => handleClick(c)}>
<KeyboardArrowRightIcon />
</IconButton>
</Box>
<Box
display="flex"
flexDirection="row"
gap={2}
pb={2}
justifyContent="flex-end"
>
<Typography>
{listing.listingMonth} {listing.listingYear}
</Typography>
<Box
sx={{
textTransform: "lowercase",
"&::first-letter": { textTransform: "capitalize" },
}}
>
{c.state}
</Box>
</Box>
</React.Fragment>
);
})}
</Paper>
);
};

/*
id: uuid(),
listing: listing.id,
state: randomSelection(COLLABORATION_STATES, 1),
application: {
details: faker.random.words(faker.random.numeric(2)),
posts: faker.random.numeric(1),
reels: faker.random.numeric(1, {
bannedDigits: ["4", "5", "6", "7", "8", "9"],
}),
},
influencer: influencer.id,
*/
113 changes: 45 additions & 68 deletions src/containers/proposals/AllListings.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
// import MailIcon from "@mui/icons-material/Mail";
import KeyboardArrowRightIcon from "@mui/icons-material/KeyboardArrowRight";
import {
Avatar,
// Badge,
Box,
Button,
IconButton,
Paper,
Typography,
} from "@mui/material";
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { collaborations, listings as data } from "../../api/data";
import { CollaborationsStateCounts } from "../../presentation/CollaborationsStateCounts";
const text = {
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
"&>p": {
fontWeight: 600,
"&::first-letter": {
textTransform: "capitalize",
},
},
};
import { listings as data, collaborations as collabs } from "../../api/data";
import { ListingRow } from "../../presentation/ListingRow";

export const AllListings = () => {
const nav = useNavigate();

const [listings, setListings] = React.useState([]);
const [collaborations, setCollaborations] = React.useState([]);

const handleClick = (listing) => {
nav("/listings/view/" + listing.id);
};
//TODO: Fixme: this won't be the way an api is called
useEffect(() => {
setListings(data);
setCollaborations(collabs);
}, []);
return (
<Box>
Expand All @@ -44,66 +31,56 @@ export const AllListings = () => {
</Box>
<Paper variant="outlined" sx={{ padding: 1 }}>
<Typography variant="h5">My Listings ({listings.length})</Typography>
<Box sx={{ overflow: "auto", height: 350 }}>
<Box
sx={{ overflow: "auto", height: 550 }}
display="flex"
flexDirection="column"
gap={2}
mt={1}
>
{listings
.sort(
(a, b) =>
Date.parse(`${a.listingMonth} 1, ${a.listingYear}`) -
Date.parse(`${b.listingMonth} 1, ${b.listingYear}`)
)
.map((p) => {
.map((listing) => {
const c = collaborations.filter((c) => {
return c.listing === listing.id;
});

const counts = groupBy(c, "state");
return (
<Box
key={p.id}
style={{
display: "flex",
marginTop: "10px",
cursor: "pointer",
alignItems: "center",
}}
>
<Box
onClick={() => handleClick(p)}
style={{ whiteSpace: "nowrap", marginRight: "10px" }}
>
<Avatar src={p.image} />
</Box>
<Box
style={{
minWidth: "100px",
overflow: "hidden",
marginRight: "10px",
flexGrow: 1,
}}
>
<Box onClick={() => handleClick(p)} sx={text}>
<Typography>{p.title}</Typography>
</Box>
<Box onClick={() => handleClick(p)} sx={text}>
<Typography>{p.name}</Typography>
</Box>
<Box p={0} m={0}>
<CollaborationsStateCounts
hideTitle
collaborations={collaborations}
listingId={p.id}
/>
</Box>
</Box>
<Box
sx={{ display: { xs: "none", sm: "block" } }}
alignSelf="center"
>
{p.listingMonth} {p.listingYear}
</Box>
<IconButton onClick={() => handleClick(p)}>
<KeyboardArrowRightIcon />
</IconButton>
</Box>
<ListingRow
key={listing.id}
id={listing.id}
listingTitle={listing.title}
productName={listing.name}
productImage={listing.image}
month={listing.listingMonth}
year={listing.listingYear}
appliedCount={counts.APPLIED.length}
approvedCount={counts.APPROVED.length}
rejectedCount={counts.REJECTED.length}
/>
);
})}
</Box>
</Paper>
</Box>
);
};

function groupBy(objectArray, property) {
return objectArray.reduce(
function (acc, obj) {
var key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
},
{ APPLIED: [], APPROVED: [], REJECTED: [] }
);
}
15 changes: 15 additions & 0 deletions src/presentation/AvartarLabel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Avatar, Box, Typography } from "@mui/material";
import React from "react";

export const AvartarLabel = ({ src, label }) => {
return (
<Box display="flex" alignItems="center" gap={1} border={0} flex={1}>
<Box>
<Avatar src={src} />
</Box>
<Box>
<Typography>{label}</Typography>
</Box>
</Box>
);
};
21 changes: 21 additions & 0 deletions src/presentation/CollaborationStateLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Typography } from "@mui/material";
import React from "react";
import { Link } from "react-router-dom";

const CollaborationStateLink = ({ label, count, color, path }) => {
return (
<Link
to={path}
style={{ textDecoration: "none" }}
title={`${count} ${label} collaboration`}
>
<Typography
ml={{ xs: 0, sm: 1 }}
mr={{ xs: 1, sm: 0 }}
color={color}
>{`${label}(${count})`}</Typography>
</Link>
);
};

export default CollaborationStateLink;
Loading

0 comments on commit 79d54fb

Please sign in to comment.