Skip to content

Commit

Permalink
Merge pull request #18 from LMacPhail/smaller-ui-fixes
Browse files Browse the repository at this point in the history
Smaller UI fixes
  • Loading branch information
LMacPhail authored Dec 4, 2023
2 parents 944f540 + dcb7987 commit fb99b97
Show file tree
Hide file tree
Showing 16 changed files with 542 additions and 54 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.14.19",
"@phosphor-icons/react": "^2.0.14",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
Expand Down
12 changes: 6 additions & 6 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ export const Header: React.FC<{
<div className="flex gap-2">
<button
className={`btn btn-${
view === "about" ? "outline-primary" : "ghost"
view === "index" ? "outline-primary" : "ghost"
}`}
onClick={() => setView("about")}
onClick={() => setView("index")}
>
About
Index
</button>
<button
className={`btn btn-${
view === "index" ? "outline-primary" : "ghost"
view === "about" ? "outline-primary" : "ghost"
}`}
onClick={() => setView("index")}
onClick={() => setView("about")}
>
Index
About
</button>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/atoms/PolicyBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export const PolicyBadge: React.FC<{
<span
className={`w-min ${getBGColour(
positive
)} text-white text-xs rounded-full px-2 py-1`}
)} text-white text-xs rounded-full px-2 py-1 whitespace-nowrap`}
>
{policyName}
{policyName === "publicOwnership" ? "public ownership" : policyName}
</span>
);
};
14 changes: 12 additions & 2 deletions src/components/content/FormattedContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ export const FormattedContent: React.FC<{
<li key={i}>
{formattedPoint.content}{" "}
{formattedPoint.link?.[0] && (
<a className="text-blue-500" href={formattedPoint.link[0]}>
<a
className="text-blue-500"
href={formattedPoint.link[0]}
target="_blank"
rel="noreferrer"
>
(source)
</a>
)}
Expand All @@ -32,7 +37,12 @@ export const FormattedContent: React.FC<{
<>
{formattedContent[0].content}{" "}
{formattedContent[0].link && formattedContent[0].link.length > 0 && (
<a className="text-blue-500" href={formattedContent[0]?.link[0]}>
<a
className="text-blue-500"
href={formattedContent[0]?.link[0]}
target="_blank"
rel="noreferrer"
>
(source)
</a>
)}
Expand Down
8 changes: 4 additions & 4 deletions src/components/content/MPIndex.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import React, { useEffect, useState } from "react";
import { SearchInput } from "../SearchInput";
import React, { useMemo, useState } from "react";
import { Accordion } from "./Accordion";
import { filterProfiles } from "../../data/utils/utils";
import { useSelector } from "react-redux";
import { AppState } from "../../state/store";
import { MP } from "../../data/types";
import { Spinner } from "../atoms/Spinner";
import { Filters } from "../filters/Filters";

const MPIndex: React.FC = () => {
const filters = useSelector((state: AppState) => state.activeFilters);
const data = useSelector((state: AppState) => state.data);
const { profiles, status } = data;
const [mps, setMPs] = useState<MP[]>(filterProfiles(profiles, filters));

useEffect(() => {
useMemo(() => {
setMPs(filterProfiles(profiles, filters));
}, [filters, profiles]);

Expand All @@ -25,7 +25,7 @@ const MPIndex: React.FC = () => {
</div>
) : (
<div className="flex flex-col">
<SearchInput />
<Filters />
<Accordion mps={mps} />
</div>
)}
Expand Down
35 changes: 27 additions & 8 deletions src/components/content/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import {
Contact,
Policy,
PolicyInterests,
PolicyType,
Expand All @@ -24,7 +25,7 @@ export const ProfileHeader: React.FC<{
bio: string;
constituency: string;
profile?: string;
contact?: string;
contact?: Contact;
socials: SocialMediaLinks;
policyInterests: Record<PolicyType, Policy>;
}> = ({
Expand All @@ -48,6 +49,7 @@ export const ProfileHeader: React.FC<{
return <LinkedinLogo size={LOGO_SIZE} />;
}
};

return (
<div className="flex flex-col overflow-x-hidden">
<div className="flex flex-row justify-between flex-wrap">
Expand All @@ -71,12 +73,24 @@ export const ProfileHeader: React.FC<{
<p className="font-light text-sm mb-2">{bio}</p>
<p className="font-light text-sm italic">{constituency}</p>
{contact && (
<p>
<span className="font-bold text-sm">Contact details: </span>
<span className="font-light text-sm italic hover:cursor-text">
{contact}
</span>
</p>
<>
{contact.email && (
<p>
<span className="font-bold text-sm">Email: </span>
<span className="font-light text-sm italic hover:cursor-text">
{contact.email}
</span>
</p>
)}
{contact.phone && (
<p>
<span className="font-bold text-sm">Phone: </span>
<span className="font-light text-sm italic hover:cursor-text">
{contact.phone}
</span>
</p>
)}
</>
)}
</span>
</div>
Expand All @@ -88,7 +102,12 @@ export const ProfileHeader: React.FC<{
.map((site: string) => {
const link = socials[site as keyof SocialMediaLinks];
return (
<a href={link} key={`${name}-${site}-link`}>
<a
href={link}
key={`${name}-${site}-link`}
target="_blank"
rel="noreferrer"
>
{getLogo(site)}
</a>
);
Expand Down
46 changes: 44 additions & 2 deletions src/components/filters/Filters.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,48 @@
import React from "react";
import { PolicyStance } from "./PolicyStance";
import { SearchInput } from "../SearchInput";

export const Filters: React.FC = () => {
return <PolicyStance />;
return (
<div className="">
<SearchInput />
</div>
);
};

// type SelectedSortDirection = "ascending" | "descending";

// TODO: Not make this break everything
// const SortByDropdown: React.FC = () => {
// const dispatch = useDispatch();
// const profiles = useSelector((state: AppState) => state.data.profiles);

// const [sortDirection, setSortDirection] = useState<
// SelectedSortDirection | undefined
// >(undefined);

// const handleSelectChange = (value: SelectedSortDirection) => {
// const sortedProfiles = sortByWin(profiles, value === "descending");
// dispatch({
// type: SET_DATA_ACTION,
// payload: { profiles: sortedProfiles, status: "complete" },
// });
// setSortDirection(value);
// };

// return (
// <select
// className="select select-ghost-primary"
// value={sortDirection}
// onChange={(event) =>
// handleSelectChange(event.target.value as SelectedSortDirection)
// }
// aria-label="sort profiles"
// >
// {sortDirection === undefined && (
// <option>Sort by chance of winning</option>
// )}
// <option>Most Likely to Win</option>
// <option>Least Likely to Win</option>
// </select>
// );
// };
4 changes: 1 addition & 3 deletions src/components/filters/PolicyStance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const categories: PolicyType[] = [
"workers",
"NHS",
"benefits",
"strikes",
"publicOwnership",
"housing",
"palestine",
Expand Down Expand Up @@ -50,7 +49,7 @@ const FilterCheckbox: React.FC<{

return (
<div
className={`flex flex-row justify-between m-3 ${category}`}
className={`flex flex-row justify-between ${category} text-black dark:text-white mb-4`}
key={category}
>
<p className="flex align-middle text-center capitalize">
Expand All @@ -59,7 +58,6 @@ const FilterCheckbox: React.FC<{
<input
type="checkbox"
className="checkbox"
checked={checked}
onClick={() => handleCheck()}
onChange={(_e) => handleCheck()}
/>
Expand Down
4 changes: 2 additions & 2 deletions src/components/sidebar/SidebarContent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { Filters } from "../filters/Filters";
import { ProjectTitle } from "../atoms/ProjectTitle";
import { Footer } from "./Footer";
import { PolicyStance } from "../filters/PolicyStance";

export const SidebarContent: React.FC = () => {
return (
Expand All @@ -10,7 +10,7 @@ export const SidebarContent: React.FC = () => {
<ProjectTitle />
<div className="divider"></div>
</div>
<Filters />
<PolicyStance />
<Footer />
</div>
);
Expand Down
11 changes: 8 additions & 3 deletions src/data/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ export const policyTypeNames = [
"workers",
"NHS",
"benefits",
"strikes",
"publicOwnership",
"housing",
"palestine",
];

export type PolicyType = (typeof policyTypeNames)[number];
Expand All @@ -33,7 +34,6 @@ export type PolicyInterests = {
workers: Policy; // 26
NHS: Policy; // 28
benefits: Policy; // 30
strikes: Policy; // 32
publicOwnership: Policy; // 34
housing: Policy; // 41
palestine: Policy; // 43
Expand All @@ -46,6 +46,11 @@ export type SocialMediaLinks = {
instagram?: string;
};

export type Contact = {
email?: string;
phone?: string;
};

export type MP = {
name: string; // 0
constituency: string; // 1
Expand All @@ -61,7 +66,7 @@ export type MP = {
directorOfCompanies: string;
};
policyInterests: Record<PolicyType, Policy>;
contact?: string; // 40
contact?: Contact; // 40
educationType?: string; // 41
notes?: string; // 42
profilePic?: string; // 43
Expand Down
18 changes: 17 additions & 1 deletion src/data/utils/string.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { extractLinks } from "./string";
import { extractContacts, extractLinks } from "./string";

describe("extractLinks", () => {
const basic = "Something something https://something.com";
Expand All @@ -22,3 +22,19 @@ describe("extractLinks", () => {
expect(formatted.content[1]).toEqual("Bleep bloop");
});
});

describe("extractContacts", () => {
it("extracts just an email", () => {
const contact = extractContacts("[email protected]");
expect(contact?.email).toBe("[email protected]");
expect(contact?.phone).toBe(undefined);
});

it("extracts email and a phone from the same string", () => {
const contact = extractContacts(
"[email protected] / 0121 303 2039"
);
expect(contact?.email).toBe("[email protected]");
expect(contact?.phone).toBe("0121 303 2039");
});
});
23 changes: 23 additions & 0 deletions src/data/utils/string.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Contact } from "../types";

const urlRegex = /(https?:\/\/[^ ]*)/g;
const bracketRegex = /[<>]/g;

const emailRegex = /[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+/;
const phoneRegex = /^(?:\s*\d){11}$/;

/**
* Given a content string including a hyperlink in <> parentheses, separates into content and link
*/
Expand All @@ -24,3 +29,21 @@ export const extractLinks = (

return { content, link };
};

const getMatchFromMatches = (
matches: RegExpMatchArray | null
): string | undefined =>
matches && matches.length > 0 ? matches[0] : undefined;

export const extractContacts = (raw: string): Contact | undefined => {
const email = getMatchFromMatches(raw.match(emailRegex));
const phone = getMatchFromMatches(raw.match(phoneRegex));

if (email || phone) {
return {
email,
phone,
};
}
return;
};
Loading

0 comments on commit fb99b97

Please sign in to comment.