Skip to content

Develop #22

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

Open
wants to merge 91 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
7d64e12
Ignored file package-lock.json
Mar 23, 2025
5253bfa
Corrected deprecated image layout
Mar 23, 2025
7d06c86
Fix: corrected option value in project filter to avoid React warning
Mar 23, 2025
a8ed995
Feat: added 'All Projects' option and improved category filtering logic
Mar 23, 2025
7c6754e
Feat: activated contacting via Formspree
Mar 24, 2025
08f30d9
Fix: added personal informations
Mar 24, 2025
d7fb9dd
Feat: added isic-2024 project main image
Mar 25, 2025
316f1dd
Fix: set automatic image height in projects
Mar 25, 2025
fb781c6
Feat: added bio
Mar 25, 2025
157f6e7
Feat: added Isic-2024 overview
Mar 25, 2025
424c194
Feat: added ISIC-2024 notebook
Mar 25, 2025
3a72552
Feat: ignoring quarto rendering files
Mar 26, 2025
f473adc
Feat: added quarto rendering documentation
Mar 26, 2025
bf62a29
Feat: converted isic-2024_kaggle.ipynb to html using quarto
Mar 26, 2025
b6b4aca
Feat: customized TOC in isic-2024_kaggle.qmd file
Mar 26, 2025
558197f
Feat: displaying isic-2024_kaggle.ipynb using quarto and customizing …
Mar 26, 2025
94cbc5a
Feat: added eslint dependecy
Mar 26, 2025
5bf5eec
Fix: escaped apostrophe and replaced img with Image component
Mar 26, 2025
a3689b7
Fix: add rendering Quarto notebook with theme files
Mar 26, 2025
8fab7cb
Fix: updated clients logos
Mar 26, 2025
b26a9bb
Fix: updated hire me modals
Mar 26, 2025
90b6cd8
Fix: corrected project tag
Mar 26, 2025
1f0c3f5
Refactor: Separated project layouts into NotebookProjectLayout and De…
Mar 27, 2025
3d40f9c
Feature: Implemented dynamic tabs in ProjectTabs.jsx
Mar 27, 2025
a85f5e6
Fix: Adjusted tag font size and style to match tab content
Mar 27, 2025
4cc84d4
Feature: added Data Science project category
Mar 27, 2025
2338702
Feature: web apps projects layout
Mar 27, 2025
5f9e9a7
Fix: Marked AI Skin Cancer Detection as a notebook project and added …
Mar 27, 2025
59e17aa
Debug: Added notebook file path in ProjectTabs
Mar 27, 2025
bf36b9e
Fix: NotebookViewer now dynamically loads the notebook file based on …
Mar 27, 2025
0a576d9
Feature: Added music recommendation system images
Mar 27, 2025
bdb3af7
Fix: updated resume
Mar 27, 2025
7be5c27
Fix: updated resume
Mar 28, 2025
0dd42a0
Fix: updated resume
Mar 28, 2025
fb44ed4
Feat: added music recommendation notebook
Mar 28, 2025
d84f99e
Fix: updated music recommendation notebook file
Mar 28, 2025
a4d385f
Fix: updated music recommendation project description
Mar 28, 2025
3eb7f65
Fix: updated music recommendation project description
Mar 28, 2025
532a53d
Fix: updated music recommendation project category
Mar 28, 2025
4d4db48
Fix: added music recommendation description
Mar 28, 2025
25a0393
Fix: excluded the project description from the notebook
Mar 28, 2025
2805ec0
Fix: corrected music recommendation notebook first paragraph header
Mar 28, 2025
71cff29
Fix: changed logo sizes
Mar 28, 2025
3b01748
Fix: handling correct coulour change when the user switch theme
Mar 28, 2025
6a6dc4e
Feat: creating related projects for each active project
Mar 28, 2025
23c58b8
Feat: added blog module
Mar 28, 2025
d0a693a
Feat: added test blog articles
Mar 28, 2025
f8497b9
Fix: added in hamburger menu
Mar 29, 2025
0472f87
Fix: added Blog in hamburger menu
Mar 29, 2025
92d312c
Fix: added correct blog link
Mar 29, 2025
0619d34
Feat: created Berlin Marathon post
Mar 30, 2025
eccf22d
Feat: updated portfolio logos
Mar 30, 2025
c290e01
Feat: updated share butons
Mar 30, 2025
016b0c8
Fix: updated berlin-marathon.mdx
Mar 31, 2025
7814a04
Feat: added reusable mdx components
Mar 31, 2025
8a05caa
Feat: added berlin marathon images
Mar 31, 2025
360132f
Feat: updates for reusables components integration
Mar 31, 2025
103f0b5
Feat: added clickable links int the TOC and reformatted Berlin marath…
Apr 1, 2025
fdcc034
Feat: started transformes, top-5 ai tools articles and sorted articles
Apr 1, 2025
dfcf77c
Feat: formatted berlin marthon article
Apr 1, 2025
b88aa4f
Feat: Formatted projects and blogs grid cards
Apr 1, 2025
e79f553
Fix: escaping special characters before serializing
Apr 1, 2025
fbb4d98
Fix: deleted duplicated file
Apr 1, 2025
39d0095
Fix: escapade special character tild in berlin marathon mdx
Apr 1, 2025
b54df30
Fix: deleted bad mdx file
Apr 1, 2025
5756464
Fix: updated favicon
Apr 1, 2025
9150369
Fix: updated resume
Apr 2, 2025
75b88a8
Feat: started the books that changed my life
Apr 3, 2025
1273714
Feat: updated think and grow rich image and rearranged sections
Apr 4, 2025
a547c25
Feat: added life force book
Apr 4, 2025
532c154
Feat: added new books
Apr 4, 2025
d201bbd
Feat: added last books in category reading
Apr 4, 2025
2efe300
Feat started travel articles
Apr 4, 2025
46a9a48
Fix: reformatted books article
Apr 5, 2025
54ed2d5
Fix: updated projects images
Apr 5, 2025
ceca416
Fix: escaped special character
Apr 5, 2025
41a1a5d
Feat: corrected dark mode colors
Apr 6, 2025
b528319
Feat: make TOC adapt to all screen sizes
Apr 6, 2025
21f5cc4
Fix: Updated font colors on dark/white modes
Apr 6, 2025
17a0708
Fix: fixed authors portrait not showing on mobile in books article
Apr 7, 2025
90d64c1
Feat: added google analytics
Apr 7, 2025
5c7bce8
Fix: reduced margin top of google analytics
Apr 7, 2025
9a0e357
Fix: added debug for google analytics
Apr 7, 2025
7d54160
Fix: deleted debug for google analytics
Apr 7, 2025
daa8090
Fix: making layout adapt to the screen size
Apr 8, 2025
57a9abe
Fix: made the project fully adaptive to different screen sizes
Apr 9, 2025
33228fa
Fix: Capitalize author box text
Apr 9, 2025
3fb5f00
Fix: Formatted article in progress message
Apr 9, 2025
aaa7a51
Fix: aligned proejcts and blogs grid pages
Apr 9, 2025
07b5751
Feat: updated margin-left and right of the pages
Apr 11, 2025
317e243
Feat: reduced the margins on small screens
Apr 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# next.js
/.next/
/out/
package-lock.json

# production
/build
Expand All @@ -32,3 +33,5 @@ yarn-error.log*

# vercel
.vercel

/tmp
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,51 @@ npm run dev
- Feel free to use it as your own portfolio
- Contributions are welcome

## Notebooks rendering with Quarto

1. Transform the jupyter notebook into a qmd file:

```
quarto convert isic-2024_kaggle.ipynb -o isic-2024_kaggle.qmd
```

2. Transform the qmd file to suit your layout needs, for example add this at the head of the qmd file:

```
---
format:
html:
title: ''
toc: true
toc-title: "<strong>Table of contents</strong>"
toc-location: right
toc-depth: 5
toc-expand: true
toc-float:
collapsed: true
smooth-scroll: true
width: 300px
theme: cosmo
code-fold: false
code-fold-show: true
page-layout: full
number-sections: true
code-tools: false
code-line-numbers: false
code-summary: "Show Code"
code-block-bg: true
include-in-header: styles/toc-scrollbar-hide.html
execute:
enabled: false
---
```

3. Convert the qmd into an html file:

```
quarto render isic-2024_kaggle.qmd
```

### License

[MIT](https://github.com/realstoman/nextjs-tailwindcss-portfolio/blob/main/LICENSE)
34 changes: 34 additions & 0 deletions clean_project.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
rm -rf .next node_modules package-lock.json yarn.lock
npm cache clean --force
npm install
npm run build
npm run dev


npm install next@latest react@latest react-dom@latest --force
npm install
npm run build
npm run dev



npm install framer-motion@latest
rm -rf node_modules package-lock.json .next
npm install
npm run build
npm run dev


brew install trash
trash node_modules
rm -rf ~/.Trash/*

npm install



trash node_modules
rm -rf ~/.Trash/*
rm -rf .next node_modules package-lock.json yarn.lock
npm install
npm run dev
41 changes: 16 additions & 25 deletions components/HireMeModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { FiX } from 'react-icons/fi';
import Button from './reusable/Button';

const selectOptions = [
'Web Application',
'Mobile Application',
'UI/UX Design',
'Branding',
'Data Science',
'Generative AI',
'Data Engineering',
'Software Engineering',
'Web Application'
];

function HireMeModal({ onClose, onRequest }) {
Expand All @@ -25,23 +26,22 @@ function HireMeModal({ onClose, onRequest }) {
<div className="modal-wrapper flex items-center z-30">
<div className="modal max-w-md mx-5 xl:max-w-xl lg:max-w-xl md:max-w-xl bg-secondary-light dark:bg-primary-dark max-h-screen shadow-lg flex-row rounded-lg relative">
<div className="modal-header flex justify-between gap-10 p-5 border-b border-ternary-light dark:border-ternary-dark">
<h5 className=" text-primary-dark dark:text-primary-light text-xl">
<h5 className=" text-primary-dark dark:text-gray-300 text-xl">
What project are you looking for?
</h5>
<button
onClick={onClose}
className="px-4 font-bold text-primary-dark dark:text-primary-light"
className="px-4 font-bold text-primary-dark dark:text-gray-300 "
>
<FiX className="text-3xl" />
</button>
</div>
<div className="modal-body p-5 w-full h-full">
<form
onSubmit={(e) => {
e.preventDefault();
}}
className="max-w-xl m-4 text-left"
>
<form
action="https://formspree.io/f/mldjbkwy"
method="POST"
className="max-w-xl m-4 text-left"
>
<div className="">
<input
className="w-full px-5 py-2 border dark:border-secondary-dark rounded-md text-md bg-secondary-light dark:bg-ternary-dark text-primary-dark dark:text-ternary-light"
Expand Down Expand Up @@ -97,22 +97,13 @@ function HireMeModal({ onClose, onRequest }) {
</div>

<div className="mt-6 pb-4 sm:pb-1">
<span
onClick={onRequest}
<button
type="submit"
className="px-4
sm:px-6
py-2
sm:py-2.5
text-white
bg-indigo-500
hover:bg-indigo-600
rounded-md
focus:ring-1 focus:ring-indigo-900 duration-500"
className="px-4 sm:px-6 py-2 sm:py-2.5 text-white bg-indigo-500 hover:bg-indigo-600 rounded-md focus:ring-1 focus:ring-indigo-900 duration-500"
aria-label="Submit Request"
>
<Button title="Send Request" />
</span>
<Button title="Send Request" />
</button>
</div>
</form>
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/PagesMetaHead.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function PagesMetaHead({ title, keywords, description }) {
<meta name="keywords" content={keywords} />
<meta name="description" content={description} />
<meta charSet="utf-8" />
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/favicon.png" />
<title>{title}</title>
</Head>
);
Expand All @@ -22,4 +22,4 @@ PagesMetaHead.defaultProps = {
keywords: 'Simple and multi-page next.js and react application',
};

export default PagesMetaHead;
export default PagesMetaHead;
93 changes: 93 additions & 0 deletions components/TableOfContents.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use client'

import { useEffect, useState, useRef } from 'react'

export default function TableOfContents({ className = '' }) {
const [headings, setHeadings] = useState([])
const [activeId, setActiveId] = useState(null)
const itemRefs = useRef({})

useEffect(() => {
const timeout = setTimeout(() => {
const elements = Array.from(document.querySelectorAll('h2[id], h3[id]'))
const newHeadings = elements.map((el) => ({
id: el.id,
text: el.textContent || '',
level: el.tagName === 'H2' ? 2 : 3,
}))
setHeadings(newHeadings)
}, 500)

return () => clearTimeout(timeout)
}, [])

useEffect(() => {
if (!headings.length) return

const observer = new IntersectionObserver(
(entries) => {
const visible = entries
.filter((entry) => entry.isIntersecting)
.sort((a, b) => a.target.offsetTop - b.target.offsetTop)

if (visible.length > 0) {
setActiveId(visible[0].target.id)
}
},
{
rootMargin: '-40% 0% -40% 0%',
threshold: 0.1,
}
)

const elements = document.querySelectorAll('h2[id], h3[id]')
elements.forEach((el) => observer.observe(el))

return () => {
elements.forEach((el) => observer.unobserve(el))
}
}, [headings])

if (!headings.length) return null

return (
<aside
className={`hidden [@media(min-width:2000px)]:block fixed top-60 right-10 bottom-32 w-64 z-40 overflow-y-auto text-sm text-gray-500 dark:text-gray-300 transition-all duration-300 ${className} mt-5`}
>
<div className="pl-2">
<p className="mb-2 text-xs font-bold uppercase tracking-wider text-gray-600 dark:text-gray-200">
On This Article
</p>

<div className="relative">
{/* vertical bar limited to list height */}
<div className="absolute left-2 top-0 bottom-0 w-px bg-gray-200 dark:bg-gray-600" />

<ul className="space-y-1 pl-4">
{headings.map((heading) => (
<li
key={heading.id}
className={`relative ${
heading.level === 3 ? 'pl-[21px]' : 'pl-0'
}`}
>
<a
ref={(el) => (itemRefs.current[heading.id] = el)}
href={`#${heading.id}`}
className={`block truncate transition-colors duration-200 ml-1 ${
activeId === heading.id
? 'text-indigo-600 font-semibold dark:text-indigo-400'
: 'hover:text-primary-dark dark:hover:text-primary-light'
}`}
>
{heading.text}
</a>
</li>
))}
</ul>
</div>
</div>

</aside>
)
}
21 changes: 21 additions & 0 deletions components/ThemeToggle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// components/ThemeToggle.js
import { useTheme } from 'next-themes';
import { useEffect, useState } from 'react';

export default function ThemeToggle() {
const { theme, setTheme, resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);

useEffect(() => setMounted(true), []);

if (!mounted) return null; // avoids hydration error

return (
<button
onClick={() => setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')}
className="px-4 py-2 rounded bg-gray-200 dark:bg-gray-500 text-sm"
>
Switch to {resolvedTheme === 'dark' ? 'light' : 'dark'} mode
</button>
);
}
12 changes: 6 additions & 6 deletions components/about/AboutClientSingle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import Image from 'next/image';

function AboutClientSingle({ title, image }) {
return (
<div className="py-5 px-10 border bg-secondary-light border-ternary-light dark:border-ternary-dark shadow-sm rounded-lg mb-5 cursor-pointer">
<div className="py-5 px-10 border bg-secondary-light border-gray-200 dark:border-ternary-dark shadow-sm rounded-lg mb-5 cursor-pointer">
<Image
src={image}
alt={title}
layout="responsive"
width={100}
height={50}
src={image}
alt={title}

className="object-contain w-full h-auto"
/>

</div>
);
}
Expand Down
Loading