Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements #19

Merged
merged 12 commits into from
Dec 14, 2023
19 changes: 5 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
# [Portfolio](https://sagerg.github.io/portfolio/) · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/sagerg/portfolio/blob/main/LICENSE) [![pages-build-deployment](https://github.com/sagerg/portfolio/actions/workflows/pages/pages-build-deployment/badge.svg)](https://github.com/sagerg/portfolio/actions/workflows/pages/pages-build-deployment) ![Webpack CI](https://github.com/sagerg/portfolio/actions/workflows/webpack.yml/badge.svg)


![cover photo](https://github.com/sagerg/portfolio/blob/main/cover.png)


A [React](https://reactjs.org/) web application that:

* **Serves** as a digital portfolio, providing a comprehensive overview of my capabilities and projects
* **Showcases** some of my work, skills, achievements, and experiences
A digital portfolio made with [React](https://reactjs.org/)

## Quick Start

Download and run this application in development mode on your local server:
Download and run this application in development mode:

```
$ git clone https://github.com/sagerg/portfolio.git
Expand All @@ -26,17 +21,13 @@ Run unit tests:
$ npm test
```

Create build directories `/dist` and `/docs` with a production build:
Create build directories `/dist` and `/docs`:

```
$ npm run build
```

Q: Why do we have **two** build directories?

A: Well, `/dist` is built from running `webpack --mode production` but GitHub pages require the `/index.html` to be in the root of the project directory or in `/docs`, so we copy the contents of `/dist` to `/docs` for this purpose.
```

### npm and Node.js
### npm and Node.js Versions

```
$ npm --version
Expand Down
80 changes: 40 additions & 40 deletions dist/bundle.js

Large diffs are not rendered by default.

80 changes: 40 additions & 40 deletions docs/bundle.js

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions src/App.scss

This file was deleted.

9 changes: 8 additions & 1 deletion src/assets/windows.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,16 @@
}

.icons {
font-size: 30px;
font-size: 30px;
padding-left: 10px;
padding-right: 10px;
}

.icons:hover {
border-radius: 5px;
background:rgba(128, 223, 237, 0.5);
}

.close-icon {
display: inline-block;
width: 16px;
Expand Down
7 changes: 3 additions & 4 deletions src/components/ui/CommandOutputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ export const ProjectsText = () => {
</div>
<br/>
<div>
{"Here are some of my personal favorites: "}
<div>
{"This "}
<Link url={"https://github.com/sagerg/portfolio"}>
Expand All @@ -314,10 +313,10 @@ export const ProjectsText = () => {
</div>
<div>
{"A "}
<Link url="https://github.com/sagerg/cmd-line-tools#password-manager">
{"Password Manager"}
<Link url="https://github.com/sagerg/path-finding">
{"Path Finding Script"}
</Link>
{" made with C++ and Vigenère cipher for encryption"}
{" that uses Depth-first search to find a path in a maze"}
</div>
</div>
</Delayed>
Expand Down
108 changes: 53 additions & 55 deletions src/components/ui/Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "../../assets/terminal.css";

import data from "../../data/data.json";

const Loader = ({ user, isLoading, setLoading }) => {
const Loader = ({ user, setLoading }) => {
const multiplier = 500;
const dateIdentifier = "date";
const userIdentifier = "user";
Expand Down Expand Up @@ -40,60 +40,58 @@ const Loader = ({ user, isLoading, setLoading }) => {

return (
<div data-testid="loader-test">
{isLoading &&
<div className="loader">
<PacmanLoader
color={"yellow"}
size={10}
aria-label="Loading Spinner"
/>
{bootSequence.map((text, i) => {
if (text === "") {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<br/>
</Delayed>
);
} else if (text.includes(dateIdentifier)) {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<p>
<span>{text}</span>
<span style={{ color : "cyan" }}>{(new Date()).toUTCString()}</span>
</p>
</Delayed>
);
} else if (text.includes(userIdentifier)) {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<p>
<span>{text}</span>
<span className="highlighted-text">{user}</span>
</p>
</Delayed>
);
} else {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<p>{text}</p>
</Delayed>
);
}
})}
<Delayed waitBeforeShow={loadDuration}>
<span>{"PRESS "}</span>
<Link url="#" opensOnNewTab={false} onClick={() => setLoading(false)}>{"ENTER"}</Link>
<span>{" TO CONTINUE"}</span>
<Cursor />
<br /><br />
</Delayed>
<PulseLoader
color={"yellow"}
size={10}
aria-label="Loading Spinner"
/>
</div>
}
<div className="loader">
<PacmanLoader
color={"yellow"}
size={10}
aria-label="Loading Spinner"
/>
{bootSequence.map((text, i) => {
if (text === "") {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<br/>
</Delayed>
);
} else if (text.includes(dateIdentifier)) {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<p>
<span>{text}</span>
<span style={{ color : "cyan" }}>{(new Date()).toUTCString()}</span>
</p>
</Delayed>
);
} else if (text.includes(userIdentifier)) {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<p>
<span>{text}</span>
<span className="highlighted-text">{user}</span>
</p>
</Delayed>
);
} else {
return (
<Delayed key={i} waitBeforeShow={multiplier * i}>
<p>{text}</p>
</Delayed>
);
}
})}
<Delayed waitBeforeShow={loadDuration}>
<span>{"PRESS "}</span>
<Link url="#" opensOnNewTab={false} onClick={() => setLoading(false)}>{"ENTER"}</Link>
<span>{" TO CONTINUE"}</span>
<Cursor />
<br /><br />
</Delayed>
<PulseLoader
color={"yellow"}
size={10}
aria-label="Loading Spinner"
/>
</div>
</div>
);
};
Expand Down
66 changes: 31 additions & 35 deletions src/pages/Home/Terminal.js → src/components/ui/Terminal.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React , { useEffect, useState, useRef } from "react";
import Cursor from "../../components/ui/Cursor"
import Cursor from "./Cursor"
import {
Prompt,
IntroText,
Expand All @@ -9,13 +9,13 @@ import {
AboutText,
ProjectsText,
SocialMediaText
} from "../../components/ui/CommandOutputs";
} from "./CommandOutputs";

import "../../assets/terminal.css"

import data from "../../data/data.json";

const Terminal = ({ user, isLoading, setLoading }) => {
const Terminal = ({ user, isLoading }) => {
const [terminalHistory, setTerminalHistory] = useState([]);
const [input, setInput] = useState("");
const inputRef = useRef();
Expand Down Expand Up @@ -140,7 +140,7 @@ const Terminal = ({ user, isLoading, setLoading }) => {
};

const handleScrollToInput = () => {
if (!isLoading && inputRef.current !== undefined) {
if (inputRef.current !== undefined) {
setTimeout(() => inputRef.current.scrollIntoView(), 0);
}
};
Expand All @@ -160,45 +160,41 @@ const Terminal = ({ user, isLoading, setLoading }) => {
};

useEffect(() => {
if (!isLoading) {
inputRef.current.focus();
}
}, [isLoading]);
inputRef.current.focus();
}, []);

useEffect(() => {
setTerminalHistory([<LoginText/>, <IntroText user={user}/>]);
}, []);

return (
<div data-testid="terminal-test">
{!isLoading &&
<div
className="terminal-wrapper"
onClick={() => inputRef.current.focus()}
>
<div className="terminal">
{terminalHistory.map((text, index) => (
<div key={index}>
{text}
</div>
))}
</div>
<div>
<Prompt user={user}/>
<input
autoFocus
ref={inputRef}
className="terminal-input"
type="text"
style={{"width" : getTextWidth(input)}}
value={input}
onChange={handleInputOnChange}
onKeyDown={handleOnKeyDown}
/>
<Cursor />
</div>
<div
className="terminal-wrapper"
onClick={() => inputRef.current.focus()}
>
<div className="terminal">
{terminalHistory.map((text, index) => (
<div key={index}>
{text}
</div>
))}
</div>
}
<div>
<Prompt user={user}/>
<input
autoFocus
ref={inputRef}
className="terminal-input"
type="text"
style={{"width" : getTextWidth(input)}}
value={input}
onChange={handleInputOnChange}
onKeyDown={handleOnKeyDown}
/>
<Cursor />
</div>
</div>
</div>
);
};
Expand Down
File renamed without changes.
Loading
Loading