)
diff --git a/pease-portfolio/src/app/career/skills/page.js b/pease-portfolio/src/app/career/skills/page.js
index c184f20..104717e 100644
--- a/pease-portfolio/src/app/career/skills/page.js
+++ b/pease-portfolio/src/app/career/skills/page.js
@@ -1,3 +1,10 @@
+export async function generateMetadata() {
+ return {
+ title: 'Skills | nicholaspease.com'
+ }
+ }
+
+
export default async function Page() {
var languagesData = await fetch("https://wakatime.com/share/@LAX18/1d8ca4cf-2eec-49dc-b5a3-98900456e06e.json")
var languages = await languagesData.json()
@@ -9,7 +16,7 @@ export default async function Page() {
Programming Languages
My top languages are {languages[0].name} ({languages[0].percent}%), {languages[1].name} ({languages[1].percent}%), and {languages[2].name} ({languages[2].percent}%). For a more comprehensive list of all programming languages I have experience with, please see below.
-
+
This is a somewhat incomplete number as this particular tracker WakaTime has only been active and tracking my coding activity since February 16th, 2024. Some previous languages I have more experience with include z80 Assembly for TI calculators and TI-BASIC.
Frameworks
diff --git a/pease-portfolio/src/app/page.js b/pease-portfolio/src/app/page.js
index 1a7ad04..c8b9f20 100644
--- a/pease-portfolio/src/app/page.js
+++ b/pease-portfolio/src/app/page.js
@@ -2,8 +2,16 @@ import Projects from "./projects.json"
import moment from "moment"
import LinkedInIcon from '@mui/icons-material/LinkedIn';
import GitHubIcon from '@mui/icons-material/GitHub';
+import EmailIcon from '@mui/icons-material/Email';
import Link from "next/link"
+export async function generateMetadata() {
+ return {
+ title: 'Home | nicholaspease.com'
+ }
+}
+
+
function AboutMe() {
return (
@@ -14,7 +22,8 @@ function AboutMe() {
About Me
-
+
+
diff --git a/pease-portfolio/src/app/previous_versions/page.js b/pease-portfolio/src/app/previous_versions/page.js
index 66fea40..c9f5774 100644
--- a/pease-portfolio/src/app/previous_versions/page.js
+++ b/pease-portfolio/src/app/previous_versions/page.js
@@ -1,6 +1,13 @@
import PriorVersions from "./versions.json"
import moment from 'moment';
+export async function generateMetadata() {
+ return {
+ title: 'Previous Versions | nicholaspease.com'
+ }
+ }
+
+
function PriorWebsiteVersion({version}) {
var version = PriorVersions[version]
var start = moment(version.start)
diff --git a/pease-portfolio/src/app/projects.json b/pease-portfolio/src/app/projects.json
index acb2d30..dc48726 100644
--- a/pease-portfolio/src/app/projects.json
+++ b/pease-portfolio/src/app/projects.json
@@ -45,19 +45,10 @@
"hasGitea": false,
"hasGithub": true,
"hasCustomPage": "weatherimg",
- "github_user": "LAX18",
+ "github_user": "npease18",
"github_repo": "Satellite-Imagery-Uploads",
"img": "satimg.jpg"
},
- "Personal Portfolio": {
- "description": "My personal portfolio is my first React and next.js project that also serves to showcase my personal projects and other career development accomplishments. This is hosted on my personal server and stands as a lesson in both web development as well as backend design.",
- "gitea_user": "npease",
- "gitea_repo": "portfolio",
- "isPublic": false,
- "hasGitea": true,
- "hasGithub": false,
- "hasCustomPage": false
- },
"Calculator Programming": {
"description": "My first introduction to programming was by way of the Texas Instruments series of calculators. These taught me fundamentals in programming with languages such as TI-BASIC, ICE, and Assembly.",
"gitea_user": "npease",
@@ -65,6 +56,6 @@
"isPublic": false,
"hasGitea": false,
"hasGithub": false,
- "hasCustomPage": false
+ "hasCustomPage": "calc"
}
}
\ No newline at end of file
diff --git a/pease-portfolio/src/app/projects/[slug]/page.js b/pease-portfolio/src/app/projects/[slug]/page.js
index f3d08c3..5f09363 100644
--- a/pease-portfolio/src/app/projects/[slug]/page.js
+++ b/pease-portfolio/src/app/projects/[slug]/page.js
@@ -1,6 +1,19 @@
import Projects from "../../projects.json"
import { redirect } from "next/navigation";
+export async function generateMetadata({params}) {
+ var name = params.slug.replaceAll("%20", " ")
+ if (name in Projects) {
+ return {
+ title: `${name} | nicholaspease.com`
+ }
+ } else {
+ return {
+ title: "Project Does Not Exist | nicholaspease.com"
+ }
+ }
+}
+
function Page({params}) {
var name = params.slug.replaceAll("%20", " ")
if (name in Projects) {
diff --git a/pease-portfolio/src/app/projects/custom/aa1/page.js b/pease-portfolio/src/app/projects/custom/aa1/page.js
index 932164f..4dddae1 100644
--- a/pease-portfolio/src/app/projects/custom/aa1/page.js
+++ b/pease-portfolio/src/app/projects/custom/aa1/page.js
@@ -176,6 +176,7 @@ function ImageCarousel() {
export default function Home() {
return (
diff --git a/pease-portfolio/src/app/projects/custom/aubuchon/page.js b/pease-portfolio/src/app/projects/custom/aubuchon/page.js
index 717e868..a63e7c4 100644
--- a/pease-portfolio/src/app/projects/custom/aubuchon/page.js
+++ b/pease-portfolio/src/app/projects/custom/aubuchon/page.js
@@ -6,16 +6,20 @@ import SearchIcon from '@mui/icons-material/Search';
import SignpostIcon from '@mui/icons-material/Signpost';
import FormatListNumberedIcon from '@mui/icons-material/FormatListNumbered';
import FormatColorFillIcon from '@mui/icons-material/FormatColorFill';
+import { CodeBlock, irBlack } from 'react-code-blocks';
+
+import sheetsTool from './source.js';
import { useState } from 'react';
export default function Page() {
return (
+ Aubuchon Register Tools | nicholaspease.com
-
+
Aubuchon Hardware Additional Register Tools
@@ -30,48 +34,78 @@ export default function Page() {
The Suite of Tools Includes:
+
+ Google Sheets Tool
+ As an additional tool, I have developed a Google Sheets Add-On that allows the user to interface with the Aubuchon Inventory API to query information regarding inventory, product pricing and other information. It can be used to automate a wide variety of spreadsheets including inventory pick lists and many more. A redacted version of this tool is below
+
+
+
+
);
}
function ToolExpander() {
const [tool, setTool] = useState("register")
+ var toolsMobile = []
+ for(var tool1 in tools) {
+ toolsMobile.push(
+
+
+
+ {tools[tool1].icon}
+ {tools[tool1].title}
+
+
+
+
+
{tools[tool1].title}
+ {tools[tool1].description}
+
+
+ )
+ }
return (
-
-
setTool("register")}>
-
- Generate Register Book
-
-
setTool("pallet")}>
-
- Generate Pallet Signs
-
-
setTool("list")}>
-
- Generate List from SKU/UPC
-
}
+
+
+ {toolsMobile}
+
)
@@ -79,30 +113,37 @@ function ToolExpander() {
var tools = {
register: {
+ icon: (),
title: "Generate Register Book",
description: "This tool takes a Microsoft Excel workbook and formats the data in a manner consistent among uses. This allows the store to generate identical books, with minimal duplication of efforts and materials, while optimizing for time. This tools also allows the store to utilize barcode's in the book, without relying on cashiers to type all of the codes by hand.",
},
pallet: {
+ icon: ,
title: "Generate Pallet Signs",
description: "This tool takes a Microsoft Excel workbook and reads through all the user selected categories. It then queries the central Aubuchon Inventory API to assemble individualized pallet signs with most up to date pricing and additional data.",
},
list: {
+ icon: ,
title: "Generate List from SKU/UPC",
description: "This tool takes a bulk list of UPC's / SKUs and queries the Aubuchon Inventory API to assemble a list of items with the most up to date pricing and additional data. This tool is used to generate lists for the store to use in their daily operations. Potential applications involve inventorying, general list-making, and other correspondences.",
},
counter: {
+ icon: ,
title: "SKU Counter",
description: "This tool takes a bulk list of UPC's / SKUs and queries the Aubuchon Inventory API to count the number of items in the list. This tool is used to generate counts for the store to use in their daily operations. Potential applications involve inventorying, cycle counting, box inventorying, and other applications where counting a large number of scannable items is not practical.",
},
sign: {
+ icon: ,
title: "Create-A-Sign 2",
description: "This is a better version of the Aubuchon Hardware 'Create-A-Sign' program. This tool includes options to bulk generate signs, modify the pricing data should it be inaccurate, among other additions.",
},
investigation: {
+ icon: ,
title: "SKU Investigation",
description: "This tool investigates potentially mistyped SKUs for user errors on the POS systems. It then sorts those similar SKUs according to their 'suspiciousness' and allows the user to investigate the potential errors. This tool is best used for negatives and other issue SKUs",
},
colorx: {
+ icon: ,
title: "ColorX Calculator",
description: "This tool is used to calculate the paint differential between two given Benjamin Moore ColorX paint color formulas. It works by converting both formulas into common units, and outputting a simple to dispense formula to turn the old color, into the desired color.",
}
diff --git a/pease-portfolio/src/app/projects/custom/aubuchon/source.js b/pease-portfolio/src/app/projects/custom/aubuchon/source.js
new file mode 100644
index 0000000..28dfb68
--- /dev/null
+++ b/pease-portfolio/src/app/projects/custom/aubuchon/source.js
@@ -0,0 +1,40 @@
+export default `function AUBDATALOOKUP(input, type) {
+ if (input && type) {
+ var url = API_URL;
+ var text = UrlFetchApp.fetch(url).getContentText();
+ var json = JSON.parse(text)
+ switch (type.toLowerCase()) {
+ case "description":
+ return json.product[0].webDesc
+ break;
+ case "qty":
+ return json.product[0].onHandAmt
+ break;
+ case "price":
+ return json.product[0].promoPrice != ""? "*"+json.product[0].promoPrice: json.product[0].retailPrice
+ break;
+ case "location":
+ return json.product[0].section + " S:" + json.product[0].Slot
+ break;
+ case "sku":
+ return json.product[0].sku
+ break;
+ default:
+ for (var UPC in json.Table1) {
+ UPC = json.Table1[UPC]
+ if (UPC.Primary) return UPC.altUPC
+ }
+ break;
+ }
+ } else if (input) {
+ var url = API_URL;
+ var text = UrlFetchApp.fetch(url).getContentText();
+ var json = JSON.parse(text)
+ for (var UPC in json.Table1) {
+ UPC = json.Table1[UPC]
+ if (UPC.Primary) return UPC.altUPC
+ }
+ } else {
+ return "AUBUCHON PRODUCT DATA TOOL\\n[SKU TO LOOKUP], [TYPE OF DATA]\\nVALID TYPES: UPC, DESCRIPTION, QTY, PRICE, LOCATION"
+ }
+}`
\ No newline at end of file
diff --git a/pease-portfolio/src/app/projects/custom/calc/page.js b/pease-portfolio/src/app/projects/custom/calc/page.js
new file mode 100644
index 0000000..64f03fd
--- /dev/null
+++ b/pease-portfolio/src/app/projects/custom/calc/page.js
@@ -0,0 +1,123 @@
+"use client"
+import { SourceCodeExplorer } from '../../../../components/sourcecodeviewer.js';
+
+const PROGRAMS = {
+ 'asteroids': {
+ title: 'Asteroids CE',
+ description: 'This game places you as the operator of a space craft as you attempt to shoot down ALL of the asteroids hurtling towards you. If you miss one, you lose a point. If you hit one, you gain a point.',
+ image: 'https://www.cemetech.net/media/archives/screenshots/2020/04/1691_legacy-0-003596_6Birw4C.gif',
+ link: 'https://www.cemetech.net/downloads/files/1691/x1691',
+ language: 'TI-BASIC (CE Edition)',
+ publishDate: "November 28th, 2017"
+ },
+ 'asteroidsICE': {
+ title: 'Asteroids ICE',
+ description: 'This game places you as the pilot of a spacecraft tasked with the task of destroying incomming asteroids. For every asteroid that you hit you gain a point, for every asteroid that you miss, you lose a point.',
+ image: 'https://www.cemetech.net/media/archives/screenshots/2020/04/1692_legacy-0-003606_SEBbkNC.gif',
+ link: 'https://www.cemetech.net/downloads/files/1692/x1692',
+ language: 'TI 84 ICE',
+ publishDate: "December 4th, 2017"
+ },
+ 'taxfind2017': {
+ title: 'Taxfind 2017 CE',
+ description: 'This program calculates a user-selectable applied tax on the input amount.',
+ image: 'https://www.cemetech.net/media/archives/screenshots/2020/04/1701_legacy-0-003605_F5fGRs7.gif',
+ link: 'https://www.cemetech.net/downloads/files/1701/x1701',
+ language: 'TI-BASIC (CE Edition)',
+ publishDate: "December 5th, 2017"
+ },
+ 'stocksim': {
+ title: 'StockSim',
+ description: 'StockSim is a simulation game based on the American stock market. Players can buy and sell stocks while monitoring several charts. Players have to determine the best times to sell, whilst monitoring best times to buy other stocks. Players can select from EASY and HARD modes and can save/continue their games.',
+ image: 'https://www.cemetech.net/media/archives/screenshots/2020/04/1759_legacy-0-003810_51kJ9KB.gif',
+ link: 'https://www.cemetech.net/downloads/files/1759/x1759',
+ language: 'TI 84 ICE',
+ publishDate: "May 5th, 2018"
+ },
+ 'fakecalc': {
+ title: 'Fake Calc',
+ description: 'This is a program that makes the calculator display incorrect results for calculations inputted. Use this to prank your friends. I do not take responsibility for those who abuse this and mess up others tests.',
+ image: 'https://www.cemetech.net/media/archives/screenshots/2020/04/1833_legacy-0-004048_LB5ngyI.gif',
+ link: 'https://www.cemetech.net/downloads/files/1833/x1833',
+ language: 'TI-BASIC (83+ Edition)',
+ publishDate: "January 9th, 2019"
+ }
+}
+
+const calcFiles = {
+ "Asteroids CE": {
+ title: 'Asteroids CE',
+ files: ['ASTROID3','ASHINST']
+ },
+ "Asteroids ICE": {
+ title: 'Asteroids ICE',
+ files: ['ASTEROID','ASTINST']
+ },
+}
+
+const NOS = {
+ title: 'NOS (Nick Operating System)',
+ description: "NOS (or Nick's Operational Shell) will be a simple shell with a GUI similar to the Kindle Fire Home Screen. To scroll through the programs, you use the left and right keys. Possible features would be pinning programs to the beginning of the carousel and using the A-Z keys to navigate similarly to Cesium.",
+ image: '/images/NOS.png',
+ link: 'https://github.com/npease18/NOS',
+ language: 'TI 84 ICE',
+ publishDate: "Unpublished"
+}
+
+
+function Program({program}) {
+ return (
+
+ )
+}
+
+function Programs() {
+ var arr = []
+ for (const program in PROGRAMS) {
+ arr.push()
+ }
+ return arr
+}
+
+
+
+export default function Home() {
+ return (
+
+ Calculator Programming | nicholaspease.com
+
+
+
+ Calculator Programming
+ Calculator programming is where I got my initial start in software development and taught me the fundamentals of programming. I started with a TI-83+ calculator that I purchased from a thrift store. Below you can find many of the software programs I have written for the TI series of calculators. While I was developing programs for the TI series of calculators starting around 2014, I did not publish them online until around 2018, where I found the online community Cemetech. Below are some of the published products I produced.
+
+
+
+
+
+
+ Below are some unfinished projects that I have worked on. These were never published but may have had some beta programs released.
+
+
+
+
+ {/*
+ Source Code
+ Please use the below source code viewer to examine the source code of the programs above. The source code is written in raw file formats for transfer to the calculators, and requires a premade viewer here.
+
+ */}
+
+
)
+}
diff --git a/pease-portfolio/src/app/projects/custom/chatmaps/page.js b/pease-portfolio/src/app/projects/custom/chatmaps/page.js
index d049676..22ec71e 100644
--- a/pease-portfolio/src/app/projects/custom/chatmaps/page.js
+++ b/pease-portfolio/src/app/projects/custom/chatmaps/page.js
@@ -216,6 +216,7 @@ function ImageCarousel() {
export default function Home() {
return (
+ ChatMaps | nicholaspease.com
diff --git a/pease-portfolio/src/app/projects/custom/weatherimg/page.js b/pease-portfolio/src/app/projects/custom/weatherimg/page.js
index 6f3f17f..d3a610a 100644
--- a/pease-portfolio/src/app/projects/custom/weatherimg/page.js
+++ b/pease-portfolio/src/app/projects/custom/weatherimg/page.js
@@ -2,7 +2,6 @@
import { Gallery, Item } from 'react-photoswipe-gallery'
import 'photoswipe/dist/photoswipe.css'
-
export default function Page() {
var NOAAComposite = [
{
@@ -177,6 +176,7 @@ export default function Page() {
return (
+ Weather Satellite Imagery | nicholaspease.com
Weather Satellite Imagery Capture and Processing
During March to May of 2020, I spent extensive time learning to receive and process various types of VHF satellite imagery provided by a handful of government satellites. Primarily, imagery can be download via two series of satellites, NOAA and Roscosmos "Meteor" satellites. Both transmit in the VHF frequency band, with NOAA transmitting via automated picture transmission (APT) format, and Meteor transmitting via low-resolution picture transmission (LRPT) format. The images are received via a VHF antenna, and decoded using a software-defined radio (SDR) and a decoding software. The images are then processed using a variety of software tools to enhance the image quality and remove noise. The images are then composited together to create a full image of the Earth. The images are then used to monitor weather patterns and storm systems.
diff --git a/pease-portfolio/src/app/projects/page.js b/pease-portfolio/src/app/projects/page.js
index 2143da4..76a1324 100644
--- a/pease-portfolio/src/app/projects/page.js
+++ b/pease-portfolio/src/app/projects/page.js
@@ -2,6 +2,12 @@ import Image from "next/image"
import ProjectsListJSON from "../projects.json"
+export async function generateMetadata() {
+ return {
+ title: 'Projects | nicholaspease.com'
+ }
+}
+
function ProjectHeader() {
return (
diff --git a/pease-portfolio/src/components/sourcecodeviewer.js b/pease-portfolio/src/components/sourcecodeviewer.js
new file mode 100644
index 0000000..e603638
--- /dev/null
+++ b/pease-portfolio/src/components/sourcecodeviewer.js
@@ -0,0 +1,27 @@
+import { CodeBlock, dracula } from 'react-code-blocks';
+import {useState} from 'react'
+
+export function SourceCodeExplorer({data}) {
+ const [tab, setTab] = useState('Asteroids CE')
+
+ var TABS = []
+ for (const file in data) {
+ TABS.push( {setTab(a)}}/>)
+ }
+ return (
+