Skip to content

Commit

Permalink
feature/matter-page (#222)
Browse files Browse the repository at this point in the history
Creates the matters/:id route and corresponding page

Co-authored-by: Brian Ledbetter <Brian.Ledbetter@gettyimages.com>
  • Loading branch information
BrianL3 and Brian Ledbetter committed Jun 7, 2022
1 parent d67bc17 commit 7ee8245
Show file tree
Hide file tree
Showing 17 changed files with 298 additions and 45 deletions.
4 changes: 4 additions & 0 deletions src/app/App.tsx
Expand Up @@ -16,6 +16,7 @@ import { EventPage } from "../pages/EventPage";
import { EventsPage } from "../pages/EventsPage";
import { PersonPage } from "../pages/PersonPage";
import { PeoplePage } from "../pages/PeoplePage";
import { MatterPage } from "../pages/MatterPage";
import { ErrorPage } from "../pages/ErrorPage";

import { SEARCH_TYPE } from "../pages/SearchPage/types";
Expand Down Expand Up @@ -102,6 +103,9 @@ function App() {
<Route exact path="/people/:id">
<PersonPage />
</Route>
<Route exact path="/matters/:id">
<MatterPage />
</Route>
<Route path="*" component={ErrorPage} />
</Switch>
</Main>
Expand Down
1 change: 1 addition & 0 deletions src/assets/LocalizedStrings.tsx
Expand Up @@ -101,6 +101,7 @@ export interface MasterStringsList extends LocalizedStringsMethods {
latest_vote: string;
history: string;
minutes: string;
go_to_matter_details: string;
}

// Note: Add languages to video.js in /src/pages/EventPage/utils when adding new languages
Expand Down
1 change: 1 addition & 0 deletions src/assets/strings/de.ts
Expand Up @@ -90,6 +90,7 @@ const de = {
latest_vote: "Letzte Abstimmung",
history: "Geschichte",
minutes: "Protokoll",
go_to_matter_details: "Gehen Sie zu den vollständigen Rechtsvorschriften",
};

export default de;
1 change: 1 addition & 0 deletions src/assets/strings/en.ts
Expand Up @@ -89,6 +89,7 @@ const en = {
latest_vote: "Latest Vote",
history: "History",
minutes: "Minutes",
go_to_matter_details: "Go to Full Legislation Details",
};

export default en;
1 change: 1 addition & 0 deletions src/assets/strings/es.ts
Expand Up @@ -89,6 +89,7 @@ const es = {
latest_vote: "Último Voto",
history: "Historia",
minutes: "Protocolo",
go_to_matter_details: "Ir a los detalles completos de la legislación",
};

export default es;
13 changes: 7 additions & 6 deletions src/components/Details/Legislation/LegislationIntroduction.tsx
Expand Up @@ -38,12 +38,13 @@ const LegislationIntroduction: FC<LegislationIntroductionProps> = ({
flex: 1,
}}
>
{indexedMatterGrams.map((indexedMatterGram) => (
<div key={indexedMatterGram.id}>
<p style={{ display: "inline", paddingLeft: 11, paddingRight: 11 }}></p>
<p style={{ display: "inline" }}>{indexedMatterGram.unstemmed_gram}</p>
</div>
))}
{indexedMatterGrams &&
indexedMatterGrams.map((indexedMatterGram) => (
<div key={indexedMatterGram.id}>
<p style={{ display: "inline", paddingLeft: 11, paddingRight: 11 }}></p>
<p style={{ display: "inline" }}>{indexedMatterGram.unstemmed_gram}</p>
</div>
))}
</div>
</div>
</div>
Expand Down
50 changes: 27 additions & 23 deletions src/components/Details/Legislation/LegislationOverview.tsx
Expand Up @@ -63,11 +63,11 @@ export interface LegislationOverviewProps {
/** The latest matter status of the matter */
matterStatus: MatterStatus;
/** The latest event where the matter was a minutes item */
event: Event;
event?: Event;
/** The persons who sponsored the matter */
sponsors: Person[];
/** The latest document of the matter */
document: { name: string; url: string };
document?: { name: string; url: string };
}

const LegislationOverview: FC<LegislationOverviewProps> = ({
Expand Down Expand Up @@ -103,27 +103,31 @@ const LegislationOverview: FC<LegislationOverviewProps> = ({
<ProgressBar status={matterStatus.status} />
</dd>
</div>
<div>
<dt>Latest Meeting:</dt>
<dd>
<Link to={`/events/${event.id}`}>
{event.event_datetime.toLocaleDateString(language, {
timeZone: municipality.timeZone,
month: "short",
day: "numeric",
year: "numeric",
})}
</Link>
</dd>
</div>
<div>
<dt>Latest Document:</dt>
<dd>
<a target="_blank" rel="noopener noreferrer" href={document.url}>
{document.name}
</a>
</dd>
</div>
{event && (
<div>
<dt>Latest Meeting:</dt>
<dd>
<Link to={`/events/${event.id}`}>
{event.event_datetime.toLocaleDateString(language, {
timeZone: municipality.timeZone,
month: "short",
day: "numeric",
year: "numeric",
})}
</Link>
</dd>
</div>
)}
{document && (
<div>
<dt>Latest Document:</dt>
<dd>
<a target="_blank" rel="noopener noreferrer" href={document.url}>
{document.name}
</a>
</dd>
</div>
)}
<div>
<dt>Sponsored by:</dt>
<dd>
Expand Down
11 changes: 6 additions & 5 deletions src/components/Details/MinutesItemsList/MinutesItemsList.tsx
@@ -1,11 +1,12 @@
import React, { FC } from "react";
import styled from "@emotion/styled";
/* import { Link } from "react-router-dom"; */
import { Link } from "react-router-dom";

import DocumentsList from "./DocumentsList";
/* import ChevronDownIcon from "../../Shared/ChevronDownIcon"; */
import ChevronDownIcon from "../../Shared/ChevronDownIcon";

import { Item } from "./types";
import { strings } from "../../../assets/LocalizedStrings";

const ListItem = styled.li({
"& > div:first-of-type": {
Expand Down Expand Up @@ -37,11 +38,11 @@ const MinutesItemsList: FC<MinutesItemsListProps> = ({ minutesItems }: MinutesIt
return (
<ListItem key={elem.name}>
<div>{elem.name}</div>
{/* {elem.matter_ref && (
{elem.matter_ref && (
<Link to={`/matters/${elem.matter_ref}`}>
{"Go to Full Legislation Details"} <ChevronDownIcon />
{strings.go_to_matter_details} <ChevronDownIcon />
</Link>
)} */}
)}
{elem.description && <div>{elem.description}</div>}
<DocumentsList documents={elem.documents} />
</ListItem>
Expand Down
Expand Up @@ -98,7 +98,7 @@ function VoteCell(isExpanded: boolean, votes: IndividualMeetingVote[], isMobile:

const MeetingVotesTableRow = ({
index,
/* legislationLink, */
legislationLink,
legislationName,
legislationDescription,
councilDecision,
Expand All @@ -120,10 +120,11 @@ const MeetingVotesTableRow = ({
}}
>
<div>
{/* <Link to={legislationLink}>{legislationName}</Link> */}
<p className="mzp-c-card-desc" style={{ fontWeight: 600, marginBottom: 0 }}>
{legislationName}
</p>
<Link to={legislationLink}>
<p className="mzp-c-card-desc" style={{ fontWeight: 600, marginBottom: 0 }}>
{legislationName}
</p>
</Link>
{!isMobile && <p>{legislationDescription}</p>}
</div>
<DecisionResult result={councilDecision} />
Expand Down
11 changes: 6 additions & 5 deletions src/components/Tables/VotingTableRow/VotingTableRow.tsx
Expand Up @@ -35,7 +35,7 @@ export type VotingTableRowProps = {

const VotingTableRow = ({
index,
/* legislationLink, */
legislationLink,
legislationName,
legislationTags,
voteDecision,
Expand Down Expand Up @@ -67,10 +67,11 @@ const VotingTableRow = ({
columnDistribution={columnDistribution}
>
<React.Fragment>
{/* <Link to={legislationLink}>{legislationName}</Link> */}
<p className="mzp-c-card-desc" style={{ fontWeight: 600, marginBottom: 0 }}>
{legislationName}
</p>
<Link to={legislationLink}>
<p className="mzp-c-card-desc" style={{ fontWeight: 600, marginBottom: 0 }}>
{legislationName}
</p>
</Link>
{!isMobile && <p className="mzp-c-card-desc">{legislationTagsString}</p>}
</React.Fragment>
<DecisionResult result={voteDecision} />
Expand Down
51 changes: 51 additions & 0 deletions src/containers/MatterContainer/MatterContainer.tsx
@@ -0,0 +1,51 @@
import React from "react";
import styled from "@emotion/styled";

import MatterStatus from "../../models/MatterStatus";
import Event from "../../models/Event";
import Person from "../../models/Person";
import Vote from "../../models/Vote";
import IndexedMatterGram from "../../models/IndexedMatterGram";
import EventMinutesItem from "../../models/EventMinutesItem";

import LegislationIntroduction from "../../components/Details/Legislation/LegislationIntroduction";
import LegislationOverview from "../../components/Details/Legislation/LegislationOverview";
import { LegislationLatestVote } from "../../components/Details/Legislation/LegislationLatestVote";
import { LegislationHistory } from "../../components/Details/Legislation/LegislationHistory";

const Matter = styled.div({
display: "grid",
gridTemplateColumns: "1fr",
rowGap: 64,
});
interface MatterContainerProps {
matterStatus: MatterStatus;
indexedMatterGrams: IndexedMatterGram[];
event?: Event;
sponsors: Person[];
votes?: Vote[];
legislationHistory?: EventMinutesItem[];
}

const MatterContainer = ({
matterStatus,
indexedMatterGrams,
event,
sponsors,
votes,
legislationHistory,
}: MatterContainerProps) => {
return (
<Matter>
<LegislationIntroduction
matterStatus={matterStatus}
indexedMatterGrams={indexedMatterGrams}
/>
<LegislationOverview matterStatus={matterStatus} event={event} sponsors={sponsors} />
{votes && <LegislationLatestVote votes={votes} />}
{legislationHistory && <LegislationHistory eventMinutesItems={legislationHistory} />}
</Matter>
);
};

export default MatterContainer;
1 change: 1 addition & 0 deletions src/containers/MatterContainer/index.ts
@@ -0,0 +1 @@
export { default as MatterContainer } from "./MatterContainer";
8 changes: 7 additions & 1 deletion src/containers/PersonContainer/MattersSponsored.tsx
@@ -1,5 +1,6 @@
import React, { FC, useMemo, useCallback } from "react";
import { Loader } from "semantic-ui-react";
import { Link } from "react-router-dom";

import { useAppConfigContext } from "../../app";
import useFetchModels, {
Expand Down Expand Up @@ -74,7 +75,12 @@ const MattersSponsored: FC<MattersSponsoredProps> = ({ personId }: MattersSponso
<li key={matterSponsored.id}>
<dl>
<dt>
<strong>{matterSponsored.matter?.name}</strong>
<Link
key={matterSponsored.matter?.id}
to={`/matters/${matterSponsored.matter?.id}`}
>
<strong>{matterSponsored.matter?.name}</strong>
</Link>
</dt>
<dd>{matterSponsored.matter?.title}</dd>
</dl>
Expand Down
23 changes: 23 additions & 0 deletions src/networking/MatterSponsorService.ts
Expand Up @@ -27,6 +27,29 @@ export default class MatterSponsorService extends ModelService {
super(COLLECTION_NAME.MatterSponsor, firebaseConfig);
}

async getMatterSponsorByMatterId(matterId: string): Promise<MatterSponsor[]> {
const populatePerson = new Populate(
COLLECTION_NAME.MatterSponsor,
REF_PROPERTY_NAME.MatterSponsorPersonRef
);
const networkQueryResponse = this.networkService.getDocuments(
COLLECTION_NAME.MatterSponsor,
[
where(
REF_PROPERTY_NAME.MatterSponsorMatterRef,
WHERE_OPERATOR.eq,
doc(NetworkService.getDb(), COLLECTION_NAME.Matter, matterId)
),
],
new PopulationOptions([populatePerson])
);
return this.createModels(
networkQueryResponse,
MatterSponsor,
`getMatterSponsorByMatterId(${matterId})`
) as Promise<MatterSponsor[]>;
}

/**
*
* @param personId The person's id
Expand Down
44 changes: 44 additions & 0 deletions src/networking/MatterStatusService.ts
@@ -0,0 +1,44 @@
import ModelService from "./ModelService";
import { where, orderBy, doc } from "@firebase/firestore";
import {
COLLECTION_NAME,
Populate,
PopulationOptions,
REF_PROPERTY_NAME,
} from "./PopulationOptions";
import { ORDER_DIRECTION, WHERE_OPERATOR } from "./constants";
import { NetworkService } from "./NetworkService";

import MatterStatus from "../models/MatterStatus";
import { FirebaseConfig } from "../app/AppConfigContext";

export default class MatterStatusService extends ModelService {
constructor(firebaseConfig: FirebaseConfig) {
super(COLLECTION_NAME.MatterStatus, firebaseConfig);
}

async getMatterStatusesByMatterId(matterId: string): Promise<MatterStatus[]> {
const populateEventMinutesItems = new Populate(
COLLECTION_NAME.MatterStatus,
REF_PROPERTY_NAME.MatterStatusEventMinutesItemRef
);

const networkQueryResponse = this.networkService.getDocuments(
COLLECTION_NAME.MatterStatus,
[
where(
REF_PROPERTY_NAME.MatterStatusMatterRef,
WHERE_OPERATOR.eq,
doc(NetworkService.getDb(), COLLECTION_NAME.Matter, matterId)
),
orderBy("update_datetime", ORDER_DIRECTION.desc),
],
new PopulationOptions([populateEventMinutesItems])
);
return this.createModels(
networkQueryResponse,
MatterStatus,
`getMatterStatusByMatterId(${matterId})`
) as Promise<MatterStatus[]>;
}
}

0 comments on commit 7ee8245

Please sign in to comment.