mirror of
https://github.com/tlsnotary/website.git
synced 2026-01-07 21:24:15 -05:00
Refactored projects to card sections and magic cards to be more genericly usable, added team members
This commit is contained in:
@@ -15,7 +15,7 @@ The components live under `/src/components`.
|
||||
|
||||
### Add / Change a Project Entry
|
||||
|
||||
All the projects are stored in the `projects.json` file in `/src/components/`
|
||||
All the projects are stored in the `projects.json` file in `/src/data/`
|
||||
|
||||
Here is an example of a project's entry:
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import EthLogo from './components/EthLogo';
|
||||
import Starter from './components/Starter';
|
||||
import Projects from './components/Projects';
|
||||
import Team from './components/Team';
|
||||
import Footer from './components/Footer';
|
||||
import './Home.css';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.ProjectsList {
|
||||
.Cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||
gap: 2.5rem;
|
||||
41
src/components/CardSection.tsx
Normal file
41
src/components/CardSection.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import MagicCard, { MagicCardProps } from './MagicCard';
|
||||
import { shuffleFisherYates } from '../Utils';
|
||||
import './CardSection.css';
|
||||
|
||||
interface ICardSection {
|
||||
title: string;
|
||||
cardData: MagicCardProps[];
|
||||
shuffle?: boolean;
|
||||
renderBanner?: boolean | undefined;
|
||||
}
|
||||
|
||||
function CreateCards(cards: MagicCardProps[], shuffle: boolean = true, renderBanner: boolean | undefined): JSX.Element[] {
|
||||
let _cards = cards.map((card: MagicCardProps) => {
|
||||
if (renderBanner == true) {
|
||||
return <MagicCard key={card.name} {...card} renderBanner={true} />;
|
||||
} else if (renderBanner == false) {
|
||||
return <MagicCard key={card.name} {...card} renderBanner={false} />;
|
||||
}
|
||||
return <MagicCard key={card.name} {...card} />;
|
||||
})
|
||||
|
||||
if (shuffle) {
|
||||
_cards = shuffleFisherYates(_cards as []);
|
||||
}
|
||||
|
||||
return _cards
|
||||
}
|
||||
|
||||
function CardSection(props: ICardSection) {
|
||||
let [cards] = useState<any[]>([CreateCards(props.cardData, props.shuffle, props.renderBanner)]);
|
||||
|
||||
return (
|
||||
<div className="CardSection">
|
||||
<h1 className="CardSectionTitle mt-5 mb-4">{props.title}</h1>
|
||||
<div className="Cards">{cards}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CardSection;
|
||||
@@ -6,13 +6,14 @@ import telegram from '../images/telegram.svg';
|
||||
import './MagicCard.css';
|
||||
import ColorHash from 'color-hash'
|
||||
|
||||
export interface CardProps {
|
||||
export interface MagicCardProps {
|
||||
name: string;
|
||||
short_name?: string;
|
||||
description: string | string[];
|
||||
long_description?: string | string[];
|
||||
image?: string;
|
||||
links?: Links[];
|
||||
renderBanner?: boolean;
|
||||
}
|
||||
|
||||
interface Links {
|
||||
@@ -34,13 +35,13 @@ function renderLink(url: string, source: string, icon: string): any {
|
||||
);
|
||||
}
|
||||
|
||||
function renderImage(name: string): any {
|
||||
function renderBanner(name: string): any {
|
||||
let hueRange = { min: 45, max: 360 }
|
||||
let colorHashText = new ColorHash({hue: hueRange, lightness: [0.8, 0.9]}).hex(name);
|
||||
let colorHashBG = new ColorHash({hue: hueRange, lightness: [0.35, 0.4], saturation: [0.65, 0.85, 1]}).hex(name);
|
||||
return (
|
||||
<svg height="150px" width="350px" style={{backgroundColor: colorHashBG}} className="card-img-top">
|
||||
<text text-anchor="middle" x="175px" y="85px" fill={colorHashText} style={{ fontSize: "2.5rem", fontStyle: "italic"}}>{name}</text>
|
||||
<text text-anchor="middle" x="50%" y="50%" fill={colorHashText} style={{ fontSize: "2.5rem", fontStyle: "italic"}}>{name}</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -58,7 +59,7 @@ function renderDescription(description: string | string[]): any {
|
||||
});
|
||||
}
|
||||
|
||||
function MagicCard(props: CardProps) {
|
||||
function MagicCard(props: MagicCardProps) {
|
||||
let links = props.links
|
||||
? props.links.map((link) => {
|
||||
if (link.github) {
|
||||
@@ -83,11 +84,19 @@ function MagicCard(props: CardProps) {
|
||||
return (
|
||||
<img className="card-img-top" src={require(`../images/${props.image}`)} alt={props.name} />
|
||||
);
|
||||
} else {
|
||||
return renderImage(props.short_name || props.name);
|
||||
} else if (props.renderBanner == true || props.renderBanner == undefined) {
|
||||
return renderBanner(props.short_name || props.name);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
return renderImage(props.short_name || props.name);
|
||||
if (props.renderBanner == true || props.renderBanner == undefined) {
|
||||
return renderBanner(props.short_name || props.name);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -96,7 +105,7 @@ function MagicCard(props: CardProps) {
|
||||
{img}
|
||||
<div className="card-body">
|
||||
<h5 className="card-title">{props.name}</h5>
|
||||
<p className="card-text">{props.description}</p>
|
||||
{renderDescription(props.description)}
|
||||
<div className="card-footer">{links}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,28 +1,10 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import MagicCard, { CardProps } from './MagicCard';
|
||||
import { shuffleFisherYates } from '../Utils';
|
||||
import ProjectData from './Projects.json';
|
||||
import './Projects.css';
|
||||
import CardSection from './CardSection';
|
||||
import ProjectData from '../data/Projects.json';
|
||||
|
||||
|
||||
function Projects() {
|
||||
let [projects, setProjects] = useState<CardProps[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
setProjects(ProjectData);
|
||||
}, []);
|
||||
|
||||
let _projects = projects.map((project) => {
|
||||
return (<MagicCard key={project.name} {...project} />);
|
||||
})
|
||||
|
||||
_projects = shuffleFisherYates(_projects as []);
|
||||
|
||||
return (
|
||||
<div className="Projects">
|
||||
<h1 className="mb-4">Projects</h1>
|
||||
<div className="ProjectsList">{_projects}</div>
|
||||
</div>
|
||||
<CardSection title="Projects" cardData={ProjectData}></CardSection>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ function Starter() {
|
||||
</div>
|
||||
<div className="col-md-12 arrow">
|
||||
<img src={arrow} alt="" />
|
||||
<div className="fst-italic more-info" style={{ opacity: '75%', paddingTop: '1rem' }}>
|
||||
<div className="fst-italic more-info" style={{ opacity: '85%', paddingTop: '1rem' }}>
|
||||
more info below
|
||||
</div>
|
||||
</div>
|
||||
|
||||
11
src/components/Team.tsx
Normal file
11
src/components/Team.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import CardSection from './CardSection';
|
||||
import TeamData from '../data/Team.json';
|
||||
|
||||
|
||||
function Team() {
|
||||
return (
|
||||
<CardSection title="Team Members" cardData={TeamData} renderBanner={false}></CardSection>
|
||||
);
|
||||
}
|
||||
|
||||
export default Team;
|
||||
38
src/data/Team.json
Normal file
38
src/data/Team.json
Normal file
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"name": "AtHeartEngineer",
|
||||
"description": "Dev",
|
||||
"links": [
|
||||
{
|
||||
"github": "https://github.com/atheartengineer"
|
||||
},
|
||||
{
|
||||
"twitter": "https://twitter.com/atheartengineer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Person1",
|
||||
"description": "Dev",
|
||||
"links": [
|
||||
{
|
||||
"github": "https://github.com/atheartengineer"
|
||||
},
|
||||
{
|
||||
"twitter": "https://twitter.com/atheartengineer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Person2",
|
||||
"description": "Dev",
|
||||
"links": [
|
||||
{
|
||||
"github": "https://github.com/atheartengineer"
|
||||
},
|
||||
{
|
||||
"twitter": "https://twitter.com/atheartengineer"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -25,7 +25,7 @@
|
||||
}
|
||||
|
||||
.btn {
|
||||
color: black;
|
||||
color: var(--gray);
|
||||
font-weight: 500;
|
||||
margin: 0.25rem;
|
||||
border: 2px solid var(--gray);
|
||||
@@ -52,7 +52,10 @@
|
||||
}
|
||||
|
||||
body {
|
||||
color: black;
|
||||
color: var(--gray);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-rendering: optimizeLegibility;
|
||||
background: var(--purple);
|
||||
background-attachment: fixed;
|
||||
height: 100vh;
|
||||
|
||||
Reference in New Issue
Block a user