Prettified code

This commit is contained in:
Michael Fatemi 2020-11-25 18:05:30 -05:00
parent a9bdd07089
commit 4435307996
25 changed files with 325 additions and 277 deletions

File diff suppressed because one or more lines are too long

13
.prettierrc Normal file
View File

@ -0,0 +1,13 @@
{
"singleQuote": true,
"jsxSingleQuote": true,
"printWidth": 80,
"useTabs": true,
"semi": true,
"quoteProps": "consistent",
"trailingComma": "es5",
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"endOfLine": "lf"
}

View File

@ -1,4 +1,4 @@
import React from 'react' import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom'; import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Layout from './components/Layout'; import Layout from './components/Layout';
@ -9,19 +9,19 @@ import newsArticle from './pages/newsArticle';
import notFound from './pages/404'; import notFound from './pages/404';
function App() { function App() {
return ( return (
<BrowserRouter> <BrowserRouter>
<Layout> <Layout>
<Switch> <Switch>
<Route path="/initiatives" exact component={initiatives} /> <Route path='/initiatives' exact component={initiatives} />
<Route path="/news/:articleId" component={newsArticle} /> <Route path='/news/:articleId' component={newsArticle} />
<Route path="/news" exact component={news} /> <Route path='/news' exact component={news} />
<Route path="/:path" component={notFound} /> <Route path='/:path' component={notFound} />
<Route path="/" exact component={index} /> <Route path='/' exact component={index} />
</Switch> </Switch>
</Layout> </Layout>
</BrowserRouter> </BrowserRouter>
); );
} }
export default App; export default App;

View File

@ -1,9 +1,11 @@
import React from 'react' import React from 'react';
import useQuery from '../hooks/useInitiatives' import useQuery from '../hooks/useInitiatives';
import ArticleRow from './ArticleRow'; import ArticleRow from './ArticleRow';
export default function ArticleList() { export default function ArticleList() {
let articles = useQuery<SGA.ArticleDocument[]>('*[_type == "article"] | order(publish_date desc) [0...3]'); let articles = useQuery<SGA.ArticleDocument[]>(
'*[_type == "article"] | order(publish_date desc) [0...3]'
);
if (!articles) { if (!articles) {
return null; return null;
@ -12,12 +14,10 @@ export default function ArticleList() {
console.log(articles); console.log(articles);
return ( return (
<div style={{display: "flex", flexDirection: "column"}}> <div style={{ display: 'flex', flexDirection: 'column' }}>
{ {articles.map((article) => {
articles.map(article => { return <ArticleRow key={article._id} article={article} />;
return <ArticleRow key={article._id} article={article} /> })}
})
}
</div> </div>
) );
} }

View File

@ -1,9 +1,13 @@
import React from 'react' import React from 'react';
import imageUrl from '../imageUrl' import imageUrl from '../imageUrl';
import BlockContent from '@sanity/block-content-to-react' import BlockContent from '@sanity/block-content-to-react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
export default function ArticleRow({ article }: {article: SGA.ArticleDocument}) { export default function ArticleRow({
article,
}: {
article: SGA.ArticleDocument;
}) {
let thumbUrl: string | null = null; let thumbUrl: string | null = null;
if (article.thumbnail) { if (article.thumbnail) {
thumbUrl = imageUrl(article.thumbnail).url(); thumbUrl = imageUrl(article.thumbnail).url();
@ -11,26 +15,23 @@ export default function ArticleRow({ article }: {article: SGA.ArticleDocument})
const slug = (s: string) => { const slug = (s: string) => {
return s.toLowerCase().replaceAll(' ', '-'); return s.toLowerCase().replaceAll(' ', '-');
} };
return ( return (
<div style={{display: "flex"}}> <div style={{ display: 'flex' }}>
<div style={{flex: 1, padding: "10px"}}> <div style={{ flex: 1, padding: '10px' }}>
{ thumbUrl ? {thumbUrl ? (
<img className="mb-4" src={thumbUrl} alt={article.title} /> <img className='mb-4' src={thumbUrl} alt={article.title} />
: null ) : null}
}
</div> </div>
<div style={{flex: 3, padding: "10px"}}> <div style={{ flex: 3, padding: '10px' }}>
<Link to={'/news/' + article._id + '/' + slug(article.title)}> <Link to={'/news/' + article._id + '/' + slug(article.title)}>
<h3 className="font-bold text-3xl mb-6"> <h3 className='font-bold text-3xl mb-6'>{article.title}</h3>
{ article.title }
</h3>
</Link> </Link>
<i className="text-sm">{ article.publish_date }</i> <i className='text-sm'>{article.publish_date}</i>
<br/> <br />
<BlockContent blocks={article.content} /> <BlockContent blocks={article.content} />
</div> </div>
</div> </div>
); );
} }

View File

@ -1,5 +1,5 @@
import React from 'react' import React from 'react';
import '../css/footer.css' import '../css/footer.css';
import BlockContent from '@sanity/block-content-to-react'; import BlockContent from '@sanity/block-content-to-react';
import useFooter from '../hooks/useFooter'; import useFooter from '../hooks/useFooter';
@ -9,14 +9,22 @@ export default function Footer() {
return null; return null;
} }
return <section className="footer-wrapper"> return (
<img className="footer-banner" src="/images/footer-banner.png" alt="Footer Banner" /> <section className='footer-wrapper'>
<div className="footer-container"> <img
{ footer.columns.map(col => { className='footer-banner'
return <div className="footer-col" key={col._id}> src='/images/footer-banner.png'
<BlockContent blocks={col.content}></BlockContent> alt='Footer Banner'
</div> />
}) } <div className='footer-container'>
</div> {footer.columns.map((col) => {
</section> return (
} <div className='footer-col' key={col._id}>
<BlockContent blocks={col.content}></BlockContent>
</div>
);
})}
</div>
</section>
);
}

View File

@ -1,28 +1,41 @@
import React from 'react' import React from 'react';
type HeroProps = { type HeroProps = {
imageURL?: string, imageURL?: string;
heading?: string heading?: string;
} };
export default function Hero({ imageURL = "/images/hero.png", heading = "TJHSST SGA"}: HeroProps) { export default function Hero({
return <div className="hero relative"> imageURL = '/images/hero.png',
<span style={{ heading = 'TJHSST SGA',
display: "flex", }: HeroProps) {
fontSize: "4rem", return (
fontWeight: "bold", <div className='hero relative'>
textShadow: "1px 1px rgba(48, 48, 48, 0.5)", <span
color: "white", style={{
position: "absolute", display: 'flex',
height: "100%", fontSize: '4rem',
width: "100%", fontWeight: 'bold',
justifyContent: "center", textShadow: '1px 1px rgba(48, 48, 48, 0.5)',
alignItems: "center", color: 'white',
}}>{ heading }</span> position: 'absolute',
<img src={imageURL} alt="Background" style={{ height: '100%',
width: "100vw", width: '100%',
height: "60vh", justifyContent: 'center',
objectFit: "cover" alignItems: 'center',
}}></img> }}
</div> >
} {heading}
</span>
<img
src={imageURL}
alt='Background'
style={{
width: '100vw',
height: '60vh',
objectFit: 'cover',
}}
/>
</div>
);
}

View File

@ -1,4 +1,4 @@
import React from 'react' import React from 'react';
import BlockContent from '@sanity/block-content-to-react'; import BlockContent from '@sanity/block-content-to-react';
import imageUrl from '../imageUrl'; import imageUrl from '../imageUrl';
@ -8,14 +8,13 @@ export default function InitiativeColumn({ name, thumbnail, content }) {
thumbUrl = imageUrl(thumbnail).url(); thumbUrl = imageUrl(thumbnail).url();
} }
return <div className="lg:w-1/3 w-full lg:px-4 mb-4"> return (
<h3 className="text-center font-bold text-3xl text-secondary mb-6"> <div className='lg:w-1/3 w-full lg:px-4 mb-4'>
{ name } <h3 className='text-center font-bold text-3xl text-secondary mb-6'>
</h3> {name}
{ thumbUrl ? </h3>
<img className="mb-4" src={thumbUrl} alt={name} /> {thumbUrl ? <img className='mb-4' src={thumbUrl} alt={name} /> : null}
: null <BlockContent blocks={content} style={{ fontSize: '1.5rem' }} />
} </div>
<BlockContent blocks={content} style={{fontSize: "1.5rem"}} /> );
</div>
} }

View File

@ -1,17 +1,21 @@
import React from 'react' import React from 'react';
import useQuery from '../hooks/useInitiatives'; import useQuery from '../hooks/useInitiatives';
import InitiativeColumn from './InitiativeColumn'; import InitiativeColumn from './InitiativeColumn';
export default function InitiativeList() { export default function InitiativeList() {
let initiatives = useQuery<SGA.InitiativeDocument[]>('*[_type == "initiative"]'); let initiatives = useQuery<SGA.InitiativeDocument[]>(
'*[_type == "initiative"]'
);
if (!initiatives) { if (!initiatives) {
return null; return null;
} }
return <section className="container mx-auto px-8 my-8 flex flex-wrap"> return (
{ initiatives.map(initiative => { <section className='container mx-auto px-8 my-8 flex flex-wrap'>
return <InitiativeColumn key={initiative._id} {...initiative} /> {initiatives.map((initiative) => {
}) } return <InitiativeColumn key={initiative._id} {...initiative} />;
</section> })}
} </section>
);
}

View File

@ -1,27 +1,28 @@
import React from 'react' import React from 'react';
import imageUrl from '../imageUrl'; import imageUrl from '../imageUrl';
import BlockContent from '@sanity/block-content-to-react'; import BlockContent from '@sanity/block-content-to-react';
export default function InitiativeRow({ initiative }: { initiative: SGA.InitiativeDocument }) { export default function InitiativeRow({
initiative,
}: {
initiative: SGA.InitiativeDocument;
}) {
let thumbUrl: string | null = null; let thumbUrl: string | null = null;
if (initiative.thumbnail) { if (initiative.thumbnail) {
thumbUrl = imageUrl(initiative.thumbnail).url(); thumbUrl = imageUrl(initiative.thumbnail).url();
} }
return ( return (
<div style={{display: "flex"}}> <div style={{ display: 'flex' }}>
<div style={{flex: 1, padding: "10px"}}> <div style={{ flex: 1, padding: '10px' }}>
{ thumbUrl ? {thumbUrl ? (
<img className="mb-4" src={thumbUrl} alt={initiative.name} /> <img className='mb-4' src={thumbUrl} alt={initiative.name} />
: null ) : null}
}
</div> </div>
<div style={{flex: 3, padding: "10px"}}> <div style={{ flex: 3, padding: '10px' }}>
<h3> <h3>{initiative.name}</h3>
{ initiative.name }
</h3>
<BlockContent blocks={initiative.content} /> <BlockContent blocks={initiative.content} />
</div> </div>
</div> </div>
); );
} }

View File

@ -5,25 +5,22 @@
* See: https://www.gatsbyjs.com/docs/use-static-query/ * See: https://www.gatsbyjs.com/docs/use-static-query/
*/ */
import React from "react" import React from 'react';
import Navbar from './Navbar'; import Navbar from './Navbar';
import Footer from './Footer'; import Footer from './Footer';
export default function Layout({ children }: { children: React.ReactNode }) { export default function Layout({ children }: { children: React.ReactNode }) {
return ( return (
<> <>
<div className="bg-light text-dark"> <div className='bg-light text-dark'>
<Navbar></Navbar> <Navbar></Navbar>
<main id="page"> <main id='page'>{children}</main>
{ children } <hr />
</main>
<hr />
<Footer /> <Footer />
</div> </div>
</> </>
) );
} }

View File

@ -1,4 +1,4 @@
import React from 'react' import React from 'react';
import useMission from '../hooks/useMission'; import useMission from '../hooks/useMission';
export default function Mission() { export default function Mission() {
@ -7,23 +7,19 @@ export default function Mission() {
return null; return null;
} }
return <section className="text-center bg-secondary text-light"> return (
<div className="container mx-auto px-8 py-8"> <section className='text-center bg-secondary text-light'>
<h3 className="text-center font-bold text-3xl text-secondary mb-6"> <div className='container mx-auto px-8 py-8'>
Mission <h3 className='text-center font-bold text-3xl text-secondary mb-6'>
</h3> Mission
<p> </h3>
{ mission.mission } <p>{mission.mission}</p>
</p> <h3 className='text-center font-bold text-3xl text-secondary mb-6'>
<h3 className="text-center font-bold text-3xl text-secondary mb-6"> Vision
Vision </h3>
</h3> <p>{mission.vision}</p>
<p> <blockquote>{mission.quote_text}</blockquote>
{ mission.vision } </div>
</p> </section>
<blockquote> );
{ mission.quote_text } }
</blockquote>
</div>
</section>
}

View File

@ -1,35 +1,43 @@
import React from 'react' import React from 'react';
import "../css/navbar.css" import '../css/navbar.css';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
let pages = [ let pages = [
{ {
url: "/", url: '/',
title: "Home" title: 'Home',
}, },
{ {
url: "/news", url: '/news',
title: "News" title: 'News',
}, },
{ {
url: "/initiatives", url: '/initiatives',
title: "Initiatives" title: 'Initiatives',
} },
] ];
export default function Navbar() { export default function Navbar() {
return <div className="nav"> return (
<Link to="/"> <div className='nav'>
<img src="/images/banner.png" alt="TJ SGA" style={{ <Link to='/'>
height: "2rem", <img
alignSelf: "center", src='/images/banner.png'
margin: "1rem" alt='TJ SGA'
}}/> style={{
</Link> height: '2rem',
{ pages.map(page => { alignSelf: 'center',
return <Link key={page.url} className="nav-link" to={page.url}> margin: '1rem',
{ page.title } }}
/>
</Link> </Link>
}) } {pages.map((page) => {
</div> return (
} <Link key={page.url} className='nav-link' to={page.url}>
{page.title}
</Link>
);
})}
</div>
);
}

View File

@ -1,20 +1,22 @@
import React from 'react' import React from 'react';
import sanity from '../sanity'; import sanity from '../sanity';
import { SanityDocument } from '@sanity/client/sanityClient'; import { SanityDocument } from '@sanity/client/sanityClient';
interface FooterDocument { interface FooterDocument {
columns: { columns: {
_id: string _id: string;
content: any[] content: any[];
}[] }[];
} }
export default function useFooter() { export default function useFooter() {
let [footer, setFooter] = React.useState<SanityDocument<FooterDocument> | undefined>(); let [footer, setFooter] = React.useState<
SanityDocument<FooterDocument> | undefined
>();
React.useEffect(() => { React.useEffect(() => {
sanity.getDocument<FooterDocument>('footer').then(setFooter) sanity.getDocument<FooterDocument>('footer').then(setFooter);
}, []) }, []);
return footer; return footer;
} }

View File

@ -1,12 +1,12 @@
import React from 'react' import React from 'react';
import sanity from '../sanity'; import sanity from '../sanity';
export default function useQuery<T>(query: string, params?: any) { export default function useQuery<T>(query: string, params?: any) {
let [result, setResult] = React.useState<T>(); let [result, setResult] = React.useState<T>();
React.useEffect(() => { React.useEffect(() => {
sanity.fetch(query, params).then(setResult); sanity.fetch(query, params).then(setResult);
}, []) }, [query, params]);
return result; return result;
} }

View File

@ -1,22 +1,24 @@
import React from 'react' import React from 'react';
import sanity from '../sanity'; import sanity from '../sanity';
import { SanityDocument } from '@sanity/client/sanityClient'; import { SanityDocument } from '@sanity/client/sanityClient';
interface MissionDocument { interface MissionDocument {
mission: string mission: string;
vision: string vision: string;
quote_text: string quote_text: string;
quote_author: string quote_author: string;
} }
function useMission() { function useMission() {
let [mission, setMission] = React.useState<SanityDocument<MissionDocument> | undefined>(); let [mission, setMission] = React.useState<
SanityDocument<MissionDocument> | undefined
>();
React.useEffect(() => { React.useEffect(() => {
sanity.getDocument<MissionDocument>('mission').then(setMission) sanity.getDocument<MissionDocument>('mission').then(setMission);
}, []) }, []);
return mission; return mission;
} }
export default useMission; export default useMission;

20
src/index.d.ts vendored
View File

@ -1,16 +1,16 @@
declare namespace SGA { declare namespace SGA {
interface InitiativeDocument { interface InitiativeDocument {
name: string, name: string;
thumbnail: {}, thumbnail: {};
content: any[], content: any[];
_id: string _id: string;
} }
interface ArticleDocument { interface ArticleDocument {
title: string, title: string;
thumbnail: {}, thumbnail: {};
content: any[], content: any[];
publish_date: string, publish_date: string;
_id: string _id: string;
} }
} }

View File

@ -5,10 +5,10 @@ import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
<App /> <App />
</React.StrictMode>, </React.StrictMode>,
document.getElementById('root') document.getElementById('root')
); );
// If you want to start measuring performance in your app, pass a function // If you want to start measuring performance in your app, pass a function

View File

@ -1,10 +1,10 @@
import React from "react" import React from 'react';
const NotFoundPage = () => ( const NotFoundPage = () => (
<div style={{textAlign: "center"}}> <div style={{ textAlign: 'center' }}>
<h1>404: Not Found</h1> <h1>404: Not Found</h1>
<p>This page wasn't found...</p> <p>This page wasn't found...</p>
</div> </div>
) );
export default NotFoundPage export default NotFoundPage;

View File

@ -1,25 +1,25 @@
import React from "react" import React from 'react';
import Hero from "../components/Hero" import Hero from '../components/Hero';
import InitiativeList from "../components/InitiativeList" import InitiativeList from '../components/InitiativeList';
import Mission from "../components/Mission" import Mission from '../components/Mission';
const IndexPage = () => { const IndexPage = () => {
return <> return (
{/* Hero image */} <>
<Hero></Hero> {/* Hero image */}
<Hero></Hero>
{/* Initiatives section */} {/* Initiatives section */}
<InitiativeList /> <InitiativeList />
{/* Mission */} {/* Mission */}
<Mission /> <Mission />
{/* News articles section */} {/* News articles section */}
<section className="container mx-auto px-8 my-8"> <section className='container mx-auto px-8 my-8'></section>
</>
</section> );
</> };
}
export default IndexPage export default IndexPage;

View File

@ -1,25 +1,25 @@
import React from 'react' import React from 'react';
import Hero from '../components/Hero'; import Hero from '../components/Hero';
import InitiativeRow from '../components/InitiativeRow'; import InitiativeRow from '../components/InitiativeRow';
import useQuery from '../hooks/useInitiatives' import useQuery from '../hooks/useInitiatives';
export default function Initiatives() { export default function Initiatives() {
let initiatives = useQuery<SGA.InitiativeDocument[]>('*[_type == "initiative"]'); let initiatives = useQuery<SGA.InitiativeDocument[]>(
'*[_type == "initiative"]'
);
if (!initiatives) { if (!initiatives) {
return null; return null;
} }
return ( return (
<> <>
<Hero heading="Initiatives"></Hero> <Hero heading='Initiatives'></Hero>
<div style={{display: "flex", flexDirection: "column"}}> <div style={{ display: 'flex', flexDirection: 'column' }}>
{ {initiatives.map((initiative) => {
initiatives.map(initiative => { return <InitiativeRow initiative={initiative} />;
return <InitiativeRow initiative={initiative} /> })}
})
}
</div> </div>
</> </>
) );
} }

View File

@ -1,10 +1,12 @@
import React from 'react' import React from 'react';
import ArticleList from '../components/ArticleList' import ArticleList from '../components/ArticleList';
import Hero from '../components/Hero' import Hero from '../components/Hero';
export default function News() { export default function News() {
return (<> return (
<Hero heading="News"></Hero> <>
<ArticleList></ArticleList> <Hero heading='News'></Hero>
</>) <ArticleList></ArticleList>
} </>
);
}

View File

@ -1,17 +1,19 @@
import React from 'react' import React from 'react';
import { Link, useParams } from 'react-router-dom' import { Link, useParams } from 'react-router-dom';
import Hero from '../components/Hero'; import Hero from '../components/Hero';
import useQuery from '../hooks/useInitiatives'; import useQuery from '../hooks/useInitiatives';
import imageUrl from '../imageUrl'; import imageUrl from '../imageUrl';
import BlockContent from '@sanity/block-content-to-react'; import BlockContent from '@sanity/block-content-to-react';
export default function NewsArticle() { export default function NewsArticle() {
let { articleId } = useParams<{articleId: string}>(); let { articleId } = useParams<{ articleId: string }>();
let article = useQuery<SGA.ArticleDocument>('*[_id == $articleId] [0]', {articleId}); let article = useQuery<SGA.ArticleDocument>('*[_id == $articleId] [0]', {
articleId,
});
if (!article) { if (!article) {
return null; return null;
} }
let thumbUrl: string | undefined = undefined; let thumbUrl: string | undefined = undefined;
if (article.thumbnail) { if (article.thumbnail) {
thumbUrl = imageUrl(article.thumbnail).url() || undefined; thumbUrl = imageUrl(article.thumbnail).url() || undefined;
@ -22,14 +24,14 @@ export default function NewsArticle() {
return ( return (
<> <>
<Hero heading={article.title} imageURL={thumbUrl} /> <Hero heading={article.title} imageURL={thumbUrl} />
<div style={{maxWidth: "640px"}} className="mx-auto my-8"> <div style={{ maxWidth: '640px' }} className='mx-auto my-8'>
<i className="text-sm">Published: {article.publish_date}</i> <i className='text-sm'>Published: {article.publish_date}</i>
<br/> <br />
<Link to="/news">Go to all news articles</Link> <Link to='/news'>Go to all news articles</Link>
<br/> <br />
<BlockContent blocks={article.content}></BlockContent> <BlockContent blocks={article.content}></BlockContent>
<br/> <br />
</div> </div>
</> </>
) );
} }

View File

@ -1,9 +1,9 @@
import sanityClient from '@sanity/client' import sanityClient from '@sanity/client';
const sanity = sanityClient({ const sanity = sanityClient({
projectId: "yi263kzm", projectId: 'yi263kzm',
dataset: "production", dataset: 'production',
useCdn: true useCdn: true,
}); });
export default sanity; export default sanity;

View File

@ -18,7 +18,7 @@
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true, "isolatedModules": true,
"noEmit": true, "noEmit": true,
"jsx": "react", "jsx": "react-jsx",
"noImplicitAny": false "noImplicitAny": false
}, },
"include": [ "include": [