implemented projects page and footer. added under construction splash to other pages.
This commit is contained in:
Generated
+10
@@ -12,6 +12,7 @@
|
||||
"react": "19.0.0-rc-3edc000d-20240926",
|
||||
"react-bootstrap": "^2.10.7",
|
||||
"react-dom": "19.0.0-rc-3edc000d-20240926",
|
||||
"react-icons": "^5.4.0",
|
||||
"react-router": "^7.0.2",
|
||||
"react-scripts": "^5.0.0"
|
||||
}
|
||||
@@ -13914,6 +13915,15 @@
|
||||
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz",
|
||||
"integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"react": "19.0.0-rc-3edc000d-20240926",
|
||||
"react-bootstrap": "^2.10.7",
|
||||
"react-dom": "19.0.0-rc-3edc000d-20240926",
|
||||
"react-icons": "^5.4.0",
|
||||
"react-router": "^7.0.2",
|
||||
"react-scripts": "^5.0.0"
|
||||
},
|
||||
|
||||
|
Before Width: | Height: | Size: 4.6 MiB After Width: | Height: | Size: 4.6 MiB |
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
<title>Josh Ashton</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import Navigation from './components/Navigation';
|
||||
import Footer from './components/Footer';
|
||||
import Splash from './components/Splash';
|
||||
|
||||
export default function About() {
|
||||
return (
|
||||
<>
|
||||
<Navigation />
|
||||
<Splash primaryText="Under Construction" />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import Navigation from './components/Navigation';
|
||||
import Footer from './components/Footer';
|
||||
import Splash from './components/Splash';
|
||||
|
||||
export default function Blog() {
|
||||
return (
|
||||
<>
|
||||
<Navigation />
|
||||
<Splash primaryText="Under Construction" />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import Navigation from './components/Navigation';
|
||||
import Footer from './components/Footer';
|
||||
import Splash from './components/Splash';
|
||||
|
||||
export default function Contact() {
|
||||
return (
|
||||
<>
|
||||
<Navigation />
|
||||
<Splash primaryText="Under Construction" />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ import FeaturedContent from './components/FeaturedContent';
|
||||
|
||||
export default function Home() {
|
||||
const projectCards = [
|
||||
<ProjectCard img="./assets/img/dnd.png" title="D&D" description="ASDF" url="https://github.com/quaxlyqueen/dnd"/>,
|
||||
<ProjectCard img="./assets/img/graph.png" title="Graph Visualizer" description="ASDF" url="https://github.com/quaxlyqueen/2420-graph-visualizer"/>,
|
||||
<ProjectCard img="./assets/img/dnd.png" name="D&D" description="Dungeons and Dragons character builder app, developed in Java." url="https://github.com/quaxlyqueen/dnd"/>,
|
||||
<ProjectCard img="./assets/img/graph.png" name="Graph Visualizer" description="Interactive representation of a graph data structure, developed in Java." url="https://github.com/quaxlyqueen/2420-graph-visualizer"/>,
|
||||
];
|
||||
return (
|
||||
<>
|
||||
|
||||
+29
-9
@@ -1,6 +1,6 @@
|
||||
import Navigation from './components/Navigation';
|
||||
import Footer from './components/Footer';
|
||||
import ProjectDisplay from './components/ProjectDisplay';
|
||||
import ProjectCard from './components/ProjectCard';
|
||||
|
||||
/*
|
||||
* The Projects page.
|
||||
@@ -8,24 +8,44 @@ import ProjectDisplay from './components/ProjectDisplay';
|
||||
export default function Projects() {
|
||||
/*
|
||||
* An array of project data to feed to the ProjectDisplay component.
|
||||
{
|
||||
frontend: "",
|
||||
backend: "",
|
||||
id: "",
|
||||
name: "",
|
||||
description: "",
|
||||
url: "",
|
||||
img: ""
|
||||
},
|
||||
*/
|
||||
const data = [
|
||||
{
|
||||
frontend: "flutter",
|
||||
backend: "go",
|
||||
id: "one-ai",
|
||||
name: 'One AI',
|
||||
description: "TODO",
|
||||
url: "https://github.com/quaxlyqueen/one-ai"
|
||||
frontend: "java",
|
||||
backend: "",
|
||||
id: "dnd",
|
||||
name: "D&D",
|
||||
description: "Dungeons and Dragons character builder app, developed in Java.",
|
||||
url: "https://github.com/quaxlyqueen/dnd",
|
||||
img: "/assets/img/dnd.png"
|
||||
},
|
||||
{
|
||||
frontend: "java",
|
||||
backend: "",
|
||||
id: "graph",
|
||||
name: "Graph Visualizer",
|
||||
description: "Interactive representation of a graph data structure, developed in Java.",
|
||||
url: "https://github.com/quaxlyqueen/2420-graph-visualizer",
|
||||
img: "/assets/img/graph.png"
|
||||
},
|
||||
];
|
||||
|
||||
let i = 0;
|
||||
return (
|
||||
<>
|
||||
<Navigation />
|
||||
<div>
|
||||
<div className="project-grid">
|
||||
{data.map(item => (
|
||||
<ProjectDisplay frontend={item.frontend} backend={item.backend} id={item.id} name={item.name} description={item.description} url={item.url} />
|
||||
<ProjectCard frontend={item.frontend} backend={item.backend} id={item.id} name={item.name} description={item.description} url={item.url} img={item.img} />
|
||||
))}
|
||||
</div>
|
||||
<Footer />
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import Navigation from './components/Navigation';
|
||||
import Footer from './components/Footer';
|
||||
import Splash from './components/Splash';
|
||||
|
||||
export default function Resume() {
|
||||
return (
|
||||
<>
|
||||
<Navigation />
|
||||
<Splash primaryText="Under Construction" />
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { FaLinkedinIn } from 'react-icons/fa';
|
||||
import { FaInstagram } from 'react-icons/fa';
|
||||
import { FaTwitterinIn } from 'react-icons/fa';
|
||||
import { FaThreadsIn } from 'react-icons/fa';
|
||||
/**
|
||||
*
|
||||
*
|
||||
@@ -6,13 +10,34 @@
|
||||
*/
|
||||
export default function Footer() {
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<p>Copyright or open source license here.</p>
|
||||
<ul>
|
||||
<li><a href="contact">Contact</a></li>
|
||||
<footer className="footer">
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<p>© {new Date().getFullYear()} Josh Ashton</p>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<ul className="social-links">
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="/projects">Projects</a></li>
|
||||
<li><a href="/about">About</a></li>
|
||||
<li><a href="/contact">Contact</a></li>
|
||||
<li><a href="/resume">Resume</a></li>
|
||||
<li><a href="/blog">Blog</a></li>
|
||||
<li>
|
||||
<a href="https://www.linkedin.com/in/joshuatashton/" target="_blank" rel="noopener noreferrer">
|
||||
<FaLinkedinIn />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.instagram.com/joshuatashton/" target="_blank" rel="noopener noreferrer">
|
||||
<FaInstagram />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,38 @@
|
||||
import React, { useState } from 'react';
|
||||
import Nav from 'react-bootstrap/Nav';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
/*
|
||||
* Create a nav bar component.
|
||||
*
|
||||
* Use Bootstrap for styling.
|
||||
*
|
||||
* TODO: Add links as a prop.
|
||||
*/
|
||||
export default function Navigation() {
|
||||
const [isNavbarCollapsed, setIsNavbarCollapsed] = useState(false);
|
||||
|
||||
const toggleNavbar = () => {
|
||||
setIsNavbarCollapsed(!isNavbarCollapsed);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<a className="navbar-brand" href="/">Josh Ashton</a>
|
||||
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<button
|
||||
className="navbar-toggler"
|
||||
type="button"
|
||||
onClick={toggleNavbar}
|
||||
aria-controls="navbarNav"
|
||||
aria-expanded={isNavbarCollapsed}
|
||||
aria-label="Toggle navigation"
|
||||
>
|
||||
<span className="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div className="collapse navbar-collapse" id="navbarNav">
|
||||
<div
|
||||
className={`collapse navbar-collapse ${isNavbarCollapsed ? 'show' : ''}`}
|
||||
id="navbarNav"
|
||||
>
|
||||
<ul className="navbar-nav nav-fill w-100">
|
||||
<a className="nav-link" href="/projects"><li className="nav-item">Projects</li></a>
|
||||
<a className="nav-link" href="/about"><li className="nav-item">About</li></a>
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
/*
|
||||
* Create a ProjectCard.
|
||||
*
|
||||
* @param String frontend "The frontend framework/library used for the project. Used for sorting/filtering."
|
||||
* @param String backend "The backend framework/library used for the project. Used for sorting/filtering."
|
||||
* @param String id "Lowercase string representation of the project name."
|
||||
* @param String name "The name of the project."
|
||||
* @param String description "A description of the project."
|
||||
* @param String url "The URL for the repository of the project."
|
||||
* @param String img "Path to an image."
|
||||
* @param String title "Title of the card."
|
||||
* @param String description "A short description for the card."
|
||||
* @param String url "URL to a project."
|
||||
*
|
||||
* TODO: Need to add classes and styling.
|
||||
* @param String imgCaption "Accessibile caption for the image."
|
||||
*/
|
||||
export default function ProjectCard( {img, title, description, url} ) {
|
||||
export default function ProjectCard( {frontend, backend, id, name, description, url, img, imgCaption} ) {
|
||||
console.log(img);
|
||||
return (
|
||||
<>
|
||||
<div className="card">
|
||||
<img className="card-img-top" src={img} alt="TODO: Image caption."/>
|
||||
<div className={`card ${frontend} ${backend}`}>
|
||||
<img className="card-img-top" src={img} alt={imgCaption}/>
|
||||
<div className="card-body">
|
||||
<h2 className="card-title dark-text">{title}</h2>
|
||||
<h2 className="card-title dark-text">{name}</h2>
|
||||
<p className="dark-text">{description}</p>
|
||||
<a className = "btn btn-primary" target="_blank" href={url}>View Code on GitHub</a>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
/*
|
||||
* Create a clickable frame which expands to expose additional information on click.
|
||||
*
|
||||
@@ -9,12 +11,30 @@
|
||||
* TODO: Need to implement onClick
|
||||
*/
|
||||
export default function ProjectDisplay( {frontend, backend, id, name, description, url} ) {
|
||||
const [isDisplayCollapsed, setIsDisplayCollapsed] = useState(false);
|
||||
|
||||
const toggleDisplay = () => {
|
||||
setIsDisplayCollapsed(!isDisplayCollapsed);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className={`panel ${frontend} ${backend}`} id={id}>
|
||||
<div
|
||||
className={`panel ${frontend} ${backend} ${isDisplayCollapsed ? 'open open-active' : ''}`}
|
||||
id={id}
|
||||
onClick={toggleDisplay}
|
||||
aria-expanded={!isDisplayCollapsed} // Invert the condition for aria-expanded
|
||||
>
|
||||
<h3 className="label">{name}</h3>
|
||||
{isDisplayCollapsed && ( // Conditionally render additional content
|
||||
<>
|
||||
<h4 className="label-text">{description}</h4>
|
||||
<button type="button" className="btn btn-primary"><a target="_blank" href={url}>View Code on GitHub</a></button>
|
||||
<button type="button" className="btn btn-primary">
|
||||
<a target="_blank" href={url}>
|
||||
View Code on GitHub
|
||||
</a>
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
+84
-4
@@ -1,6 +1,6 @@
|
||||
:root {
|
||||
--main-dark-color: #4A245E;
|
||||
--main-offwhite-color: white,
|
||||
--main-offwhite-color: white;
|
||||
--main-midtone-color: #9BC995;
|
||||
--main-accent-color: #673283;
|
||||
--secondary-accent-color: #98B9AB;
|
||||
@@ -92,7 +92,7 @@ p {
|
||||
|
||||
.navbar-brand {
|
||||
padding-left: .5vw;
|
||||
color: #4A245E;
|
||||
color: var(--main-dark-color);
|
||||
font-size: 2vw;
|
||||
font-weight: bold;
|
||||
|
||||
@@ -132,7 +132,7 @@ p {
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: var(--main-dark-color);
|
||||
background-color: var(--main-dark-color);
|
||||
}
|
||||
|
||||
.bar {
|
||||
@@ -206,6 +206,7 @@ input[type="radio"]:hover + label {
|
||||
background-position: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panel > * {
|
||||
@@ -247,10 +248,19 @@ input[type="radio"]:hover + label {
|
||||
}
|
||||
|
||||
.panel.open {
|
||||
overflow: visible;
|
||||
flex: 5;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.panel .label-text, .panel .btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel.open .label-text, .panel.open .btn {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.carousel-wrapper {
|
||||
flex: 0 0 40%;
|
||||
padding-top: 5vw;
|
||||
@@ -274,6 +284,24 @@ input[type="radio"]:hover + label {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex; /* Enable flexbox layout */
|
||||
flex-direction: column; /* Stack items vertically */
|
||||
align-items: center; /* Center items horizontally */
|
||||
justify-content: center; /* Center items vertically */
|
||||
margin: 1vw;
|
||||
}
|
||||
|
||||
.card img {
|
||||
max-width: 50vw;
|
||||
max-height: 35vw;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-size: 2vw;
|
||||
}
|
||||
@@ -316,10 +344,62 @@ input[type="radio"]:hover + label {
|
||||
|
||||
.btn:hover {
|
||||
background-color: var(--main-accent-color);
|
||||
border: 2px solid var(--main-offwhite-color);
|
||||
}
|
||||
|
||||
.btn > a {
|
||||
text-decoration: none;
|
||||
color: var(--main-offwhite-color);
|
||||
}
|
||||
|
||||
.social-links {
|
||||
list-style: none; /* Remove default list styling */
|
||||
display: flex; /* Display list items as flex items */
|
||||
justify-content: space-between; /* Space items evenly */
|
||||
}
|
||||
|
||||
.social-links li {
|
||||
margin: 0 10px; /* Add spacing between icons */
|
||||
}
|
||||
|
||||
.social-links li a {
|
||||
text-decoration: none;
|
||||
color: var(--main-offwhite-color);
|
||||
}
|
||||
|
||||
.project-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between; /* Distribute projects evenly */
|
||||
margin: 2vw auto; /* Center grid horizontally */
|
||||
}
|
||||
|
||||
/* Responsive Breakpoints */
|
||||
@media (min-width: 992px) { /* Large Screens (3 columns) */
|
||||
.project-grid {
|
||||
width: 80%; /* Adjust width as needed */
|
||||
}
|
||||
|
||||
.project-grid > * {
|
||||
flex: 0 0 30%; /* Set a fixed width for each project */
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 991px) { /* Medium Screens (2 columns) */
|
||||
.project-grid {
|
||||
width: 80%; /* Adjust width as needed */
|
||||
}
|
||||
|
||||
.project-grid > * {
|
||||
flex: 0 0 40%; /* Set a fixed width for each project */
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) { /* Small Screens (1 column) */
|
||||
.project-grid {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.project-grid > * {
|
||||
flex: 1 1 80%; /* Set full width for each project */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user