added toggleable state to the skill cards. technically mobile works, at least on mobile-like sized browsers. it doesn't work on mobile. freakin weird.
This commit is contained in:
+5
-2
@@ -1,7 +1,11 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta
|
||||||
|
charset="UTF-8"
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1.0"
|
||||||
|
/>
|
||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
@@ -12,7 +16,6 @@
|
|||||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Josh Ashton</title>
|
<title>Josh Ashton</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Generated
+196
-1
@@ -18,7 +18,8 @@
|
|||||||
"swiper": "^10.0.0"
|
"swiper": "^10.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite": "^4.0.4"
|
"vite": "^4.0.4",
|
||||||
|
"vite-plugin-terminal": "^1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@esbuild/android-arm": {
|
"node_modules/@esbuild/android-arm": {
|
||||||
@@ -453,6 +454,73 @@
|
|||||||
"react": ">=16.3"
|
"react": ">=16.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@polka/url": {
|
||||||
|
"version": "1.0.0-next.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
|
||||||
|
"integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/plugin-strip": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-strip/-/plugin-strip-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-LDRV49ZaavxUo2YoKKMQjCxzCxugu1rCPQa0lDYBOWLj6vtzBMr8DcoJjsmg+s450RbKbe3qI9ZLaSO+O1oNbg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^5.0.1",
|
||||||
|
"estree-walker": "^2.0.2",
|
||||||
|
"magic-string": "^0.30.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/pluginutils": {
|
||||||
|
"version": "5.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
|
||||||
|
"integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/estree": "^1.0.0",
|
||||||
|
"estree-walker": "^2.0.2",
|
||||||
|
"picomatch": "^4.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"rollup": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/estree": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@zeit/schemas": {
|
"node_modules/@zeit/schemas": {
|
||||||
"version": "2.36.0",
|
"version": "2.36.0",
|
||||||
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz",
|
"resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz",
|
||||||
@@ -879,6 +947,13 @@
|
|||||||
"@esbuild/win32-x64": "0.18.20"
|
"@esbuild/win32-x64": "0.18.20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/estree-walker": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/execa": {
|
"node_modules/execa": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||||
@@ -1037,6 +1112,13 @@
|
|||||||
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/kolorist": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/loose-envify": {
|
"node_modules/loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
@@ -1049,6 +1131,16 @@
|
|||||||
"loose-envify": "cli.js"
|
"loose-envify": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/magic-string": {
|
||||||
|
"version": "0.30.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
|
||||||
|
"integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/merge-stream": {
|
"node_modules/merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
@@ -1115,6 +1207,16 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mrmime": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@@ -1222,6 +1324,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.49",
|
"version": "8.4.49",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
|
||||||
@@ -1477,6 +1592,21 @@
|
|||||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/sirv": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@polka/url": "^1.0.0-next.24",
|
||||||
|
"mrmime": "^2.0.0",
|
||||||
|
"totalist": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
@@ -1568,6 +1698,16 @@
|
|||||||
"node": ">= 4.7.0"
|
"node": ">= 4.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/totalist": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "2.19.0",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
@@ -1580,6 +1720,13 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ufo": {
|
||||||
|
"version": "1.5.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
|
||||||
|
"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/update-check": {
|
"node_modules/update-check": {
|
||||||
"version": "1.5.4",
|
"version": "1.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz",
|
||||||
@@ -1664,6 +1811,54 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vite-plugin-terminal": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vite-plugin-terminal/-/vite-plugin-terminal-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-IIw1V+IySth8xlrGmH4U7YmfTp681vTzYpa7b8A3KNCJ2oW1BGPPwW8tSz6BQTvSgbRmrP/9NsBLsfXkN4e8sA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/plugin-strip": "^3.0.2",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"kolorist": "^1.7.0",
|
||||||
|
"sirv": "^2.0.2",
|
||||||
|
"ufo": "^1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/patak-dev"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vite": "^2.0.0||^3.0.0||^4.0.0||^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vite-plugin-terminal/node_modules/debug": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vite-plugin-terminal/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|||||||
+2
-1
@@ -10,7 +10,8 @@
|
|||||||
"swiper": "^10.0.0"
|
"swiper": "^10.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite": "^4.0.4"
|
"vite": "^4.0.4",
|
||||||
|
"vite-plugin-terminal": "^1.2.0"
|
||||||
},
|
},
|
||||||
"name": "portfolio",
|
"name": "portfolio",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
|||||||
+12
-7
@@ -1,12 +1,9 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import VerticalSlider from "./components/VerticalSlider";
|
import VerticalSlider from "./components/VerticalSlider";
|
||||||
import Primary from "./Primary";
|
import Primary from "./Primary";
|
||||||
import Skills from "./Skills";
|
|
||||||
import Projects from "./Projects";
|
import Projects from "./Projects";
|
||||||
import Contact from "./Contact";
|
|
||||||
import About from "./About";
|
|
||||||
import ProjectCard from "./components/ProjectCard";
|
|
||||||
import "./main.css";
|
import "./main.css";
|
||||||
|
import { terminal } from "virtual:terminal";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Read in data from a plain text file for easier editing in the future.
|
* TODO: Read in data from a plain text file for easier editing in the future.
|
||||||
@@ -16,12 +13,19 @@ export default function App() {
|
|||||||
const [isMobile, setIsMobile] = useState(window.innerWidth <= 790);
|
const [isMobile, setIsMobile] = useState(window.innerWidth <= 790);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleResize = () => setIsMobile(window.innerWidth <= 790);
|
const handleResize = () => {
|
||||||
|
const mediaQuery = window.matchMedia("(max-width: 790px)");
|
||||||
|
setIsMobile(mediaQuery.matches);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleResize(); // Initial check on mount
|
||||||
window.addEventListener("resize", handleResize);
|
window.addEventListener("resize", handleResize);
|
||||||
|
|
||||||
return () => window.removeEventListener("resize", handleResize);
|
return () => window.removeEventListener("resize", handleResize);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const initState = isMobile ? [true, false, false] : [true, true, true];
|
const initState = isMobile ? [true, false, false] : [true, true, true];
|
||||||
|
terminal.log("isMobile: " + isMobile);
|
||||||
|
|
||||||
// DATA VARIABLES
|
// DATA VARIABLES
|
||||||
/*
|
/*
|
||||||
@@ -37,7 +41,7 @@ export default function App() {
|
|||||||
{
|
{
|
||||||
title: "One AI",
|
title: "One AI",
|
||||||
descriptionA:
|
descriptionA:
|
||||||
"An end-to-end self-hosted Artificial Intelligence solution, using Meta's Ollama platform to run Large Language Models. Go was used for the backend as a wrapper API and the frontend is Flutter for its write once, build anywhere ideology. Here are some of the implemented features:",
|
"An end-to-end self-hosted Artificial Intelligence solution, using Meta's Ollama platform to run Large Language Models. Go was used for the backend as a wrapper API and the frontend is Flutter. Here are some of the implemented features:",
|
||||||
featureList: [
|
featureList: [
|
||||||
"user authentication",
|
"user authentication",
|
||||||
"AES encryption",
|
"AES encryption",
|
||||||
@@ -97,5 +101,6 @@ export default function App() {
|
|||||||
/>,
|
/>,
|
||||||
<Projects cardData={projectData} />,
|
<Projects cardData={projectData} />,
|
||||||
];
|
];
|
||||||
|
|
||||||
return <VerticalSlider slides={slides} />;
|
return <VerticalSlider slides={slides} />;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-1
@@ -1,6 +1,7 @@
|
|||||||
// TODO: Replace h4 callToAction with a GREEN button callToAction.
|
// TODO: Replace h4 callToAction with a GREEN button callToAction.
|
||||||
import React, { useState } from "react";
|
import React, { useState, useRef } from "react";
|
||||||
import SkillCard from "./components/SkillCard";
|
import SkillCard from "./components/SkillCard";
|
||||||
|
import { terminal } from "virtual:terminal";
|
||||||
|
|
||||||
export default function Primary({
|
export default function Primary({
|
||||||
primaryText,
|
primaryText,
|
||||||
@@ -10,6 +11,7 @@ export default function Primary({
|
|||||||
skills,
|
skills,
|
||||||
initState,
|
initState,
|
||||||
}) {
|
}) {
|
||||||
|
const [activeCardIndex, setActiveCardIndex] = useState(null);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div id="primary">
|
<div id="primary">
|
||||||
@@ -30,18 +32,27 @@ export default function Primary({
|
|||||||
symbol="code"
|
symbol="code"
|
||||||
list={skills.languages}
|
list={skills.languages}
|
||||||
initState={initState[0]}
|
initState={initState[0]}
|
||||||
|
index={0}
|
||||||
|
isActive={activeCardIndex === 0}
|
||||||
|
onToggle={() => setActiveCardIndex(0)}
|
||||||
/>
|
/>
|
||||||
<SkillCard
|
<SkillCard
|
||||||
header="Tools"
|
header="Tools"
|
||||||
symbol="terminal"
|
symbol="terminal"
|
||||||
list={skills.tools}
|
list={skills.tools}
|
||||||
initState={initState[1]}
|
initState={initState[1]}
|
||||||
|
index={1}
|
||||||
|
isActive={activeCardIndex === 1}
|
||||||
|
onToggle={() => setActiveCardIndex(1)}
|
||||||
/>
|
/>
|
||||||
<SkillCard
|
<SkillCard
|
||||||
header="Other"
|
header="Other"
|
||||||
symbol="hub"
|
symbol="hub"
|
||||||
list={skills.other}
|
list={skills.other}
|
||||||
initState={initState[2]}
|
initState={initState[2]}
|
||||||
|
index={2}
|
||||||
|
isActive={activeCardIndex === 2}
|
||||||
|
onToggle={() => setActiveCardIndex(2)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ export default function ProjectCard({
|
|||||||
<h3>{title}</h3>
|
<h3>{title}</h3>
|
||||||
<p>{descriptionA}</p>
|
<p>{descriptionA}</p>
|
||||||
<ul className="feature-list">
|
<ul className="feature-list">
|
||||||
{featureList.map((item) => (
|
{featureList.map((item, index) => (
|
||||||
<li>{item}</li>
|
<li key={index}>{item}</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
|||||||
@@ -2,26 +2,29 @@ import React, { useState } from "react";
|
|||||||
|
|
||||||
// TODO: Add state which only allows one skill card at a time to be expanded.
|
// TODO: Add state which only allows one skill card at a time to be expanded.
|
||||||
// TODO: Ensure that the expandability of the skill card is only an option when @media max-width 790px (mobile)
|
// TODO: Ensure that the expandability of the skill card is only an option when @media max-width 790px (mobile)
|
||||||
export default function SkillCard({ header, symbol, list, initState }) {
|
const SkillCard = ({ header, symbol, list, initState, isActive, onToggle }) => {
|
||||||
const [isExpanded, setIsExpanded] = useState(initState); // Initial state
|
const [isExpanded, setIsExpanded] = useState(initState || isActive);
|
||||||
|
|
||||||
const toggleExpansion = () => {
|
const toggleExpansion = () => {
|
||||||
setIsExpanded(!isExpanded);
|
setIsExpanded(!isExpanded);
|
||||||
|
onToggle();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card shadow">
|
<div className={`card shadow ${isActive ? "active-skill-card" : ""}`}>
|
||||||
<div className="skill-section-header" onClick={toggleExpansion}>
|
<div className="skill-section-header" onClick={() => toggleExpansion()}>
|
||||||
<span className="material-icons skill-symbol">{symbol}</span>
|
<span className="material-icons skill-symbol">{symbol}</span>
|
||||||
<h3>{header}</h3>
|
<h3>{header}</h3>
|
||||||
</div>
|
</div>
|
||||||
{isExpanded && (
|
{isActive && (
|
||||||
<ul>
|
<ul>
|
||||||
{list.map((item) => (
|
{list.map((item, index) => (
|
||||||
<li>{item}</li>
|
<li key={index}>{item}</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default SkillCard;
|
||||||
|
|||||||
+10
-1
@@ -446,7 +446,7 @@ h4 {
|
|||||||
@media (max-width: 790px) {
|
@media (max-width: 790px) {
|
||||||
#primary {
|
#primary {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: 50% 40% 10%;
|
grid-template-rows: 40% 40% 10%;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,6 +513,11 @@ h4 {
|
|||||||
font-size: 10vw;
|
font-size: 10vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#project-grid-container {
|
||||||
|
height: 90vh;
|
||||||
|
grid-template-rows: 10% 80%;
|
||||||
|
}
|
||||||
|
|
||||||
.project-card {
|
.project-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 100%;
|
grid-template-columns: 100%;
|
||||||
@@ -528,6 +533,10 @@ h4 {
|
|||||||
padding: 2vw;
|
padding: 2vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project-text-column {
|
||||||
|
margin-left: 5vw;
|
||||||
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import Terminal from "vite-plugin-terminal";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
plugins: [Terminal()],
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user