0% found this document useful (0 votes)
10 views7 pages

Portfolio

Uploaded by

helesej120
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views7 pages

Portfolio

Uploaded by

helesej120
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

import React, { useEffect, useRef } from "react";

import "./PortfolioCard.scss";
import AOS from "aos";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import dotSmall from "../../assets/dot-small.svg";

function PortfolioCard({
imgSrc,
delay,
classTitle,
hidden,
techStack = [], // Default to an empty array if techStack is undefined
Description,
imgBg,
imgIcon,
logo,
Category,
nTs,
}) {
let hiddenClass = "";
let bg = imgBg;

const slider = useRef(null);


const sliderSettings = {
slidesToShow: 1,
slidesToScroll: 1,
centerMode: true,
arrows: true,
centerPadding: "100px",
infinite: true,
responsive: [
{
breakpoint: 1300,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
centerMode: true,
centerPadding: "90px",
},
},
{
breakpoint: 1100,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
centerMode: true,
centerPadding: "70px",
},
},
{
breakpoint: 800,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
centerMode: true,
centerPadding: "20px",
infinite: true,
},
},
{
breakpoint: 650,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
centerMode: true,
centerPadding: "80px",
},
},
],
};

if (hidden) {
hiddenClass = "hidden";
}

useEffect(() => {
AOS.init();
}, []);

// Convert techStack from object to array if it's an object


const techStackArray = Array.isArray(techStack)
? techStack
: Object.entries(techStack).map(([key, value]) => ({
name: value,
icon: imgIcon[key], // Assuming imgIcon has the same keys as techStack
}));

return (
<div
className={"PortfolioCard " + hiddenClass}
data-aos="fade-up"
data-aos-delay={delay}
>
<button className="next" onClick={() => slider?.current?.slickNext()}>
&#x1F862;
</button>
<button className="prev" onClick={() => slider?.current?.slickPrev()}>
&#x1F860;
</button>

<div
className={"portfolio-card-container"}
style={{ backgroundImage: `url(${bg})` }}
>
<div className={"portfolio-class-title"}>{classTitle}</div>
<svg width="30" height="30" className="project-logo">
<image xlinkHref={logo} height="30" width="30" />
</svg>

<div className="slider-container">
<Slider ref={slider} {...sliderSettings}>
{imgSrc?.map((img, index) => (
<div key={index}>
<img alt={img} src={img} className="crousel-image" />
</div>
))}
</Slider>
</div>
</div>
<div className="portfolio-project-description">
<p className="portfolio-card-header">{Category} App</p>
<ul className="portfolio-tech-list">
<li className="tech-list-item">
<div className={"details " + classTitle}>
<ul className="tech-stack">
{/* Use the transformed techStackArray */}
{techStackArray?.map((item, i) => (
<div className="project-details" key={item.name + i}>
<svg width="30" height="30" className="techStack-logo">
<image xlinkHref={item.icon} height="25" width="25" />
</svg>
<p className="skill">{item.name}</p>
{nTs-- > 1 && (
<svg width="40" height="40">
<image
xlinkHref={dotSmall}
x="9"
y="5"
height="20px"
width="20px"
className="startNewProject-dotSmall"
></image>
</svg>
)}
</div>
))}
</ul>
<div>
<p className="project-description">{Description}</p>
</div>
</div>
</li>
</ul>
</div>
</div>
);
}

export default PortfolioCard;

import React, { useState, useEffect } from "react";


import PortfolioCard from "../PortfolioCard/PortfolioCard";
import "./Portfolio.scss";
import { arr, arr2 } from "../../helper/helper";
import dotSmall from "../../assets/dot-small.svg";

function Portfolio() {
const [data, setData] = useState([...arr]);
const [currentCard, setCurrentCard] = useState("All");
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [showViewMore, setShowViewMore] = useState(true);
const [activeButton, setActiveButton] = useState("All");

// Fetch data from the API


useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(
"http://strapi.koders.in/api/koders-projects?populate=*"
);

if (!response.ok) {
throw new Error("Network response was not ok");
}

const result = await response.json();


console.log("Fetched data:", result);

if (Array.isArray(result.data)) {
// Combine fetched data with local data (arr and arr2) if needed
setData(result.data);
} else {
console.error("Data format is invalid, expected an array.");
}
} catch (error) {
setError(error.message);
console.error("Error fetching data:", error);
} finally {
setLoading(false);
}
};

fetchData();
}, []);

// Handle category button click


const handleBtns = (e) => {
const selectedCategory = e.target.value;
setCurrentCard(selectedCategory);
setActiveButton(selectedCategory);
};

// Filter data based on the selected category


useEffect(() => {
const filteredData =
currentCard === "All"
? [...arr, ...arr2] // If "All" is selected, show all data
: [...arr, ...arr2].filter(
(item) =>
item.Category === currentCard ||
item.Category.includes(currentCard)
);

setData(filteredData);
setShowViewMore(
currentCard === "All" && filteredData.length < arr.length + arr2.length
);
}, [currentCard]);
// Handle "View More" button click
const handleClick = () => {
setData((prevData) => [...prevData, ...arr2]);
setShowViewMore(false); // Hide the "view more" button once clicked
};

if (loading) {
return <div>Loading...</div>;
}

if (error) {
return <div>Error: {error}</div>;
}

return (
<div className="Portfolio">
<div className="portfolio-header">
<h1>PORTFOLIO</h1>
<h4>AUTOMATION: Rules the Roost</h4>
<p>
Automation is made easier with Koders. Take a look at the various
projects we've completed.
</p>
</div>

<div className="portfolio-nav">
<section className="nav-items" id="nav">
<button
className={`btn ${activeButton === "All" ? "active" : ""}`}
onClick={handleBtns}
type="button"
value="All"
>
All
</button>
<button
className={`btn ${activeButton === "Mobile" ? "active" : ""}`}
onClick={handleBtns}
type="button"
value="Mobile"
>
Mobile Apps
</button>
<button
className={`btn ${activeButton === "Desktop" ? "active" : ""}`}
onClick={handleBtns}
type="button"
value="Desktop"
>
Desktop Apps
</button>
<button
className={`btn ${activeButton === "Web" ? "active" : ""}`}
onClick={handleBtns}
type="button"
value="Web"
>
Websites
</button>
<button
className={`btn ${activeButton === "UI" ? "active" : ""}`}
onClick={handleBtns}
type="button"
value="UI"
>
UI/UX
</button>
</section>
</div>

<div className="portfolio-cards">
{data.map((item) => (
<PortfolioCard
key={item.title}
hidden={item.hidden}
imgSrc={item.imgSrc}
delay={item.delay}
classTitle={item.classTitle}
position={item.position}
techStack={item.techStack}
imgIcon={item.imgIcon}
Description={item.Description}
imgBg={item.imgBg}
title={item.title}
isMobile={item?.isMobile}
logo={item.logo}
Category={item.Category}
nTs={item.nTs}
/>
))}
</div>

<div className="portfolio-buttons">
{showViewMore && (
<button className="portfolio-viewmore-btn" onClick={handleClick}>
View More
</button>
)}
<div className="startNewProject">
<a
className="startNewProject-btn"
href="https://koders.in/start-project"
target="_blank"
rel="noreferrer"
>
<svg
className="rotatingText"
viewBox="0 0 200 200"
width="165"
height="165"
>
<defs>
<path
id="circle"
d="M 100, 100
m -75, 0
a 75, 75 0 1, 0 150, 0
a 75, 75 0 1, 0 -150, 0
"
></path>
</defs>
<text width="400">
<textPath
alignmentBaseline="top"
xlinkHref="#circle"
className="startNewProjectText"
>
Start A Project With US
</textPath>
</text>
<image
xlinkHref={dotSmall}
x="75"
y="75"
height="50px"
width="50px"
className="startNewProject-dotSmall"
></image>
</svg>
</a>
</div>
</div>
</div>
);
}

export default Portfolio;

You might also like