-
+
+
+
- Portfolio
+
+
+
+
+
+
+
+
+
+ Oscar's Portfolio
+
+
+
+
+
+
+
-
+
+
+
diff --git a/package.json b/package.json
index 48911600..8cd0337f 100644
--- a/package.json
+++ b/package.json
@@ -7,21 +7,46 @@
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
- "preview": "vite preview"
+ "preview": "vite preview",
+ "test": "vitest"
},
"dependencies": {
+ "@tailwindcss/postcss": "^4.1.4",
+ "@versoly/react-taos": "^0.1.0",
+ "aos": "^3.0.0-beta.6",
"react": "^19.0.0",
- "react-dom": "^19.0.0"
+ "react-dom": "^19.0.0",
+ "styled-components": "^6.1.17",
+ "taos": "^1.0.5"
},
"devDependencies": {
- "@eslint/js": "^9.21.0",
+ "@babel/core": "^7.26.10",
+ "@babel/preset-env": "^7.26.9",
+ "@babel/preset-react": "^7.26.3",
+ "@eslint/js": "^9.25.1",
+ "@testing-library/jest-dom": "^6.6.3",
+ "@testing-library/react": "^16.3.0",
+ "@testing-library/user-event": "^14.6.1",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
- "@vitejs/plugin-react": "^4.3.4",
- "eslint": "^9.21.0",
+ "@vitejs/plugin-react": "^4.4.0",
+ "autoprefixer": "^10.4.21",
+ "babel-jest": "^29.7.0",
+ "babel-plugin-styled-components": "^2.1.4",
+ "eslint": "^9.25.1",
+ "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^15.15.0",
- "vite": "^6.2.0"
+ "identity-obj-proxy": "^3.0.0",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "jsdom": "^26.1.0",
+ "postcss": "^8.5.3",
+ "react-test-renderer": "^19.1.0",
+ "tailwindcss": "^3.4.17",
+ "tailwindcss-motion": "^1.1.0",
+ "vite": "^6.2.0",
+ "vitest": "^3.1.2"
}
}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 00000000..e5ce722e
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,8 @@
+import { TAOS } from "@versoly/react-taos";
+
+export default {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+};
diff --git a/public/article-acces.avif b/public/article-acces.avif
new file mode 100644
index 00000000..7121f61b
Binary files /dev/null and b/public/article-acces.avif differ
diff --git a/public/article-api.avif b/public/article-api.avif
new file mode 100644
index 00000000..41a458f1
Binary files /dev/null and b/public/article-api.avif differ
diff --git a/public/article-first.avif b/public/article-first.avif
new file mode 100644
index 00000000..ec8090b2
Binary files /dev/null and b/public/article-first.avif differ
diff --git a/public/article-movie.avif b/public/article-movie.avif
new file mode 100644
index 00000000..63a7ddeb
Binary files /dev/null and b/public/article-movie.avif differ
diff --git a/public/article-portfolio.avif b/public/article-portfolio.avif
new file mode 100644
index 00000000..a6c56c8b
Binary files /dev/null and b/public/article-portfolio.avif differ
diff --git a/public/article-recipe.avif b/public/article-recipe.avif
new file mode 100644
index 00000000..f4130bea
Binary files /dev/null and b/public/article-recipe.avif differ
diff --git a/public/article-todo.avif b/public/article-todo.avif
new file mode 100644
index 00000000..1452423b
Binary files /dev/null and b/public/article-todo.avif differ
diff --git a/public/article-weather.avif b/public/article-weather.avif
new file mode 100644
index 00000000..460c930b
Binary files /dev/null and b/public/article-weather.avif differ
diff --git a/public/happy_thoughts.avif b/public/happy_thoughts.avif
new file mode 100644
index 00000000..6143313a
Binary files /dev/null and b/public/happy_thoughts.avif differ
diff --git a/public/icon.svg b/public/icon.svg
new file mode 100644
index 00000000..cecc781a
--- /dev/null
+++ b/public/icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/meta-og-img.avif b/public/meta-og-img.avif
new file mode 100644
index 00000000..d8d126ef
Binary files /dev/null and b/public/meta-og-img.avif differ
diff --git a/public/vite.svg b/public/vite.svg
deleted file mode 100644
index e7b8dfb1..00000000
--- a/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/pull_request_template.md b/pull_request_template.md
index 4263c7e8..6f5a50fc 100644
--- a/pull_request_template.md
+++ b/pull_request_template.md
@@ -1 +1,5 @@
-Please include a link to your Figma design and a Netlify link.
\ No newline at end of file
+Please include a link to your Figma design and a Netlify link.
+
+# www.figma.com/board/PymjF0tI8PYjLJ45Ud1Ai9/Water-🌊?node-id=0-1&p=f&t=fyWZXSjCKeiorHlN-0
+
+# https://oscars-js-portfolio.netlify.app
diff --git a/src/App.css b/src/App.css
new file mode 100644
index 00000000..311f8e9b
--- /dev/null
+++ b/src/App.css
@@ -0,0 +1,5 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+/*This is required to activate tailwind*/
diff --git a/src/App.jsx b/src/App.jsx
index a161d8d3..5fbed51a 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,8 +1,28 @@
+import React from "react";
+
+import { FeaturedProjects } from "./sections/FeaturedProjects";
+import { HiThere } from "./sections/HiThere";
+import { LetsTalk } from "./sections/LetsTalk";
+import { MyWords } from "./sections/MyWords";
+import { Skills } from "./sections/Skills";
+import { Tech } from "./sections/Tech";
+import { GlobalStyle } from "./GlobalStyle";
+
export const App = () => {
return (
<>
-
Portfolio
-
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem, laborum! Maxime animi nostrum facilis distinctio neque labore consectetur beatae eum ipsum excepturi voluptatum, dicta repellendus incidunt fugiat, consequatur rem aperiam.
+
+
+
+
+
+
+
>
- )
-}
+ );
+};
+
+//App is our main hub for all section and components. the "sandwich"
+
+//add tests
+//add accessibility and aria-labels
diff --git a/src/App.test.jsx b/src/App.test.jsx
new file mode 100644
index 00000000..151a8853
--- /dev/null
+++ b/src/App.test.jsx
@@ -0,0 +1,19 @@
+import { render, screen } from "@testing-library/react";
+import { App } from "./App";
+
+/*
+describe("A truthy statement", () => {
+ it("should be equal to 2", () => {
+ expect(1 + 1).toEqual(2);
+ });
+});
+test
+*/
+
+describe("App", () => {
+ it("renders the App component", () => {
+ render();
+
+ screen.debug(); // prints out the jsx in the App component unto the command line
+ });
+});
diff --git a/src/Breakpoints.js b/src/Breakpoints.js
new file mode 100644
index 00000000..7754ea6a
--- /dev/null
+++ b/src/Breakpoints.js
@@ -0,0 +1,12 @@
+export const media = {
+ mobile: "(min-width: 768px)",
+ tablet: "(min-width: 1024px)",
+ smalldesktop: "(min-width: 1280px)",
+ desktop: "(min-width: 1536px)",
+};
+
+//sm = 640px
+//mobile = 768px = md
+//tablet = 1024px = lg
+//smalldesktop = 1280px = xl
+//desktop = 1536px = 2xl
diff --git a/src/GlobalStyle.jsx b/src/GlobalStyle.jsx
new file mode 100644
index 00000000..fdfd2614
--- /dev/null
+++ b/src/GlobalStyle.jsx
@@ -0,0 +1,66 @@
+import { createGlobalStyle } from "styled-components";
+
+import { media } from "./Breakpoints";
+
+export const GlobalStyle = createGlobalStyle`
+ * {
+ font-family: "Poppins", sans-serif;
+ font-style: normal;
+ line-height: normal;
+ color: #000000;
+ }
+
+ :focus-visible {
+ outline: 4px solid yellow;
+ outline-offset: 2px;
+ border-radius: 2px;
+ }
+
+ body {
+ margin: 0;
+ padding: 0;
+ }
+
+ #root {
+ width: 100%;
+ }
+
+
+ h1 {
+ font-size: 52px;
+ font-weight: 700;
+ }
+
+ h2 {
+ font-size: 48px;
+ font-weight: 700;
+ }
+
+ h3 {
+ font-size: 24px;
+ font-weight: 500;
+ }
+
+ li {
+ font-size: 16px;
+ font-weight: 400;
+ list-style-type: none;
+ }
+
+ @media ${media.smalldesktop} {
+ h1 {
+ font-size: 100px;
+ font-weight: 700;
+ }
+
+ h2 {
+ font-size: 80px;
+ font-weight: 700;
+ }
+
+ h3 {
+ font-size: 30px;
+ font-weight: 500;
+ }
+ }
+`;
diff --git a/src/assets/Btn-instagram.svg b/src/assets/Btn-instagram.svg
new file mode 100644
index 00000000..512ca9f9
--- /dev/null
+++ b/src/assets/Btn-instagram.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/Btn-linkedin.svg b/src/assets/Btn-linkedin.svg
new file mode 100644
index 00000000..7748cd68
--- /dev/null
+++ b/src/assets/Btn-linkedin.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/Btn-stackoverflow.svg b/src/assets/Btn-stackoverflow.svg
new file mode 100644
index 00000000..912255d9
--- /dev/null
+++ b/src/assets/Btn-stackoverflow.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/Ic-ArrowDown.svg b/src/assets/Ic-ArrowDown.svg
new file mode 100644
index 00000000..5febcfa6
--- /dev/null
+++ b/src/assets/Ic-ArrowDown.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/Ic-Github.svg b/src/assets/Ic-Github.svg
new file mode 100644
index 00000000..cc43e6d8
--- /dev/null
+++ b/src/assets/Ic-Github.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/Ic-Github_on-white.svg b/src/assets/Ic-Github_on-white.svg
new file mode 100644
index 00000000..06c6fed1
--- /dev/null
+++ b/src/assets/Ic-Github_on-white.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/Ic-Web.svg b/src/assets/Ic-Web.svg
new file mode 100644
index 00000000..cecc781a
--- /dev/null
+++ b/src/assets/Ic-Web.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/Ic-Web_on-white.svg b/src/assets/Ic-Web_on-white.svg
new file mode 100644
index 00000000..52b2fdf1
--- /dev/null
+++ b/src/assets/Ic-Web_on-white.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/cropped_profile.avif b/src/assets/cropped_profile.avif
new file mode 100644
index 00000000..e52f6795
Binary files /dev/null and b/src/assets/cropped_profile.avif differ
diff --git a/src/data/mywords.json b/src/data/mywords.json
new file mode 100644
index 00000000..fb6b6eae
--- /dev/null
+++ b/src/data/mywords.json
@@ -0,0 +1,36 @@
+{
+ "articles": [
+ {
+ "title": "Placeholder",
+ "image": "https://images.unsplash.com/photo-1635745694780-767722ca4007?q=80&w=2071&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ "desc": "Placeholder",
+ "date": "Placeholder",
+ "link": "Placeholder",
+ "id": "mw-1"
+ },
+ {
+ "title": "Placeholder",
+ "image": "https://images.unsplash.com/photo-1635745694780-767722ca4007?q=80&w=2071&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ "desc": "Placeholder",
+ "date": "Placeholder",
+ "link": "Placeholder",
+ "id": "mw-2"
+ },
+ {
+ "title": "Placeholder",
+ "image": "https://images.unsplash.com/photo-1635745694780-767722ca4007?q=80&w=2071&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ "desc": "Placeholder",
+ "date": "Placeholder",
+ "link": "Placeholder",
+ "id": "mw-3"
+ },
+ {
+ "title": "Placeholder",
+ "image": "https://images.unsplash.com/photo-1635745694780-767722ca4007?q=80&w=2071&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
+ "desc": "Placeholder",
+ "date": "Placeholder",
+ "link": "Placeholder",
+ "id": "mw-4"
+ }
+ ]
+}
diff --git a/src/data/projects.json b/src/data/projects.json
index 7c426028..8e560dcd 100644
--- a/src/data/projects.json
+++ b/src/data/projects.json
@@ -1,28 +1,93 @@
{
"projects": [
{
- "name": "Business site",
- "image": "https://images.unsplash.com/photo-1557008075-7f2c5efa4cfd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2497&q=80",
- "tags": [
- "HTML5",
- "CSS3",
- "JavaScript"
- ],
- "netlify": "link",
- "github": "link"
+ "name": "Happy Thoughts",
+ "image": "/happy_thoughts.avif",
+ "desc": "Happy Thoughts is a full-stack web app where users can share and like short, uplifting messages. It features user authentication, real-time updates, and a clean, responsive interface styled with Tailwind CSS.",
+ "tags": ["HTML5", "CSS3", "JavaScript", "React.js", "API", "TailwindCSS"],
+ "netlify": "https://js-project-happy-thoughts.netlify.app",
+ "github": "https://github.com/osckli990/js-project-happy-thoughts",
+ "id": "p-1"
},
{
- "name": "Weather app",
- "image": "https://images.unsplash.com/photo-1520792532857-293bd046307a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2370&q=80",
+ "name": "API Project",
+ "image": "/article-api.avif",
+ "desc": "A RESTful API built with Express.js, allowing users to perform CRUD operations on a MongoDB database. It includes user authentication and validation using Mongoose. Connected to the Happy Thoughts project.",
+ "tags": ["Express.js", "MongoDB", "Mongoose", "JavaScript", "API"],
+ "netlify": "",
+ "github": "https://github.com/Technigo/js-project-api",
+ "id": "p-1_25"
+ },
+ {
+ "name": "Todo webbapp",
+ "image": "/article-todo.avif",
+ "desc": "A simple todo application built with React, allowing users to add, remove, and edit tasks. A deepdive into global state management using Zustand, a small and fast state management library for react",
+ "tags": ["HTML5", "CSS3", "JavaScript", "React.js", "API", "Zustand"],
+ "netlify": "https://oscar-todo.netlify.app/",
+ "github": "https://github.com/osckli990/js-project-todo",
+ "id": "p-1_5"
+ },
+ {
+ "name": "Portfolio",
+ "image": "/article-portfolio.avif",
+ "desc": "The portfolio you are currently looking at! Made through JSON, such as this text, and JavaScript and React to handle components and states. Monitored with a the testing framework Vitest",
"tags": [
"HTML5",
"CSS3",
"JavaScript",
- "TypeScript",
- "APIs"
+ "React.js",
+ "JSON",
+ "Vitest",
+ "TailwindCSS"
],
- "netlify": "link",
- "github": "link"
+ "netlify": "https://oscars-js-portfolio.netlify.app",
+ "github": "https://github.com/osckli990/js-project-portfolio",
+ "id": "p-2"
+ },
+ {
+ "name": "Recipe library",
+ "image": "/article-recipe.avif",
+ "desc": "Using Spoonacular's complex-search API to gather specific recipes, then using JavaScript to sort through different alternatives, independently and together. Inlcludes pagination/infinite scrolling (well, until the api's daily limit)",
+ "tags": ["HTML5", "CSS3", "JavaScript", "API"],
+ "netlify": "https://js-project-recipe-library.netlify.app",
+ "github": "https://github.com/osckli990/js-project-recipe-library",
+ "id": "p-3"
+ },
+ {
+ "name": "Weather app",
+ "image": "/article-weather.avif",
+ "desc": "A mob-programming project and weather application that enables the user to retrieve weather information from any city, inlucing general location-tracking, through OpenWeather's API",
+ "tags": ["HTML5", "CSS3", "JavaScript", "TypeScript", "API"],
+ "netlify": "https://watherrr.netlify.app",
+ "github": "https://github.com/alex91-html/js-project-weather-app",
+ "id": "p-4"
+ },
+ {
+ "name": "Accessibility site",
+ "image": "/article-acces.avif",
+ "desc": "Another project done in mob-programming. The site has a rudementary design but follows different guidelines to allow accessibility for different disabilities or conditions",
+ "tags": ["HTML5", "CSS3", "JavaScript", "WCAG", "W3C", "WAI"],
+ "netlify": "https://js-project-accessibility.netlify.app",
+ "github": "https://github.com/osckli990/js-project-accessibility",
+ "id": "p-5"
+ },
+ {
+ "name": "Movie site",
+ "image": "/article-movie.avif",
+ "desc": "Multi-page movie site with a simple design, using React and API to fetch data from The Movie Database (TMDB). Includes a search function and pagination.",
+ "tags": ["HTML5", "CSS3", "JavaScript", "React.js", "API"],
+ "netlify": "https://js-movie-react-oscar.netlify.app",
+ "github": "https://github.com/osckli990/js-project-movies",
+ "id": "p-7"
+ },
+ {
+ "name": "First project",
+ "image": "/article-first.avif",
+ "desc": "My first web project! A front-end project with an introduction to design, while utilizing a form with simple validation and site functions, like a dark-mode",
+ "tags": ["HTML5", "CSS3", "JavaScript"],
+ "netlify": "https://js-project-business-site.netlify.app",
+ "github": "https://github.com/osckli990/js-project-business-site",
+ "id": "p-8"
}
]
-}
\ No newline at end of file
+}
diff --git a/src/data/skills.json b/src/data/skills.json
new file mode 100644
index 00000000..d5cdadeb
--- /dev/null
+++ b/src/data/skills.json
@@ -0,0 +1,37 @@
+{
+ "skills": [
+ {
+ "names": [
+ "HTML5",
+ "CSS3",
+ "Javascript ES6",
+ "React",
+ "API's",
+ "Styled Components",
+ "Github"
+ ],
+ "title": "Code",
+ "id": "s-1"
+ },
+ {
+ "names": ["Figma", "Slack"],
+ "title": "Toolbox",
+ "id": "s-2"
+ },
+ {
+ "names": ["React Native"],
+ "title": "Upcoming",
+ "id": "s-3"
+ },
+ {
+ "names": [
+ "Agile Methodology",
+ "Development",
+ "Analysis",
+ "Problem solving"
+ ],
+ "title": "More",
+ "id": "s-4"
+ }
+ ]
+}
diff --git a/src/data/tech.json b/src/data/tech.json
new file mode 100644
index 00000000..65675e1a
--- /dev/null
+++ b/src/data/tech.json
@@ -0,0 +1,24 @@
+{
+ "tech": [
+ {
+ "names": ["HTML", "CSS", "Flexbox", "Web Accessibility"],
+ "title": "Basic",
+ "id": "t-1"
+ },
+ {
+ "names": ["Javascript", "JSX", "Node.js", "Mongo DB", "API's"],
+ "title": "Backend",
+ "id": "t-2"
+ },
+ {
+ "names": ["JavaScript", "React", "React Hooks"],
+ "title": "Frontend",
+ "id": "t-3"
+ },
+ {
+ "names": ["Mob-programming", "Pair-programming", "Github", "Git"],
+ "title": "Methods",
+ "id": "t-4"
+ }
+ ]
+}
diff --git a/src/index.css b/src/index.css
deleted file mode 100644
index 61010be6..00000000
--- a/src/index.css
+++ /dev/null
@@ -1,4 +0,0 @@
-body {
- background: pink;
- color: hotpink;
-}
\ No newline at end of file
diff --git a/src/main.jsx b/src/main.jsx
index ed109d76..f4d05e33 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -1,12 +1,18 @@
-import { StrictMode } from 'react'
-import { createRoot } from 'react-dom/client'
+import React from "react";
-import { App } from './App.jsx'
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
-import './index.css'
+import { App } from "./App.jsx";
+// { } if exported directly in function
+//else imporn App from...
-createRoot(document.getElementById('root')).render(
+import "./App.css";
+
+createRoot(document.getElementById("root")).render(
- ,
-)
+
+);
+
+//main is a recipe and should not be changed
diff --git a/src/sections/DescComponent/Desc.jsx b/src/sections/DescComponent/Desc.jsx
new file mode 100644
index 00000000..4d38c4b7
--- /dev/null
+++ b/src/sections/DescComponent/Desc.jsx
@@ -0,0 +1,5 @@
+import React from "react";
+
+export const Desc = ({ desc }) => {
+ return
{desc}
;
+};
diff --git a/src/sections/FeaturedProjects.jsx b/src/sections/FeaturedProjects.jsx
new file mode 100644
index 00000000..16c9cadb
--- /dev/null
+++ b/src/sections/FeaturedProjects.jsx
@@ -0,0 +1,29 @@
+import React, { useState } from "react";
+
+import { Title } from "./TitleComponents/Title";
+import { ProjectBox } from "./FeaturedProjectsComponents/ProjectBox";
+import { SeeMore } from "./SeeMoreComponent/SeeMore";
+
+export const FeaturedProjects = () => {
+ let [articles, setArticles] = useState(4);
+
+ const handleClick = () => {
+ setArticles(articles + 4);
+ };
+
+ return (
+
+
+
+ {articles === 4 && }
+
+ );
+};
+
+// question ? do this : else this
+//articles === 4 ? : null
+
+//question && do this
+//articles === 4 &&
+
+//ternary operator but tweaked when it should do nothing if false
diff --git a/src/sections/FeaturedProjectsComponents/ProjectBox.jsx b/src/sections/FeaturedProjectsComponents/ProjectBox.jsx
new file mode 100644
index 00000000..b993ffaf
--- /dev/null
+++ b/src/sections/FeaturedProjectsComponents/ProjectBox.jsx
@@ -0,0 +1,43 @@
+import React, { useEffect } from "react";
+
+import projects from "../../data/projects.json";
+
+import { Image } from "./ProjectBoxComponents/Image";
+import { Tags } from "./ProjectBoxComponents/Tags";
+import { Desc } from "../DescComponent/Desc";
+import { Links } from "./ProjectBoxComponents/Links";
+import { Title } from "../TitleComponents/TitleH3";
+
+import AOS from "aos";
+import "aos/dist/aos.css";
+
+export const ProjectBox = ({ load }) => {
+ useEffect(() => {
+ AOS.init({ duration: 1000 });
+ }, []);
+ console.log(load);
+
+ return (
+ <>
+ {projects.projects.slice(0, load).map((project, index) => (
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+ >
+ );
+};
+
+//only show four items at first, then load four more. State?
diff --git a/src/sections/FeaturedProjectsComponents/ProjectBoxComponents/Image.jsx b/src/sections/FeaturedProjectsComponents/ProjectBoxComponents/Image.jsx
new file mode 100644
index 00000000..9a812121
--- /dev/null
+++ b/src/sections/FeaturedProjectsComponents/ProjectBoxComponents/Image.jsx
@@ -0,0 +1,18 @@
+import React from "react";
+
+export const Image = ({ index, url }) => {
+ const orderClass = index % 2 === 0 ? "xl:order-first" : "xl:order-last";
+
+ return (
+
+
+
+ );
+};
+
+//object-fill self-stretch
diff --git a/src/sections/FeaturedProjectsComponents/ProjectBoxComponents/Links.jsx b/src/sections/FeaturedProjectsComponents/ProjectBoxComponents/Links.jsx
new file mode 100644
index 00000000..2c17c581
--- /dev/null
+++ b/src/sections/FeaturedProjectsComponents/ProjectBoxComponents/Links.jsx
@@ -0,0 +1,31 @@
+import React from "react";
+
+import netlifyPic from "../../../assets/Ic-Web.svg";
+import githubPic from "../../../assets/Ic-Github.svg";
+
+export const Links = ({ netlf, github }) => {
+ return (
+
+
+ As a developer with a background in health and social care 💊, I have a
+ unique perspective on how technology can improve people's lives. I am
+ currently enrolled in a 32-week remote bootcamp at Technigo, where I am
+ learning JavaScript (ES6), TypeScript, React, HTML5, CSS, and server-side
+ programming with Node.js. I have also worked as a 3D technician at
+ Sculptur, where I designed furniture through CAD and launched tests on a
+ new filament. My goal is to combine my passion for technology and social
+ impact to create innovative solutions that make a difference. ðŸ§
+