diff --git a/src/components/ArticleRow.tsx b/src/components/ArticleRow.tsx index 8c167cc..526ea4a 100644 --- a/src/components/ArticleRow.tsx +++ b/src/components/ArticleRow.tsx @@ -1,7 +1,9 @@ -import React, { DetailedHTMLProps } from 'react'; +import React from 'react'; import imageUrl from '../lib/imageUrl'; import '../css/article.css'; import ClickableLink from './ClickableLink'; +import FlexRow from './FlexRow'; +import FlexRowSection from './FlexRowSection'; export default function ArticleRow({ article, @@ -15,18 +17,16 @@ export default function ArticleRow({ ); } - const slug = (s: string) => { - return s.toLowerCase().replaceAll(' ', '-'); - }; + const slug = (s: string) => s.toLowerCase().replace(/ /g, '-'); + const articleUrl = '/news/' + article._id + '/' + slug(article.title); return ( -
-
{thumbnail}
-
- + + + {thumbnail} + + +

{article.title}

@@ -37,7 +37,7 @@ export default function ArticleRow({

{article.summary}

-
-
+ + ); } diff --git a/src/components/ConstrainedImage.tsx b/src/components/ConstrainedImage.tsx new file mode 100644 index 0000000..a35e93c --- /dev/null +++ b/src/components/ConstrainedImage.tsx @@ -0,0 +1,35 @@ +import { CSSProperties } from 'react'; + +export default function ConstrainedImage({ + alt, + src, + style, +}: { + alt: string; + src: string; + style?: CSSProperties; +}) { + return ( +
+ {alt} +
+ ); +} diff --git a/src/components/FlexRow.tsx b/src/components/FlexRow.tsx new file mode 100644 index 0000000..9410ea6 --- /dev/null +++ b/src/components/FlexRow.tsx @@ -0,0 +1,28 @@ +export default function FlexRow({ + paddingLeft, + paddingRight, + marginTop, + marginBottom, + children, +}: { + paddingLeft?: string; + paddingRight?: string; + marginTop?: string; + marginBottom?: string; + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} diff --git a/src/components/FlexRowSection.tsx b/src/components/FlexRowSection.tsx new file mode 100644 index 0000000..da0381d --- /dev/null +++ b/src/components/FlexRowSection.tsx @@ -0,0 +1,31 @@ +export default function FlexRowSection({ + children, + flex, + paddingLeft, + paddingRight, + paddingTop, + paddingBottom, + paddingX, + paddingY, +}: { + children: React.ReactNode; + flex: number; + paddingLeft?: string; + paddingRight?: string; + paddingTop?: string; + paddingBottom?: string; + paddingX?: string; + paddingY?: string; +}) { + if (paddingX != null) { + paddingLeft = paddingRight = paddingX; + } + if (paddingY != null) { + paddingTop = paddingBottom = paddingY; + } + return ( +
+ {children} +
+ ); +} diff --git a/src/components/MemberRow.tsx b/src/components/MemberRow.tsx index 3b15c10..f85b3eb 100644 --- a/src/components/MemberRow.tsx +++ b/src/components/MemberRow.tsx @@ -1,6 +1,8 @@ import imageUrl from '../lib/imageUrl'; import '../css/article.css'; import RowItemHeader from './RowItemHeader'; +import ConstrainedImage from './ConstrainedImage'; +import RowItemSubheader from './RowItemSubheader'; export default function MemberRow({ member, @@ -9,29 +11,35 @@ export default function MemberRow({ member: SGA.MemberDocument; limitPhotoHeight?: boolean; }) { - let thumbnail: React.ReactElement | null = null; - if (member.profile_photo) { - thumbnail = ( - {member.name} - ); - } + let thumbnail = member.profile_photo + ? imageUrl(member.profile_photo).url() + : undefined; return (
-
- {thumbnail} +
+ {thumbnail ? ( + limitPhotoHeight ? ( + + ) : ( + {member.name} + ) + ) : null}
-
+
{member.name} - + {member.role}, {member.year} - +

{member.bio}

diff --git a/src/components/Mission.tsx b/src/components/Mission.tsx index 8e1e4a2..7f74246 100644 --- a/src/components/Mission.tsx +++ b/src/components/Mission.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Link } from 'react-router-dom'; import '../css/mission.css'; import useMission from '../hooks/useMission'; +import BlueButtonLink from './BlueButtonLink'; export default function Mission() { let mission = useMission(); @@ -13,9 +13,7 @@ export default function Mission() {

“{mission.vision}”

- - Our Mission - + Our Mission
); diff --git a/src/components/RowItemSubheader.tsx b/src/components/RowItemSubheader.tsx new file mode 100644 index 0000000..f114b81 --- /dev/null +++ b/src/components/RowItemSubheader.tsx @@ -0,0 +1,3 @@ +export default function RowItemSubheader({ children }) { + return {children}; +} diff --git a/src/components/Segment.tsx b/src/components/Segment.tsx index 7b0d1f9..7470a94 100644 --- a/src/components/Segment.tsx +++ b/src/components/Segment.tsx @@ -15,14 +15,14 @@ function SegmentHeader({ children }: { children: React.ReactNode }) { ); } -export default function Segment({ title, content, imageURL, infoURL }) { +export default function Segment({ title, content, imageUrl, infoUrl }) { return (
{title} - {title} + {title}

{content}

- MORE INFO + MORE INFO
); } diff --git a/src/components/SegmentGroup.tsx b/src/components/SegmentGroup.tsx index d4a3e4a..63b06d6 100644 --- a/src/components/SegmentGroup.tsx +++ b/src/components/SegmentGroup.tsx @@ -1,26 +1,35 @@ import Segment from './Segment'; +export const segments = [ + { + imageUrl: '/images/segments/news-and-happenings.jpg', + infoUrl: '/news', + title: 'News and Happenings', + content: + 'Read about SGA initiatives, goals, and progress from SGA officers, as well as from other student leaders, students, and student organizations.', + }, + { + imageUrl: '/images/segments/who-we-are.jpg', + title: 'Who We Are', + infoUrl: '/officers', + content: + "Learn about your representatives, and how they're working to advance the common agenda that SGA has set to improve your experience at TJ.", + }, + { + imageUrl: '/images/segments/get-involved.jpg', + infoUrl: '/involved', + title: 'Get Involved', + content: + 'Any questions or concerns? Have an idea for how SGA could be doing more to advocate for students? Want to get involved? Contact Us!', + }, +]; + export default function InfoColumnGroup() { return (
- - - + {segments.map((segment) => ( + + ))}
); } diff --git a/src/css/article.css b/src/css/article.css index dce596d..6de455b 100644 --- a/src/css/article.css +++ b/src/css/article.css @@ -12,8 +12,13 @@ text-align: center; } +.article-row-thumbnail-height-constrained { + width: 100px; + height: 200px; +} + .article-row-thumbnail-height-constrained>img { - max-height: 200px; + object-fit: cover; } .article-row-content { diff --git a/src/pages/classcouncil.tsx b/src/pages/classcouncil.tsx index 894b01a..bba4411 100644 --- a/src/pages/classcouncil.tsx +++ b/src/pages/classcouncil.tsx @@ -24,8 +24,6 @@ export default function ClassCouncil() { return null; } - console.log(members); - let years: [string, SGA.MemberDocument[]][] = []; let currentYearMembers: SGA.MemberDocument[] = []; let currentYear = ''; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 8ebb9a2..9a23a98 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -6,16 +6,10 @@ import SegmentGroup from '../components/SegmentGroup'; export default function IndexPage() { return ( <> - {/* Hero image */} -
- {/* Info columns */} -
- - {/* Mission */}
diff --git a/src/pages/mission.tsx b/src/pages/mission.tsx index 525ac97..f13643a 100644 --- a/src/pages/mission.tsx +++ b/src/pages/mission.tsx @@ -24,24 +24,29 @@ export default function Mission() { return ( <> - {mission ? ( -
- +
+ {mission && ( + <> + - - - + + + + + )} - - - Previous Leadership - - -
- ) : null} + + + Previous Leadership + + +
); } diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js new file mode 100644 index 0000000..92753b1 --- /dev/null +++ b/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = (onPerfEntry) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals;