diff --git a/pages/hack-school/_meta.json b/pages/hack-school/_meta.json index e07362a..f800991 100644 --- a/pages/hack-school/_meta.json +++ b/pages/hack-school/_meta.json @@ -6,6 +6,7 @@ "css": "Week 1: CSS", "js": "Week 2: JavaScript", "react": "Week 3: React", + "express": "Week 4: Building APIs with Express", "mongodb": "Week 5: Databases & MongoDB", "deployment": "Week 6: Deployment" -} +} \ No newline at end of file diff --git a/pages/hack-school/express.mdx b/pages/hack-school/express.mdx new file mode 100644 index 0000000..d3462da --- /dev/null +++ b/pages/hack-school/express.mdx @@ -0,0 +1,211 @@ +# Week 4: Building APIs with Express.js + +## What is Express? +[Express](https://expressjs.com) is a web application framework for Node.js that enables developers to start a local server and develop API routes. Express does +a good job of abstracting away the complexity of serving a web application. Before we explore Express, some background on the Internet and APIs is helpful! + +## Background on the Internet + +Before we explore Express.js, some background information on how servers work is necessary. + +### How the Internet works + +The internet can be thought of as a really, really long wire. Computers all over the world can interact with one another via this wire. +In prior chapters, we mentioned the idea of **clients**. Web **clients** are the users (technically, web browsers, like Chrome or Safari). +These clients request data through this long wire from web **servers**, which are simply any computers that serve data to client. + +The standard of this client/server communication is a protocol known as HTTPS (Hypertext Transfer Protocol). This is a "language" that both +clients and servers can speak. + +### HTTP Requests + +We mentioned earlier that clients can request data from servers across the internet. This is accomplished with an HTTP Request, which is just +a way of telling the server what the client would like to do. There are four common HTTP methods: + +- `GET`, for retrieving a resource from the server +- `POST`, for posting or adding a resource to the server +- `PUT`, for editing or modifying an existing resource on the server +- `DELETE`, for deleting an existing resource on the server + +Together, these four methods give any application **CRUD functionality**–Create, Read, Update, Delete. Take a look at your favorite applications, and you'll be structured +to notice that all of them support some form of CRUD. + +There are more [HTTP methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods), but the above four are the most common ones you'll see. + +### HTTP Responses +For every request, there must be a response. Servers can respond to requests through an HTTP response. These responses have status codes tied to them, to indicate +to the client whether the request was successful, and any specific information if it was unsuccessful. You've definitely seen these before! Have you ever tried to buy tickets to an event, +but encountered a `500` (internal server error), or clicked on a link to be met with a `404` (resource not found error)? + +Status codes are 3 digit numbers that are classified according to success level, client errors, server errors, etc. You can see a comprehensive list +of them [here](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)! + +### Web application architecture + +Putting our clients, servers, requests, and responses together, this is a standard web application architecture: + +![image](pages/hack-school/images/webapparch.png) + +To summarize, clients communicate with servers via HTTP requests and responses. When those requests and recieved and processed, +the server may make database queries to provide actual data for the client to use. + +## APIs +Although there exists a standard for communication (HTTP), every server interacts differently. Imagine trying to `GET` a song from Spotify's servers, and then +attemping to `GET` a movie from Netflix's servers. While both requests are attempting to retrieve a resource, the way that one might ask for each differs. This is where +**APIs** come into play. + +API stands for **A**pplication **P**rogramming **I**nterface. An API is simply a toolkit for a client to interact with. Every server is different and accomplishes different goals +through the use of this toolkit. APIs provide a framework and standard for how clients can interact with any given server. + +A good analogy for APIs is that of a waiter in a restaurant. The tables and dining area is the client, where the customers send requests for food to the kitchen (Requests), which is the backend. The kitchen is responsible for creating +the food and sending it back to the dining area (Responses). How is this communication done? Through the waiters and waitresses! APIs are similar to waiters and waitresses, since they're the middlemen responsible for requests making it to the back-end, and +responses making it back to the client. + +![image here](pages/hack-school/images/apiwaiter.png) +Source: monosolutions.com + +Generally, APIs provide **API routes**, which are specific routes on a server that HTTP requests can be sent to. This allows clients to figure out how to interact with a particular server and request +a certain set of resources. API routes have the following syntax: + +``` +http://localhost:5000/api/purchases + +``` + +where `/api/purchases` is the route, and `localhost:5000` is the server. + +The same API route can be used for different HTTP methods. For example, a GET request sent to this route might return all purchases, while a POST +request sent to this route (with a request body) would post a new purchase. + +You can see this in action with the [Spotify API](https://developer.spotify.com/documentation/web-api)! Take a look at the endpoints for various routes, possible responses based on status code, and parameters for [GET Album](https://developer.spotify.com/documentation/web-api/reference/get-an-album). + +### Further API functionality + +Routes aren't the only part of APIs. Production APIs especially can be far more complex with many moving parts. You might have heard of **rate-limiting**, or limiting the number of API requests or calls made by a certain +user within a time period. APIs may also need to deal with **authentication/authorization** (this is the case for routes involving user profiles for Spotify, since it handles user account information). In both of these cases, **middleware** is important. Like the name +suggests, middleware is a blanket term for any technology or processes that sit in the "middle" of an API. Middleware often intercepts requests and can process them in a certain way, *before* the server handles them. For example, +a certain request's headers can be validated for the necessary authorization to access a route, or the signature can be checked to ensure the same user isn't breaking the rate-limiting threshold. You can read about Express middleware [here](https://expressjs.com/en/guide/using-middleware.html). + + +## Building our own APIs with Express + +Now that we have a background on what APIs are and how we interact with them, we can discuss how Express enables developers to build their own APIs. Express abstracts away +the complexity in serving a web application, allowing developers to quickly set up and customize their application. + +### Server setup +To get started, create a directory called `server` within your application. + +Next, [initialize a Node.js application](https://docs.npmjs.com/cli/v10/commands/npm-init). +This is achieved by executing `npm init -y` in your terminal. The `-y` flag is a shortcut to allow default configurations. + +```bash copy showLineNumbers +npm init -y +``` + +Now, we need to install Express as a package. [NPM (Node Package Manager)](https://www.npmjs.com) has hundreds of packages for developing applications, which you can see here. +We just need Express for now, so you can execute + +```bash copy showLineNumbers +npm i express +``` + +which will install Express. You should notice a `package.json` file in your directory + +Then, navigate inside this directory with `cd server` and create a file called +`index.js`. You can populate it with the following three lines: + +```javascript copy showLineNumbers +const express = require('express'); +const server = express(); +server.listen(3000); +``` + +These three lines import Express, instantiates a server, and has it listening on your computer's `PORT 3000`. If you open your web browser and +go to `localhost:3000`, you can see the result of this API! + +### Creating an API route + +Now that Express is instantiated, we can add API routes. The following lines define a `GET` route: + +```javascript copy showLineNumbers +const router = express.Router(); +router.get('/purchases', async (req, res) => { + // fetch purchases from database + res.status(200).json({ purchase }); +}); +``` + +We begin by instantiating an Express router, which enables us to attach routes to our API. +Then, we define a `GET` route with arrow function syntax. This route is now live on `localhost:3000/purchases`, so sending a `GET` request +would return the `json` representation of `purchase`. + +You'll notice that we have a callback function here too; an asynchronous function with `(req, res)` as parameters. If you guessed that these are +our **request** and **response** objects, you'd be correct! This is how our `GET` route can access the request and attach a status code to the response. + +What if we want to get a specific purchase? This is where route parameters come into play. We can slightly adjust our route to take in a specific ID, and use it +to query from our database + +```javascript copy showLineNumbers +router.get('/purchases/:id', async (req, res) => { + + const purchaseId = req.params.id; + + // fetch purchases from database + res.status(200).json({ purchase }); +}); +``` + +The resulting response might look something like this (note that we sent the output as JSON above; requests are sent in the same manner): + +```json copy showLineNumbers +{ + "purchase": { + "id": 123, + "product": "ACM Hack Hoodie", + "price": 30.99, + "quantity": 2, + "timestamp": "2023-09-24T10:00:00Z" + } +} +``` + +We can do something similar with `POST` requests—we can utilize the `req` parameter to access details of our request body. + +Sample request: + +```json copy showLineNumbers +{ + "purchase": { + "name": "ACM Bucket Hat", + "description": "ACM's very first bucket hat, in 3 stunning colors", + "color": "Blue", + "price": 25.99, + "quantity": 3, + "timestamp": "2023-09-24T14:30:00Z", + } +} +``` + + +```javascript copy showLineNumbers +router.post('/purchases', async (req, res) => { + + const purchase = req.body.purchase; + + const name = purchase.name; + + const {description} = purchase; // object destructuring + + // log purchases to database + res.status(200).json({ purchase }); +}); +``` +> Don't forget that a robust API can include some middleware. [Check out how to add functionality to your Express API's middleware](https://expressjs.com/en/guide/using-middleware.html). +## Testing our API with Postman + +It's always important to test APIs, just as you would test any software you build. Check out our section on testing with Postman! + + + + + diff --git a/pages/hack-school/images/apiwaiter.png b/pages/hack-school/images/apiwaiter.png new file mode 100644 index 0000000..c73a458 Binary files /dev/null and b/pages/hack-school/images/apiwaiter.png differ diff --git a/pages/hack-school/images/props.PNG b/pages/hack-school/images/props.PNG new file mode 100644 index 0000000..d5871bc Binary files /dev/null and b/pages/hack-school/images/props.PNG differ diff --git a/pages/index.mdx b/pages/index.mdx index 9bffb72..7bfaf31 100644 --- a/pages/index.mdx +++ b/pages/index.mdx @@ -1,2 +1,22 @@ import HomePage from '../src/homepage'; -export default HomePage; \ No newline at end of file +import { useSSG } from 'nextra/ssg'; +import { getAllHackEvents, getHackEvent } from '../src/api/events_api'; + +export async function getStaticProps() { + const uuids = ["1668587f-5816-45cc-8b5e-1a4825dff9e4", "2ba9e5ed-614e-4c19-9d7c-ab2cfd57e140", "73fc61ef-b3db-46c4-a5bf-71aba152e2f6", "3b922d84-9c57-4f2a-9e76-19e4e9130fe2", "6124d23b-ab77-481f-9248-920565ac07f3", "fdd1c33f-f31b-4421-abc9-0887158147cc"] + const promises = uuids.map(uuid => getHackEvent(uuid)) + const past_events = await Promise.all(promises); + const future_events = await getAllHackEvents('future'); + + return { + props: { + ssg: { + past_events: past_events || [], + future_events: future_events || [] + } + }, + revalidate: 1 * 60 * 60, // once every hour (in seconds) + }; +} + + diff --git a/public/assets/alexis.jpeg b/public/assets/alexis.jpeg new file mode 100644 index 0000000..e3f847b Binary files /dev/null and b/public/assets/alexis.jpeg differ diff --git a/public/assets/angela.jpeg b/public/assets/angela.jpeg new file mode 100644 index 0000000..d4d871c Binary files /dev/null and b/public/assets/angela.jpeg differ diff --git a/public/assets/charvi.jpeg b/public/assets/charvi.jpeg new file mode 100644 index 0000000..b7fd2b0 Binary files /dev/null and b/public/assets/charvi.jpeg differ diff --git a/public/assets/khushi.jpeg b/public/assets/khushi.jpeg new file mode 100644 index 0000000..965cde3 Binary files /dev/null and b/public/assets/khushi.jpeg differ diff --git a/public/assets/left_diamonds.svg b/public/assets/left_diamonds.svg index 0b336b3..91095d6 100644 --- a/public/assets/left_diamonds.svg +++ b/public/assets/left_diamonds.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/public/assets/nikhil.JPG b/public/assets/nikhil.JPG new file mode 100644 index 0000000..44b6781 Binary files /dev/null and b/public/assets/nikhil.JPG differ diff --git a/public/assets/right_diamonds.svg b/public/assets/right_diamonds.svg index 031aec5..70d7785 100644 --- a/public/assets/right_diamonds.svg +++ b/public/assets/right_diamonds.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/api/events_api.tsx b/src/api/events_api.tsx new file mode 100644 index 0000000..ae3e251 --- /dev/null +++ b/src/api/events_api.tsx @@ -0,0 +1,66 @@ +// Modified from https://github.com/acmucsd/main-website/blob/main/src/api/EventsAPI.ts +const EVENT_API = 'https://api.acmucsd.com/api/v2/event'; + +export type EventObject = { + uuid: string; + organization: string; + committee: string; + cover: string; + title: string; + description: string; + location: string; + eventLink?: string; + start: string; + end: string; + pointValue: number; + requiresStaff: boolean; + staffPointBonus: number; +}; + +export type EventsArray = EventObject[]; + +export type EventsResponse = { + error: unknown; + events: EventsArray; +}; + +export type EventResponse = { + error: unknown; + event: EventObject; +}; + +const handleErrors = (response: Response) => { + if (!response.ok) { + throw Error(response.statusText); + } + return response.json(); +}; + +const getAllHackEvents = async ( + type: 'past' | 'future' | '' = '' +): Promise => { + const api_url = `${EVENT_API}/${type}`; + + try { + const response: Response = await fetch(api_url); + const result: EventsResponse = await handleErrors(response); + const filteredEvents = result.events.filter(event => event.committee === 'Hack'); + return filteredEvents; + } catch (error) { + return undefined; + } +}; + +const getHackEvent = async (uuid: string): Promise => { + const api_url = `${EVENT_API}/${uuid}`; + + try { + const response: any = await fetch(api_url); + const result: EventResponse = await handleErrors(response); + return result.event; + } catch (error) { + return undefined; + } +}; + +export { getAllHackEvents, getHackEvent }; diff --git a/src/components/event-card/index.tsx b/src/components/event-card/index.tsx index ea1acad..62c6c4b 100644 --- a/src/components/event-card/index.tsx +++ b/src/components/event-card/index.tsx @@ -1,7 +1,52 @@ import styles from './style.module.css'; +import { EventObject } from '../../api/events_api'; -const EventsCard: React.FC = () => { - return

Event Card

; +const EventsCard: React.FC<{ event: EventObject }> = ({ event }) => { + const months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'June', + 'July', + 'Aug', + 'Sept', + 'Oct', + 'Nov', + 'Dec', + ]; + const days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat']; + const date = new Date(event.start).getDate(); + const month = months[new Date(event.start).getMonth()]; + const day = days[new Date(event.start).getDay()]; + const year = new Date(event.start).getFullYear(); + const { uuid, title, cover, location } = event; + const formatTitle = (title: string): string => { + return encodeURIComponent(title.toLowerCase().trim().replace(/ /g, '-')); + }; + return ( +
+ +
+
+

+ {month} + {date} {year} +

+

{day}

+
+
+ Event cover +
+
+

{title}

+

{location}

+
+
+
+
+ ); }; export default EventsCard; diff --git a/src/components/event-card/style.module.css b/src/components/event-card/style.module.css index e69de29..363e038 100644 --- a/src/components/event-card/style.module.css +++ b/src/components/event-card/style.module.css @@ -0,0 +1,38 @@ +.card { + display: flex; + flex-direction: column; + justify-content: space-between; + width: 100%; + height: 100%; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + border: 2px solid #333; + border-radius: 20px; + position: relative; + padding: 1rem; + cursor: pointer; +} + +.card_header { + display: flex; + justify-content: space-between; + font-size: 1.5rem; + margin-bottom: 1rem; +} + +.card_cover { + flex-grow: 1; + width: 100%; + margin-bottom: 1rem; +} + +.card_image { + border-radius: 20px; +} + +.card_title { + color: var(--docs-accent-color) !important; +} + +.card_day { + font-size: 1rem; +} \ No newline at end of file diff --git a/src/components/team-card/email.tsx b/src/components/team-card/email.tsx new file mode 100644 index 0000000..fee9199 --- /dev/null +++ b/src/components/team-card/email.tsx @@ -0,0 +1,10 @@ +// email.svg +import React from 'react'; + +const EmailIcon = () => ( + + + +); + +export default EmailIcon; diff --git a/src/components/team-card/index.tsx b/src/components/team-card/index.tsx index eba7d40..b6082a0 100644 --- a/src/components/team-card/index.tsx +++ b/src/components/team-card/index.tsx @@ -1,37 +1,45 @@ import React from 'react'; import styles from './style.module.css'; +import EmailIcon from './email'; +import LinkedInIcon from './linkedin'; + const TeamCard: React.FC = () => { const teamMembers = [ { name: 'Nikhil Dange', position: 'Hack Technical Lead', email: 'nikhil@acmucsd.org', - imageUrl: 'assets/nikhil2_pfp.JPG', + linkedinLink: 'https://www.linkedin.com/in/nsdange/', + imageUrl: 'assets/nikhil.JPG', }, { name: 'Angela Hu', - position: 'Hack Technical Event Directors', + position: 'Hack Technical Event Director', email: 'angelahu@acmucsd.org', - imageUrl: 'assets/angela_pfp.PNG', + linkedinLink: 'https://www.linkedin.com/in/angelahu925/', + imageUrl: 'assets/angela.jpeg', }, { name: 'Khushi Patel', - position: 'Hack Technical Event Directors', + position: 'Hack Technical Event Director', email: 'khushi@acmucsd.org', - imageUrl: 'assets/khushi_pfp.PNG', + linkedinLink: 'http://www.linkedin.com/in/pateljkhushi', + imageUrl: 'assets/khushi.jpeg', }, { name: 'Charvi Shukla', - position: 'Hack Technical Event Directors', + position: 'Hack Technical Event Director', email: 'charvi@acmucsd.org', - imageUrl: 'assets/charvi_pfp.PNG', + linkedinLink: 'https://www.linkedin.com/in/charvi-shukla-439b681b2/', + imageUrl: 'assets/charvi.jpeg', }, { name: 'Alexis Vergnet', - position: 'Hack Technical Event Directors', + position: 'Hack Technical Event Director', email: 'alexis@acmucsd.org', - imageUrl: 'assets/alexis_pfp.PNG', + linkedinLink: 'https://www.linkedin.com/in/avergnet/', + imageUrl: 'assets/alexis.jpeg', }, ]; @@ -42,13 +50,19 @@ const TeamCard: React.FC = () => {
{member.name}

{member.name}

-

{member.position}

-

{member.email}

+
{member.position}
+
+ + + + + + +
))} ); }; - export default TeamCard; diff --git a/src/components/team-card/linkedin.tsx b/src/components/team-card/linkedin.tsx new file mode 100644 index 0000000..e9de2f7 --- /dev/null +++ b/src/components/team-card/linkedin.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +const LinkedInIcon = () => ( + + + +); + +export default LinkedInIcon; diff --git a/src/components/team-card/style.module.css b/src/components/team-card/style.module.css index c438be7..efecc82 100644 --- a/src/components/team-card/style.module.css +++ b/src/components/team-card/style.module.css @@ -1,25 +1,55 @@ .team { - display: flex; - flex-wrap: wrap; + display: grid; + /* grid-template-columns: 19% 19% 19% 19% 19%; */ + grid-template-columns: repeat(5, 1fr); justify-content: center; -} - -.card { - margin: 10px; + gap: 0.5rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + } + + .card { text-align: center; -} - -.cardOutline { - border: 2px solid #333; + } + + .cardOutline { + border: 2px solid #f9a857; padding: 16px; - text-align: center; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); border-radius: 10px; -} + height: 100%; + } -.card img { - width: 250px; - height: 250px; + .card h4 { + font-weight: bold; + margin-top: 10px; + } + + .icons { + display: flex; + align-items: center; + justify-content: center; + gap: 1.5rem; + margin-top: 0.25rem; + } + + .icons svg { + fill: #f9a857; + } + + .card img { border-radius: 50%; - display: inline-block; -} \ No newline at end of file + } + + @media screen and (max-width: 810px) { + .team { + grid-template-columns: repeat(3, 1fr); + gap: 0.3rem; + } + } + @media screen and (max-width: 600px) { + .team { + grid-template-columns: 50%; + gap: 0.3rem; + } + } + \ No newline at end of file diff --git a/src/homepage.tsx b/src/homepage.tsx index 5e8854e..aa04b9c 100644 --- a/src/homepage.tsx +++ b/src/homepage.tsx @@ -5,12 +5,17 @@ import About from './sections/About'; import Events from './sections/Events'; import Team from './sections/Team'; -const HomePage: NextPage = () => { +import { EventsArray } from './api/events_api'; + +const HomePage: NextPage<{ past_events: EventsArray; future_events: EventsArray }> = ({ + past_events, + future_events, +}) => { return (
- +
); diff --git a/src/sections/Events/index.tsx b/src/sections/Events/index.tsx index 9a48704..3f7f6f3 100644 --- a/src/sections/Events/index.tsx +++ b/src/sections/Events/index.tsx @@ -1,7 +1,48 @@ +import { useState } from 'react'; import styles from './style.module.css'; +import EventsCard from '../../components/event-card'; +import { EventsArray } from '../../api/events_api'; -const Events: React.FC = () => { - return

Event Section

; +const Events: React.FC<{ past_events: EventsArray; future_events: EventsArray }> = ({ + past_events, + future_events, +}) => { + const [selectedOption, setSelectedOption] = useState('Upcoming'); // State to store the selected option + const [filteredEvents, setFilteredEvents] = useState(future_events); + + // Function to handle option change + const handleOptionChange = (event: React.ChangeEvent) => { + const selected = event.target.value; + setSelectedOption(selected); + + // Set filtered events based on the selected option + if (selected === 'Upcoming') { + setFilteredEvents(future_events); + } else if (selected === 'Past') { + setFilteredEvents(past_events); + } + }; + + return ( +
+
+

Events

+
+ +
+
+
+ {!filteredEvents ? ( +

No upcoming events. Check again later!

+ ) : ( + filteredEvents.map(event => ) + )} +
+
+ ); }; export default Events; diff --git a/src/sections/Events/style.module.css b/src/sections/Events/style.module.css index 7b3eeae..e0b47ca 100644 --- a/src/sections/Events/style.module.css +++ b/src/sections/Events/style.module.css @@ -1,9 +1,31 @@ -.events { +.container { display: flex; - justify-content: center; + flex-direction: column; align-items: center; - width: 100%; - height: 30vh; - max-height: 100vh; - border-bottom: 1px solid black; +} +.events { + display: grid; + margin: 0 auto; + grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); + row-gap: 2rem; + column-gap: 2rem; + max-width: 90%; + text-align: center; +} + +.header { + margin-top: 2rem; + margin-bottom: 2rem; + text-align: center; + font-weight: 700; +} + +.title { + font-size: 2rem; +} + +.event_type { + margin-top: 1rem; + border: 2px solid; + border-radius: 4px; } \ No newline at end of file diff --git a/src/sections/Hero/style.module.css b/src/sections/Hero/style.module.css index b436347..82c789c 100644 --- a/src/sections/Hero/style.module.css +++ b/src/sections/Hero/style.module.css @@ -7,6 +7,7 @@ background-color: var(--docs-accent-color); color: #fff; overflow: hidden; + transition: all 0.5s ease-in-out; } .backdrop { @@ -24,6 +25,7 @@ .backdrop_left, .backdrop_right { object-fit: contain; width: 100%; + height: 100%; } /* Landing Card Text */ @@ -43,6 +45,7 @@ /* Landing Card Scroll Down */ .arrow { + margin-top: auto; margin-bottom: 1em; text-align: center; font-size: 1.5em; @@ -67,11 +70,13 @@ } .backdrop { grid-template-columns: minmax(18em, 1fr); + grid-template-rows: minmax(0, 0.7fr); max-width: 95%; } .backdrop_left{ justify-self: center; - width: 70%; + max-width: 70%; + max-height: 100%; } .backdrop_right { display: none; @@ -86,10 +91,11 @@ @media screen and (min-device-width : 768px) and (max-device-width : 1024px) { .backdrop { grid-template-columns: 1fr 2fr; + grid-template-rows: 1fr; max-width: 95%; } .backdrop_left{ - width: 100%; + max-width: 100%; } .backdrop_right { display: none; @@ -116,4 +122,4 @@ html[class~='dark'] .landing_title { html[class~='dark'] .arrow { filter: brightness(85%); -} \ No newline at end of file +} diff --git a/src/sections/Team/index.tsx b/src/sections/Team/index.tsx index 315f29c..77531f3 100644 --- a/src/sections/Team/index.tsx +++ b/src/sections/Team/index.tsx @@ -4,7 +4,7 @@ import TeamCard from '../../components/team-card/index'; const Team: React.FC = () => { return (
-

Team Section

+

Meet the Team!

); diff --git a/src/sections/Team/style.module.css b/src/sections/Team/style.module.css index 9c70248..a6add00 100644 --- a/src/sections/Team/style.module.css +++ b/src/sections/Team/style.module.css @@ -8,3 +8,12 @@ border-bottom: 1px solid black; } +.h1 { + font-size: x-large; + text-align: center; + font-weight: bold; + color: #f9a857; + margin-top: 1rem; + margin-bottom: 0.5rem; +} + diff --git a/theme.config.tsx b/theme.config.tsx index 654c8e5..bda926b 100644 --- a/theme.config.tsx +++ b/theme.config.tsx @@ -13,10 +13,10 @@ const config: DocsThemeConfig = { const url = `https://hack.acmucsd.com${ defaultLocale === locale ? asPath : `/${locale}${asPath}` }`; - const title = frontMatter.title || 'ACM Hack at UCSD'; + const title = frontMatter.title || 'ACM Hack at UC San Diego'; const description = frontMatter.description || - "ACM Hack at UCSD is a community focused on software engineering and exploring what's possible through code!"; + "ACM Hack at UC San Diego is a community focused on software engineering and exploring what's possible through code!"; return ( <> @@ -33,7 +33,7 @@ const config: DocsThemeConfig = { {/* type of content */} {/* actual website title */} - + {/* title to display for the specific link being shared */} {/* preview description text */}