Skip to content

Commit 2358060

Browse files
authored
Merge pull request realstoman#12 from realstoman/final-touches
Final touches
2 parents a0d09ef + 3a535f0 commit 2358060

File tree

9 files changed

+149
-75
lines changed

9 files changed

+149
-75
lines changed

README.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# React & TailwindCSS Portfolio - With Dark Mode
22

3-
A simple portfolio starter theme built with React and TailwindCSS. This is a simple portfolio theme and its geared towards beginners. This is the React version of [vuejs-tailwindcss-portfolio](https://github.com/NangialaiStoman/vuejs-tailwindcss-portfolio).
3+
A simple portfolio starter theme built with React and TailwindCSS. This is the React version of [vuejs-tailwindcss-portfolio](https://github.com/realstoman/vuejs-tailwindcss-portfolio).
44

55
![React-TailwindCSS-Portfolio](https://user-images.githubusercontent.com/16396664/140909796-815239e4-a986-46ad-bbd0-4b166127bbb8.JPG)
66

@@ -10,20 +10,20 @@ A simple portfolio starter theme built with React and TailwindCSS. This is a sim
1010

1111
## Features
1212

13-
- Simple and responsive design
1413
- [React](https://reactjs.org) with [React Router v6](https://reactrouter.com)
15-
- [Tailwind CSS v2](https://tailwindcss.com)
16-
- Theme Switcher with Dark Mode
17-
- Context API
18-
- Transitions & Animations
19-
- Counter
14+
- [Tailwind CSS v3](https://tailwindcss.com)
15+
- Context API For State Management
16+
- Custom Hooks
17+
- Dark Mode
18+
- Framer Motion Transitions & Animations
2019
- Projects filter by category
2120
- Projects filter by search
22-
- Projects carousel
2321
- Smooth scroll
22+
- Counter
2423
- Dynamic forms
2524
- Back to top button
2625
- Download file button
26+
- Simple and responsive design
2727

2828
## Installation
2929

@@ -40,7 +40,7 @@ brew install node
4040
2. ##### Clone the repo:
4141

4242
```
43-
git clone https://github.com/NangialaiStoman/react-tailwindcss-portfolio.git
43+
git clone https://github.com/realstoman/react-tailwindcss-portfolio.git
4444
```
4545

4646
3. ##### Open the project folder:

src/App.js

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Home from './pages/Home';
99
import Projects from './pages/Projects';
1010
import ProjectSingle from './pages/ProjectSingle';
1111
import { AnimatePresence } from 'framer-motion';
12+
import UseScrollToTop from './hooks/useScrollToTop';
1213

1314
function App() {
1415
return (
@@ -30,6 +31,7 @@ function App() {
3031
</Routes>
3132
<AppFooter />
3233
</Router>
34+
<UseScrollToTop />
3335
</div>
3436
</AnimatePresence>
3537
);

src/components/HireMeModal.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { motion } from 'framer-motion';
22
import { FiX } from 'react-icons/fi';
33

4+
const selectOptions = [
5+
'Web Application',
6+
'Mobile Application',
7+
'UI/UX Design',
8+
'Branding',
9+
];
10+
411
const HireMeModal = ({ onClose, onRequest }) => {
512
return (
613
<motion.div
@@ -65,7 +72,14 @@ const HireMeModal = ({ onClose, onRequest }) => {
6572
required=""
6673
aria-label="Project Category"
6774
>
68-
<option>Something</option>
75+
{selectOptions.map((option) => (
76+
<option
77+
className="text-normal sm:text-md"
78+
key={option}
79+
>
80+
{option}
81+
</option>
82+
))}
6983
</select>
7084
</div>
7185

src/components/ScrollToTop.js

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// NOTE: This scroll to top is the default react scroll to top behavior when visiting a new route.
2+
// For the scroll to top behavior on a click event I have create a custom hook with the name of useScrollToTop under the hooks folder.
3+
14
import { useEffect } from 'react';
25
import { useLocation } from 'react-router-dom';
36

src/components/projects/ProjectSingle.js

+17-19
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,23 @@ const ProjectSingle = ({ title, category, image }) => {
1212
delay: 0.15,
1313
}}
1414
>
15-
<Link
16-
to="/projects/single-project"
17-
className="rounded-xl shadow-lg hover:shadow-xl cursor-pointer mb-10 sm:mb-0 bg-secondary-light dark:bg-ternary-dark"
18-
aria-label="Single Project"
19-
>
20-
<div>
21-
<img
22-
src={image}
23-
className="rounded-t-xl border-none"
24-
alt="Single Project"
25-
/>
26-
</div>
27-
<div className="text-center px-4 py-6">
28-
<p className="text-2xl text-ternary-dark dark:text-ternary-light font-semibold mb-2">
29-
{title}
30-
</p>
31-
<span className="text-lg text-ternary-dark dark:text-ternary-light">
32-
{category}
33-
</span>
15+
<Link to="/projects/single-project" aria-label="Single Project">
16+
<div className="rounded-xl shadow-lg hover:shadow-xl cursor-pointer mb-10 sm:mb-0 bg-secondary-light dark:bg-ternary-dark">
17+
<div>
18+
<img
19+
src={image}
20+
className="rounded-t-xl border-none"
21+
alt="Single Project"
22+
/>
23+
</div>
24+
<div className="text-center px-4 py-6">
25+
<p className="text-2xl text-ternary-dark dark:text-ternary-light font-semibold mb-2">
26+
{title}
27+
</p>
28+
<span className="text-lg text-ternary-dark dark:text-ternary-light">
29+
{category}
30+
</span>
31+
</div>
3432
</div>
3533
</Link>
3634
</motion.div>

src/components/projects/ProjectsGrid.js

-23
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { FiSearch } from 'react-icons/fi';
33
import ProjectSingle from './ProjectSingle';
44
import { ProjectsContext } from '../../context/ProjectsContext';
55
import ProjectsFilter from './ProjectsFilter';
6-
import { motion } from 'framer-motion';
76

87
const ProjectsGrid = () => {
98
const {
@@ -16,28 +15,6 @@ const ProjectsGrid = () => {
1615
selectProjectsByCategory,
1716
} = useContext(ProjectsContext);
1817

19-
const projectsResult = () => {
20-
if (setSearchProject) {
21-
return searchProjectsByTitle.map((project) => (
22-
<ProjectSingle
23-
title={project.title}
24-
category={project.category}
25-
image={project.img}
26-
key={project.id}
27-
/>
28-
));
29-
} else if (setSelectProject) {
30-
return selectProjectsByCategory.map((project) => (
31-
<ProjectSingle
32-
title={project.title}
33-
category={project.category}
34-
image={project.img}
35-
key={project.id}
36-
/>
37-
));
38-
}
39-
};
40-
4118
return (
4219
<section className="py-5 sm:py-10 mt-5 sm:mt-10">
4320
{/* Projects grid title start */}

src/css/App.css

+50-21
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,67 @@
11
.App {
2-
text-align: center;
2+
text-align: center;
33
}
44

55
.App-logo {
6-
height: 40vmin;
7-
pointer-events: none;
6+
height: 40vmin;
7+
pointer-events: none;
88
}
99

1010
@media (prefers-reduced-motion: no-preference) {
11-
.App-logo {
12-
animation: App-logo-spin infinite 20s linear;
13-
}
11+
.App-logo {
12+
animation: App-logo-spin infinite 20s linear;
13+
}
1414
}
1515

1616
.App-header {
17-
background-color: #282c34;
18-
min-height: 100vh;
19-
display: flex;
20-
flex-direction: column;
21-
align-items: center;
22-
justify-content: center;
23-
font-size: calc(10px + 2vmin);
24-
color: white;
17+
background-color: #282c34;
18+
min-height: 100vh;
19+
display: flex;
20+
flex-direction: column;
21+
align-items: center;
22+
justify-content: center;
23+
font-size: calc(10px + 2vmin);
24+
color: white;
2525
}
2626

2727
.App-link {
28-
color: #61dafb;
28+
color: #61dafb;
2929
}
3030

3131
@keyframes App-logo-spin {
32-
from {
33-
transform: rotate(0deg);
34-
}
35-
to {
36-
transform: rotate(360deg);
37-
}
32+
from {
33+
transform: rotate(0deg);
34+
}
35+
to {
36+
transform: rotate(360deg);
37+
}
38+
}
39+
40+
/* Scroll to top style */
41+
.scrollToTop {
42+
@apply bg-indigo-600;
43+
@apply text-white;
44+
position: fixed;
45+
width: 100%;
46+
align-items: center;
47+
height: 20px;
48+
justify-content: center;
49+
z-index: 999;
50+
cursor: pointer;
51+
animation: fadeIn 0.3s;
52+
transition: opacity 0.4s;
53+
opacity: 0.5;
54+
}
55+
56+
.scrollToTop:hover {
57+
opacity: 1;
58+
}
59+
60+
@keyframes fadeIn {
61+
0% {
62+
opacity: 0;
63+
}
64+
100% {
65+
opacity: 0.5;
66+
}
3867
}

src/hooks/useScrollToTop.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// NOTE: This scroll to top is the actual working scroll to to when user clicks
2+
3+
import { useState, useEffect } from 'react';
4+
import { FiChevronUp } from 'react-icons/fi';
5+
6+
const useScrollToTop = () => {
7+
const [showScroll, setShowScroll] = useState(false);
8+
9+
useEffect(() => {
10+
window.addEventListener('scroll', scrollToTop);
11+
return function cleanup() {
12+
window.removeEventListener('scroll', scrollToTop);
13+
};
14+
});
15+
16+
const scrollToTop = () => {
17+
if (!showScroll && window.pageYOffset > 400) {
18+
setShowScroll(true);
19+
} else if (showScroll && window.pageYOffset <= 400) {
20+
setShowScroll(false);
21+
}
22+
};
23+
24+
const backToTop = () => {
25+
window.scrollTo({
26+
top: 0,
27+
behavior: 'smooth',
28+
});
29+
};
30+
31+
window.addEventListener('scroll', scrollToTop);
32+
33+
return (
34+
<>
35+
<FiChevronUp
36+
className="scrollToTop"
37+
onClick={backToTop}
38+
style={{
39+
height: 45,
40+
width: 45,
41+
borderRadius: 50,
42+
right: 50,
43+
bottom: 50,
44+
display: showScroll ? 'flex' : 'none',
45+
}}
46+
/>
47+
</>
48+
);
49+
};
50+
51+
export default useScrollToTop;

src/pages/Home.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ const Home = () => {
1212
<ProjectsGrid></ProjectsGrid>
1313
</ProjectsProvider>
1414

15-
<div class="mt-10 sm:mt-15 flex justify-center">
15+
<div className="mt-10 sm:mt-15 flex justify-center">
1616
<Link
1717
to="/projects"
18-
class="flex items-center px-6 py-3 rounded-lg shadow-lg hover:shadow-xl bg-indigo-500 hover:bg-indigo-600 focus:ring-1 focus:ring-indigo-900 text-white text-lg sm:text-xl font-medium"
18+
className="flex items-center px-6 py-3 rounded-lg shadow-lg hover:shadow-xl bg-indigo-500 hover:bg-indigo-600 focus:ring-1 focus:ring-indigo-900 text-white text-lg sm:text-xl font-medium"
1919
aria-label="More Projects"
2020
>
2121
More Projects

0 commit comments

Comments
 (0)