mirror of
https://github.com/tlsnotary/website.git
synced 2026-01-08 21:48:05 -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
|
### 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:
|
Here is an example of a project's entry:
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import EthLogo from './components/EthLogo';
|
import EthLogo from './components/EthLogo';
|
||||||
import Starter from './components/Starter';
|
import Starter from './components/Starter';
|
||||||
import Projects from './components/Projects';
|
import Projects from './components/Projects';
|
||||||
|
import Team from './components/Team';
|
||||||
import Footer from './components/Footer';
|
import Footer from './components/Footer';
|
||||||
import './Home.css';
|
import './Home.css';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.ProjectsList {
|
.Cards {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||||
gap: 2.5rem;
|
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 './MagicCard.css';
|
||||||
import ColorHash from 'color-hash'
|
import ColorHash from 'color-hash'
|
||||||
|
|
||||||
export interface CardProps {
|
export interface MagicCardProps {
|
||||||
name: string;
|
name: string;
|
||||||
short_name?: string;
|
short_name?: string;
|
||||||
description: string | string[];
|
description: string | string[];
|
||||||
long_description?: string | string[];
|
long_description?: string | string[];
|
||||||
image?: string;
|
image?: string;
|
||||||
links?: Links[];
|
links?: Links[];
|
||||||
|
renderBanner?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Links {
|
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 hueRange = { min: 45, max: 360 }
|
||||||
let colorHashText = new ColorHash({hue: hueRange, lightness: [0.8, 0.9]}).hex(name);
|
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);
|
let colorHashBG = new ColorHash({hue: hueRange, lightness: [0.35, 0.4], saturation: [0.65, 0.85, 1]}).hex(name);
|
||||||
return (
|
return (
|
||||||
<svg height="150px" width="350px" style={{backgroundColor: colorHashBG}} className="card-img-top">
|
<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>
|
</svg>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -58,7 +59,7 @@ function renderDescription(description: string | string[]): any {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function MagicCard(props: CardProps) {
|
function MagicCard(props: MagicCardProps) {
|
||||||
let links = props.links
|
let links = props.links
|
||||||
? props.links.map((link) => {
|
? props.links.map((link) => {
|
||||||
if (link.github) {
|
if (link.github) {
|
||||||
@@ -83,11 +84,19 @@ function MagicCard(props: CardProps) {
|
|||||||
return (
|
return (
|
||||||
<img className="card-img-top" src={require(`../images/${props.image}`)} alt={props.name} />
|
<img className="card-img-top" src={require(`../images/${props.image}`)} alt={props.name} />
|
||||||
);
|
);
|
||||||
} else {
|
} else if (props.renderBanner == true || props.renderBanner == undefined) {
|
||||||
return renderImage(props.short_name || props.name);
|
return renderBanner(props.short_name || props.name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} 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}
|
{img}
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h5 className="card-title">{props.name}</h5>
|
<h5 className="card-title">{props.name}</h5>
|
||||||
<p className="card-text">{props.description}</p>
|
{renderDescription(props.description)}
|
||||||
<div className="card-footer">{links}</div>
|
<div className="card-footer">{links}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,28 +1,10 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import CardSection from './CardSection';
|
||||||
import MagicCard, { CardProps } from './MagicCard';
|
import ProjectData from '../data/Projects.json';
|
||||||
import { shuffleFisherYates } from '../Utils';
|
|
||||||
import ProjectData from './Projects.json';
|
|
||||||
import './Projects.css';
|
|
||||||
|
|
||||||
|
|
||||||
function Projects() {
|
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 (
|
return (
|
||||||
<div className="Projects">
|
<CardSection title="Projects" cardData={ProjectData}></CardSection>
|
||||||
<h1 className="mb-4">Projects</h1>
|
|
||||||
<div className="ProjectsList">{_projects}</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ function Starter() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-md-12 arrow">
|
<div className="col-md-12 arrow">
|
||||||
<img src={arrow} alt="" />
|
<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
|
more info below
|
||||||
</div>
|
</div>
|
||||||
</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 {
|
.btn {
|
||||||
color: black;
|
color: var(--gray);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin: 0.25rem;
|
margin: 0.25rem;
|
||||||
border: 2px solid var(--gray);
|
border: 2px solid var(--gray);
|
||||||
@@ -52,7 +52,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: black;
|
color: var(--gray);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
background: var(--purple);
|
background: var(--purple);
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|||||||
Reference in New Issue
Block a user