This commit is contained in:
Michael Fatemi 2021-01-05 23:31:27 -05:00
parent 4e93c4a948
commit b966fc92b7
22 changed files with 169 additions and 136 deletions

View File

@ -51,3 +51,18 @@ a.blue-button {
text-decoration: underline; text-decoration: underline;
color: #38A3BD; color: #38A3BD;
} }
.strong-paragraph {
color: #444;
font-size: 22px;
line-height: 33px;
font-weight: 300;
}
.paragraph-with-header-header {
font-size: 1.5rem;
font-weight: bold;
text-align: right;
display: block;
padding-right: 2em;
}

View File

@ -3,6 +3,7 @@ import ArticleRow from './ArticleRow';
import sanity from '../sanity'; import sanity from '../sanity';
import '../css/article.css'; import '../css/article.css';
import BlueButton from './BlueButton'; import BlueButton from './BlueButton';
import Centered from './Centered';
export default function ArticleList() { export default function ArticleList() {
let [articles, setArticles] = React.useState<SGA.ArticleDocument[]>([]); let [articles, setArticles] = React.useState<SGA.ArticleDocument[]>([]);
@ -64,7 +65,7 @@ export default function ArticleList() {
return ( return (
<div> <div>
{articleList} {articleList}
<div className='text-center'>{bottomComponent}</div> <Centered>{bottomComponent}</Centered>
</div> </div>
); );
} }

View File

@ -1,16 +1,18 @@
import React from 'react'; import React, { DetailedHTMLProps } from 'react';
import imageUrl from '../lib/imageUrl'; import imageUrl from '../lib/imageUrl';
import { Link } from 'react-router-dom';
import '../css/article.css'; import '../css/article.css';
import ClickableLink from './ClickableLink';
export default function ArticleRow({ export default function ArticleRow({
article, article,
}: { }: {
article: SGA.ArticleDocument; article: SGA.ArticleDocument;
}) { }) {
let thumbUrl: string | null = null; let thumbnail: React.ReactElement | null = null;
if (article.thumbnail) { if (article.thumbnail) {
thumbUrl = imageUrl(article.thumbnail).url(); thumbnail = (
<img src={imageUrl(article.thumbnail).url()} alt={article.title} />
);
} }
const slug = (s: string) => { const slug = (s: string) => {
@ -19,22 +21,22 @@ export default function ArticleRow({
return ( return (
<div className='d-flex my-4'> <div className='d-flex my-4'>
<div className='article-row-thumbnail'> <div className='article-row-thumbnail'>{thumbnail}</div>
{thumbUrl ? <img src={thumbUrl} alt={article.title} /> : null}
</div>
<div className='article-row-content'> <div className='article-row-content'>
<Link <ClickableLink
to={'/news/' + article._id + '/' + slug(article.title)} href={'/news/' + article._id + '/' + slug(article.title)}
className='clickable-link'
target='_blank' target='_blank'
> >
<h3 style={{ margin: '0px' }}>{article.title}</h3> <h3 style={{ margin: '0px' }}>{article.title}</h3>
</Link> </ClickableLink>
<i className='text-sm'>{article.publish_date}</i> <i className='text-sm'>{article.publish_date}</i>
<br /> <br />
<i>{article.author || 'No author'}</i>
<i>{article.author ?? 'No author'}</i>
<br /> <br />
<p style={{ marginBottom: '0px' }}>{article.summary}</p>
<p>{article.summary}</p>
</div> </div>
</div> </div>
); );

View File

@ -0,0 +1,25 @@
import { Link } from 'react-router-dom';
export default function ClickableLink({
href,
children,
target,
}: {
href: string;
children: React.ReactNode;
target?: string;
}) {
if (href.startsWith('http')) {
return (
<a href={href} className='clickable-link' target={target}>
{children}
</a>
);
} else {
return (
<Link to={href} className='clickable-link'>
{children}
</Link>
);
}
}

View File

@ -0,0 +1,9 @@
export default function FlexColumn({
children,
}: {
children: React.ReactNode;
}) {
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>{children}</div>
);
}

View File

@ -17,13 +17,11 @@ export default function Footer() {
alt='Footer Banner' alt='Footer Banner'
/> />
<div className='footer-container'> <div className='footer-container'>
{footer.columns.map((col, index) => { {footer.columns.map((col, index) => (
return (
<div className='footer-col' key={index}> <div className='footer-col' key={index}>
<BlockContent blocks={col.content} /> <BlockContent blocks={col.content} />
</div> </div>
); ))}
})}
</div> </div>
</section> </section>
); );

View File

@ -1,12 +0,0 @@
export default function GetInvolvedRow({ way }: { way: SGA.GetInvolvedWay }) {
return (
<div className='d-flex text-left my-4'>
<div className='get-involved-title'>
<h3>{way.title}</h3>
</div>
<div className='get-involved-description'>
<p className='get-involved-body'>{way.text}</p>
</div>
</div>
);
}

View File

@ -1,14 +1,12 @@
import '../css/hero.css'; import '../css/hero.css';
type HeroProps = {
imageURL?: string;
heading?: string;
};
export default function Hero({ export default function Hero({
imageURL = '/images/hero.jpg', imageURL = '/images/hero.jpg',
heading = 'TJHSST SGA', heading = 'TJHSST SGA',
}: HeroProps) { }: {
imageURL?: string;
heading?: string;
}) {
return ( return (
<div className='hero'> <div className='hero'>
<span className='hero-heading'>{heading}</span> <span className='hero-heading'>{heading}</span>

View File

@ -1,15 +0,0 @@
import { Link } from 'react-router-dom';
export default function LocalLinkClickable({
to,
children,
}: {
to: string;
children: React.ReactNode;
}) {
return (
<Link to={to} className='clickable-link'>
{children}
</Link>
);
}

View File

@ -1,21 +1,20 @@
import imageUrl from '../lib/imageUrl'; import imageUrl from '../lib/imageUrl';
import '../css/article.css'; import '../css/article.css';
import RowItemHeader from './RowItemHeader';
export default function MemberRow({ member }: { member: SGA.MemberDocument }) { export default function MemberRow({ member }: { member: SGA.MemberDocument }) {
let thumbUrl: string | null = null; let thumbnail: React.ReactElement | null = null;
if (member.profile_photo) { if (member.profile_photo) {
thumbUrl = imageUrl(member.profile_photo).url(); thumbnail = (
<img src={imageUrl(member.profile_photo).url()} alt={member.name} />
);
} }
return ( return (
<div className='d-flex my-4'> <div className='d-flex my-4'>
<div className='article-row-thumbnail'> <div className='article-row-thumbnail'>{thumbnail}</div>
{thumbUrl ? (
<img className='mb-4' src={thumbUrl} alt={member.name} />
) : null}
</div>
<div className='article-row-content'> <div className='article-row-content'>
<h3>{member.name}</h3> <RowItemHeader>{member.name}</RowItemHeader>
<i> <i>
{member.role}, {member.year} {member.role}, {member.year}
</i> </i>

View File

@ -0,0 +1,20 @@
import StrongParagraph from './StrongParagraph';
export default function ParagraphWithHeader({
title,
body,
}: {
title: string;
body: string;
}) {
return (
<div style={{ display: 'flex', textAlign: 'left' }}>
<div className='flex-1 p-2'>
<span className='paragraph-with-header-header'>{title}</span>
</div>
<div className='flex-2 p-2'>
<StrongParagraph>{body}</StrongParagraph>
</div>
</div>
);
}

View File

@ -2,22 +2,22 @@ import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import useQuery from '../hooks/useQuery'; import useQuery from '../hooks/useQuery';
import ArticleRow from './ArticleRow'; import ArticleRow from './ArticleRow';
import PrimaryHeader from './PrimaryHeader';
export default function RecentNews() { export default function RecentNews() {
let news = useQuery<SGA.ArticleDocument[]>( const articles =
useQuery<SGA.ArticleDocument[]>(
`*[_type == 'article'] | order (publish_date desc, title) [0...3]` `*[_type == 'article'] | order (publish_date desc, title) [0...3]`
); ) ?? [];
if (!news) { const articleList = articles.map((article) => (
return null; <ArticleRow article={article} key={article._id} />
} ));
return ( return (
<div> <div>
<h3 className='display-3'>Recent News</h3> <PrimaryHeader>Recent News</PrimaryHeader>
{news.map((article) => { {articleList}
return <ArticleRow article={article} key={article._id} />;
})}
<Link to='/news'>All News</Link> <Link to='/news'>All News</Link>
</div> </div>
); );

View File

@ -0,0 +1,7 @@
export default function RowItemHeader({
children,
}: {
children: React.ReactNode;
}) {
return <h3 className='header'>{children}</h3>;
}

View File

@ -1,15 +1,28 @@
import { Link } from 'react-router-dom';
import '../css/segment.css'; import '../css/segment.css';
import BlueButtonLink from './BlueButtonLink';
export default function InfoColumn({ title, content, imageURL, infoURL }) { function SegmentHeader({ children }: { children: React.ReactNode }) {
return (
<h3
style={{
margin: '1em 0px',
fontSize: '1.75rem',
fontWeight: 500,
}}
>
{children}
</h3>
);
}
export default function Segment({ title, content, imageURL, infoURL }) {
return ( return (
<div className='segment'> <div className='segment'>
<h3 className='segment-title'>{title}</h3> <SegmentHeader>{title}</SegmentHeader>
<img src={imageURL} alt={title} /> <img src={imageURL} alt={title} />
<p className='segment-body'>{content}</p> <p className='strong-paragraph'>{content}</p>
<Link to={infoURL} className='blue-button'>
MORE INFO <BlueButtonLink href={infoURL}>MORE INFO</BlueButtonLink>
</Link>
</div> </div>
); );
} }

View File

@ -0,0 +1,7 @@
export default function StrongParagraph({
children,
}: {
children: React.ReactNode;
}) {
return <p className='strong-paragraph'>{children}</p>;
}

View File

@ -1,17 +0,0 @@
.get-involved-body {
color: #444;
font-size: 22px;
line-height: 33px;
font-weight: 300;
text-align: left;
}
.get-involved-title {
flex: 1;
text-align: right;
padding-right: 2em;
}
.get-involved-description {
flex: 3;
}

View File

@ -10,20 +10,6 @@
line-height: 44px; line-height: 44px;
} }
.mission-header {
font-size: 2rem;
font-weight: bold;
text-align: right;
display: block;
padding-right: 2em;
}
.mission-para {
font-size: 22px;
line-height: 33px;
font-weight: 300;
}
.mission-quote { .mission-quote {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import FlexColumn from '../components/FlexColumn';
import Hero from '../components/Hero'; import Hero from '../components/Hero';
import InitiativeRow from '../components/InitiativeRow'; import InitiativeRow from '../components/InitiativeRow';
import useQuery from '../hooks/useQuery'; import useQuery from '../hooks/useQuery';
@ -11,11 +12,11 @@ export default function Initiatives() {
<> <>
<Hero heading='Initiatives' /> <Hero heading='Initiatives' />
<main> <main>
<div style={{ display: 'flex', flexDirection: 'column' }}> <FlexColumn>
{initiatives.map((initiative) => ( {initiatives.map((initiative) => (
<InitiativeRow initiative={initiative} /> <InitiativeRow initiative={initiative} />
))} ))}
</div> </FlexColumn>
</main> </main>
</> </>
); );

View File

@ -1,10 +1,10 @@
import { SanityDocument } from '@sanity/client'; import { SanityDocument } from '@sanity/client';
import React from 'react'; import React from 'react';
import BlueButtonLink from '../components/BlueButtonLink'; import BlueButtonLink from '../components/BlueButtonLink';
import GetInvolvedRow from '../components/GetInvolvedRow';
import Hero from '../components/Hero'; import Hero from '../components/Hero';
import ParagraphHeader from '../components/ParagraphHeader'; import ParagraphHeader from '../components/ParagraphHeader';
import '../css/get-involved.css'; import ParagraphWithHeader from '../components/ParagraphWithHeader';
import StrongParagraph from '../components/StrongParagraph';
import sanity from '../sanity'; import sanity from '../sanity';
export default function GetInvolved() { export default function GetInvolved() {
@ -23,25 +23,34 @@ export default function GetInvolved() {
<Hero heading='Get Involved' /> <Hero heading='Get Involved' />
<main className='text-center'> <main className='text-center'>
<ParagraphHeader>SGA Calendar</ParagraphHeader> <ParagraphHeader>SGA Calendar</ParagraphHeader>
<iframe <iframe
src='https://calendar.google.com/calendar/u/0/embed?src=mbftfg4hu7i8ueqrgcb5o7hc6k@group.calendar.google.com&ctz=America/New_York' src='https://calendar.google.com/calendar/u/0/embed?src=mbftfg4hu7i8ueqrgcb5o7hc6k@group.calendar.google.com&ctz=America/New_York'
title='SGA Calendar' title='SGA Calendar'
width='800' width='800'
height='600' height='600'
/> />
<p className='get-involved-body my-4'>
<br />
<StrongParagraph>
Interested in getting involved with SGA? You can run for office, work Interested in getting involved with SGA? You can run for office, work
on a project, or apply to a committee. If you just want to share an on a project, or apply to a committee. If you just want to share an
idea or concern or get to know your representatives, reach out to us idea or concern or get to know your representatives, reach out to us
at <b>sga@tjhsst.edu</b>! at <b>sga@tjhsst.edu</b>!
</p> </StrongParagraph>
<ParagraphHeader> <ParagraphHeader>
Here are some ways to connect with SGA: Here are some ways to connect with SGA:
</ParagraphHeader> </ParagraphHeader>
{getInvolved {getInvolved
? getInvolved.ways.map((way) => ( ? getInvolved.ways.map((way) => (
<GetInvolvedRow way={way} key={way._id} /> <ParagraphWithHeader
title={way.title}
body={way.text}
key={way._id}
/>
)) ))
: null} : null}

View File

@ -4,6 +4,7 @@ import useMission from '../hooks/useMission';
import '../css/mission.css'; import '../css/mission.css';
import BlueButtonLink from '../components/BlueButtonLink'; import BlueButtonLink from '../components/BlueButtonLink';
import Centered from '../components/Centered'; import Centered from '../components/Centered';
import ParagraphWithHeader from '../components/ParagraphWithHeader';
function MissionQuote({ text, author }) { function MissionQuote({ text, author }) {
return ( return (
@ -16,19 +17,6 @@ function MissionQuote({ text, author }) {
); );
} }
function MissionParagraph({ title, body }: { title: string; body: string }) {
return (
<div className='d-flex'>
<div className='flex-1 p-2'>
<span className='mission-header'>{title}</span>
</div>
<div className='flex-2 p-2'>
<p className='mission-para'>{body}</p>
</div>
</div>
);
}
const previousLeadershipLink = const previousLeadershipLink =
'https://docs.google.com/spreadsheets/d/1a3RYdqrDi1IPG9BKWQ2xhoX3YCPQKUl_FsRLvIVEMPg/edit?usp=drive_open&ouid=0'; 'https://docs.google.com/spreadsheets/d/1a3RYdqrDi1IPG9BKWQ2xhoX3YCPQKUl_FsRLvIVEMPg/edit?usp=drive_open&ouid=0';
@ -45,8 +33,8 @@ export default function Mission() {
text={mission.quote_text} text={mission.quote_text}
/> />
<MissionParagraph title='Vision' body={mission.vision} /> <ParagraphWithHeader title='Vision' body={mission.vision} />
<MissionParagraph title='Mission' body={mission.mission} /> <ParagraphWithHeader title='Mission' body={mission.mission} />
<Centered> <Centered>
<BlueButtonLink href={previousLeadershipLink}> <BlueButtonLink href={previousLeadershipLink}>

View File

@ -4,7 +4,7 @@ import Hero from '../components/Hero';
import imageUrl from '../lib/imageUrl'; import imageUrl from '../lib/imageUrl';
import '../css/article.css'; import '../css/article.css';
import useNewsArticle from '../hooks/useNewsArticle'; import useNewsArticle from '../hooks/useNewsArticle';
import LocalLinkClickable from '../components/LocalLinkClickable'; import ClickableLink from '../components/ClickableLink';
import BlockContentWithExternalLinks from '../components/BlockContentWithExternalLinks'; import BlockContentWithExternalLinks from '../components/BlockContentWithExternalLinks';
import PrimaryHeader from '../components/PrimaryHeader'; import PrimaryHeader from '../components/PrimaryHeader';
@ -18,7 +18,7 @@ export default function NewsArticle() {
} }
const goToAllNewsArticles = ( const goToAllNewsArticles = (
<LocalLinkClickable to='/news'>Go to all news articles</LocalLinkClickable> <ClickableLink href='/news'>Go to all news articles</ClickableLink>
); );
return ( return (
@ -33,7 +33,7 @@ export default function NewsArticle() {
Posted {article.publish_date} by {article.author || 'No author'} Posted {article.publish_date} by {article.author || 'No author'}
</i> </i>
<br /> <br />
<div id='article-content' className='article-paragraphs'> <div className='article-paragraphs'>
<BlockContentWithExternalLinks blocks={article.content} /> <BlockContentWithExternalLinks blocks={article.content} />
</div> </div>
<br /> <br />

View File

@ -26,7 +26,6 @@ export default function Officers() {
const officerList = officersSorted.map((officer) => ( const officerList = officersSorted.map((officer) => (
<MemberRow member={officer} /> <MemberRow member={officer} />
)); ));
console.log(officersSorted);
return ( return (
<> <>