Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
179 changes: 178 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,178 @@
# Portfolio
# 🏑 Kausar Portfolio

**Kausar Portfolio** is a modern, interactive portfolio website built during Technigo’s JavaScript Bootcamp (August 2025). The project showcases my skills, projects, blog articles, and tech stack, demonstrating responsive design, dynamic content, and interactive UI components.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great readme! Very detailed :) My only input here is that you could mention that you used react already in first section.


The live project is available on [Netlify](https://kausarshangareeva-portfolio.netlify.app/).

---

## πŸ”— Demo

Check it out here: [Kausar Portfolio on Netlify](https://kausarshangareeva-portfolio.netlify.app/)

---

## πŸ“Έ Screenshot

## ![Portfolio Screenshot](public/Image/portfolio-screen.png)

## πŸš€ Features

- πŸ‘‹ **Hero Section:** Intro with images and description
- πŸ› οΈ **Tech Section:** List of technologies and skills with interactive tags
- πŸ—οΈ **Featured Projects Section:** Project cards with images, tags, descriptions, and action buttons
- πŸ’» **Skills Section:** Skills and tools displayed in responsive columns
- πŸ“š **Blog Section:** Articles with images, titles, dates, and buttons for reading
- πŸ“± Fully **responsive layout** β€” adapts for desktop, tablet, and mobile
- 🎨 **Interactive UI components:** Buttons, tags, cards, burger menu
- 🌟 **Data-driven content** from JSON files for projects, skills, articles, and tech

---

## 🧰 Tech Stack / What I Built With

- **React.js** for building modular and reusable components
- **Styled-Components** for styling and media queries
- **JavaScript (ES6+)** for logic, mapping, filtering, and dynamic rendering
- **JSON** files to manage structured data: aboutMe, projectsData, articlesData, skillsData, techData
- **Vite** for fast development and bundling
- **SVG Icons & Lucide** for interactive icons and buttons

---

## 🧠 How It Works

1. **Hero Section**: Displays greeting text with animated images.
2. **Tech Section**: Shows my tech stack with dynamic tags.
3. **Featured Projects Section**: Projects rendered dynamically with images, descriptions, and action buttons. Layout adapts for even/odd projects.
4. **Skills Section**: Highlights my skills with interactive tags in columns.
5. **Blog Section**: Articles displayed from JSON data, including image, title, description, and publication date.
6. **Footer Section**: Contains contact info, social icons, and avatar.
7. **Responsive Design**: Uses styled-components media queries to adjust layout, images, and typography for different screen sizes.
8. **Dynamic Content**: All sections fetch data from JSON files, making it easy to update or expand.

---

## πŸ“‚ File Structure

```
src/
β”‚
β”œβ”€β”€ πŸ“‚ data/
β”‚ β”œβ”€β”€ aboutMe.json
β”‚ β”œβ”€β”€ projectsData.json
β”‚ β”œβ”€β”€ articlesData.json
β”‚ └── skillsData.json
β”‚ └── techData.json
β”‚
β”œβ”€β”€ πŸ“‚ Assets/
β”‚ β”œβ”€β”€ Button/
β”‚ β”‚ β”œβ”€β”€ ButtonIcons/
β”‚ β”‚ β”œβ”€β”€ Button.jsx
β”‚ β”‚ └── ButtonData.js
β”‚ β”‚
β”‚ β”œβ”€β”€ Tag/
β”‚ β”‚ β”œβ”€β”€ TagIcins/
β”‚ β”‚ β”œβ”€β”€ TagComponents.jsx
β”‚ β”‚ └── TagData.js
β”‚ β”‚
β”‚ β”œβ”€β”€ Typography
β”‚ β”‚
β”‚ β”œβ”€β”€ Image/
β”‚ β”‚ β”œβ”€β”€ ImagBlog/
β”‚ β”‚ β”œβ”€β”€ ImagHero/
β”‚ β”‚ └── ImagProject/
β”‚ β”‚
β”‚ └── Icon/
β”‚ β”œβ”€β”€ Icons/
β”‚ └── IconData.js
|
|
β”œβ”€β”€ πŸ“‚ Styles/
β”‚ β”‚
β”‚ └── HeroSection/
β”‚ β”œβ”€β”€ GlobalStyles.js
β”‚ └── responsive.js
β”‚
β”œβ”€β”€ πŸ“‚ Sections/
β”‚ β”‚
β”‚ β”œβ”€β”€ HeroSection/
β”‚ β”‚ β”œβ”€β”€ HeroSection.jsx
β”‚ β”‚ β”œβ”€β”€ HeroSection.styles.js
β”‚ β”‚ └── components/
β”‚ β”‚ β”œβ”€β”€ HeroImages.jsx
β”‚ β”‚ └── HeroDescription.jsx
β”‚ β”‚
β”‚ β”œβ”€β”€ TechSection/
β”‚ β”‚ β”œβ”€β”€ TechSection.jsx
β”‚ β”‚ └── components/
β”‚ β”‚ β”œβ”€β”€ TechColumn.jsx
β”‚ β”‚ β”œβ”€β”€ TechTagList.jsx
β”‚ β”‚ └── TechTagItem.jsx
β”‚ β”‚
β”‚ β”œβ”€β”€ FeaturedProjectsSection/
β”‚ β”‚ β”œβ”€β”€ FeaturedProjectsSection.jsx
β”‚ β”‚ └── components/
β”‚ β”‚ β”œβ”€β”€ ProjectCard.jsx
β”‚ β”‚ β”œβ”€β”€ ProjectImage.jsx
β”‚ β”‚ β”œβ”€β”€ ProjectTags.jsx
β”‚ β”‚ β”œβ”€β”€ ProjectTitle.jsx
β”‚ β”‚ β”œβ”€β”€ ProjectDescription.jsx
β”‚ β”‚ └── ProjectButtons.jsx
β”‚ β”‚
β”‚ β”œβ”€β”€ SkillsSection/
β”‚ β”‚ β”œβ”€β”€ SkillsSection.jsx
β”‚ β”‚ └── components/
β”‚ β”‚ β”œβ”€β”€ SkillsColumn.jsx
β”‚ β”‚ β”œβ”€β”€ SkillsTagList.jsx
β”‚ β”‚ └── SkillsTagItem.jsx
β”‚ β”‚
β”‚ β”œβ”€β”€ BlogSection/
β”‚ β”‚ β”œβ”€β”€ BlogSection.jsx
β”‚ β”‚ └── components/
β”‚ β”‚ β”œβ”€β”€ BlogCard.jsx
β”‚ β”‚ β”œβ”€β”€ BlogImage.jsx
β”‚ β”‚ β”œβ”€β”€ BlogDate.jsx
β”‚ β”‚ β”œβ”€β”€ BlogTitle.jsx
β”‚ β”‚ β”œβ”€β”€ BlogDescription.jsx
β”‚ β”‚ └── BlogButton.jsx
β”‚ β”‚
β”‚ └── FooterSection/
β”‚ β”œβ”€β”€ FooterSection.jsx
β”‚ └── components/
β”‚ β”œβ”€β”€ Avatar.jsx
β”‚ β”œβ”€β”€ FooterContacts.jsx
β”‚ └── FooterIcons.jsx
β”‚
|── App.jsx
└── main.jsx
```

---

## πŸ“ What I Learned

- Structuring a React project with multiple sections and reusable components
- Creating **responsive layouts** with styled-components and media queries
- Dynamically rendering content from JSON using `.map()`
- Implementing **interactive UI elements** like buttons, tags, and cards
- Handling images and icons for different screen sizes
- Managing props and component state effectively
- Combining frontend design and programming skills to build a full portfolio website

---

## πŸ”œ Next Steps

- Add filtering and search for projects and blog posts
- Implement dark/light mode toggle
- Add a contact form with email submission
- Optimize images for performance and faster loading
- Expand blog section with categories and pagination

---

## πŸ“„ License

This project is free to use for educational purposes.
2 changes: 2 additions & 0 deletions desktop.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[LocalizedFileNames]
portfolio-screen.png=@portfolio-screen,0
10 changes: 8 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"
/>
<link rel="icon" type="image/svg+xml" href="/Kausar-svg.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Portfolio</title>
</head>
Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"sass": "^1.94.2",
"styled-components": "^6.1.19"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
Expand All @@ -22,6 +24,7 @@
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^15.15.0",
"vite": "^6.2.0"
"vite": "^6.2.0",
"vite-plugin-svgr": "^4.5.0"
}
}
Binary file added public/Image/ImgBlog/BlogImage-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgHero/FooterLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgHero/HeroImage1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgHero/HeroImage2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgHero/HeroImage3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgProjects/Favorite-Dessert-img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgProjects/Pet-foster-img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgProjects/Real-Estate.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/ImgProjects/Weather-App-img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/Image/portfolio-screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
140 changes: 140 additions & 0 deletions public/Kausar-svg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion pull_request_template.md

This file was deleted.

21 changes: 17 additions & 4 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
export const App = () => {
import { GlobalStyles } from "./styles/GlobalStyles";
import HeroSection from "./Sections/HeroSection/HeroSection";
import TechSection from "./Sections/TechSection/TechSection";
import FeaturedProjectsSection from "./Sections/FeaturedProjectsSection/FeaturedProjectsSection";
import SkillsSection from "./Sections/SkillsSection/SkillsSection";
import BlogSection from "./Sections/BlogSection/BlogSection";
import FooterSection from "./Sections/FooterSection/FooterSection";

export default function App() {
return (
<>
<h1>Portfolio</h1>
<p>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.</p>
<GlobalStyles />
<HeroSection />
<TechSection />
<FeaturedProjectsSection />
<SkillsSection />
<BlogSection />
<FooterSection />
Comment on lines +12 to +18

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice and clean structure in App

</>
)
);
}
34 changes: 34 additions & 0 deletions src/Sections/BlogSection/BlogSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { BlogCard } from "./components/BlogCard";
import { SectionTitle } from "../../assets/Typography";
import articlesData from "../../data/articlesData.json";
import styled from "styled-components";
import { respond } from "../../styles/responsive";

const SectionStyle = styled.section`
padding: 0 16px;
`;

const SectionDiv = styled.div`
display: flex;
flex-direction: column;
gap: 120px;
max-width: 1000px;
margin: 0 auto;

${respond("tab-port")} {
gap: 100px;
}
`;

export default function BlogSection() {
return (
<SectionStyle>
<SectionDiv>
<SectionTitle>My words</SectionTitle>
{articlesData.articles.map((article, index) => (
<BlogCard data={article} key={article.id} index={index} />
))}
</SectionDiv>
</SectionStyle>
);
}
17 changes: 17 additions & 0 deletions src/Sections/BlogSection/components/BlogButtons.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { BlackButton } from "../../../assets/Button/Button";
import styled from "styled-components";

const ButtonBox = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
`;

export default function BlogButtons({ button }) {
return (
<ButtonBox>
{button &&
button.map((btn) => <BlackButton type={btn.name} href={btn.link} />)}
</ButtonBox>
);
}
38 changes: 38 additions & 0 deletions src/Sections/BlogSection/components/BlogCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import BlogImage from "./BlogImage";
import BlogTitle from "./BlogTitle";
import BlogDescription from "./BlogDescription";
import BlogDate from "./BlogDate";
import BlogButtons from "./BlogButtons";
import styled from "styled-components";
import { respond } from "../../../styles/responsive";

const DivStyle = styled.div`
display: flex;
align-items: center;
gap: 120px;

${respond("tab-port")} {
flex-direction: column;
gap: 50px;
}
`;

const DivBox = styled.div`
display: flex;
flex-direction: column;
gap: 30px;
`;

export function BlogCard({ data }) {
return (
<DivStyle className="projectCard">
<BlogImage src={data.imgSrc} alt={data.imgtitle} />
<DivBox>
<BlogDate date={data.date} />
<BlogTitle title={data.title} />
<BlogDescription desc={data.desc} />
<BlogButtons button={data.button} />
</DivBox>
</DivStyle>
);
}
21 changes: 21 additions & 0 deletions src/Sections/BlogSection/components/BlogDate.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from "styled-components";

const DateStyle = styled.span`
display: inline-block;
width: fit-content;
padding: 6px 13px;
font-weight: bold;
font-size: 18px;
background: rgba(255, 255, 255, 0.39);
border-radius: 10px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.014);
backdrop-filter: blur(10.8px);
-webkit-backdrop-filter: blur(10.8px);
border: 1px solid rgba(255, 255, 255, 1);
color: #000;
border: 2px solid #000;
`;

export default function BlogDate({ date }) {
return <DateStyle>{date}</DateStyle>;
}
5 changes: 5 additions & 0 deletions src/Sections/BlogSection/components/BlogDescription.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Paragraph } from "../../../assets/Typography";

export default function BlogDescription({ desc }) {
return <Paragraph>{desc}</Paragraph>;
}
18 changes: 18 additions & 0 deletions src/Sections/BlogSection/components/BlogImage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import styled from "styled-components";
import { respond } from "../../../styles/responsive";

const ImgStyle = styled.img`
width: 400px;
height: 400px;
border-radius: 20px;
object-fit: cover;

${respond("tab-port")} {
width: 100%;
max-width: 800px;
height: 400px;
}
`;
export default function BlogImage({ src, alt }) {
return <ImgStyle src={src} alt={alt} />;
}
5 changes: 5 additions & 0 deletions src/Sections/BlogSection/components/BlogTitle.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { TitleH3 } from "../../../assets/Typography";

export default function BlogTitle({ title }) {
return <TitleH3 align="Left">{title}</TitleH3>;
}
Loading