Compare commits
12 Commits
56e8c2c252
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cfdd61cc2 | |||
| d9bdf12328 | |||
| d00712c287 | |||
| 59dd998a5d | |||
| 8d440c1993 | |||
| b855cc9127 | |||
| fe463c4fcb | |||
| 29218b0e38 | |||
| cd684dbaf7 | |||
| 6b9522153f | |||
| 805bd07eb4 | |||
| e08c2d4013 |
@@ -1,2 +1,151 @@
|
|||||||
# seccodesmith-frontend
|
# SecCodeSmith Frontend Portfolio
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
A modern portfolio website with a unique fantasy blacksmith and dragon theme, showcasing my development skills and projects.
|
||||||
|
|
||||||
|
## 🐉 About
|
||||||
|
|
||||||
|
This portfolio represents my journey as a developer, designed with the aesthetic of a fantasy blacksmith working alongside dragons. The site combines modern web technologies with creative storytelling to create an engaging user experience.
|
||||||
|
|
||||||
|
**Live Demo**: [https://seccodesmith.pl](https://seccodesmith.pl)
|
||||||
|
|
||||||
|
## 🛠️ Built With
|
||||||
|
|
||||||
|
- **[Vite](https://vitejs.dev/)** - Next Generation Frontend Tooling
|
||||||
|
- **[React](https://reactjs.org/)** - JavaScript library for building user interfaces
|
||||||
|
- **[TypeScript](https://www.typescriptlang.org/)** - JavaScript with syntax for types
|
||||||
|
- **[SCSS](https://sass-lang.com/)** - CSS preprocessor for better styling
|
||||||
|
|
||||||
|
## 📋 Prerequisites
|
||||||
|
|
||||||
|
Before you begin, ensure you have the following installed:
|
||||||
|
- **Node.js** (v16.0.0 or higher)
|
||||||
|
- **npm** (v8.0.0 or higher) or **yarn** (v1.22.0 or higher)
|
||||||
|
|
||||||
|
You can check your versions by running:
|
||||||
|
```bash
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🚀 Getting Started
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
```bash
|
||||||
|
git clone https://git.seccodesmith.pl/seccodesmith/seccodesmith-frontend.git
|
||||||
|
cd seccodesmith-frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install dependencies:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
# or
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running the Project
|
||||||
|
|
||||||
|
#### Development Mode
|
||||||
|
To run the project in development mode with hot-reload:
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
The application will be available at `http://localhost:5173` (default Vite port).
|
||||||
|
|
||||||
|
#### Production Build
|
||||||
|
To build the project for production:
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
# or
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Preview Production Build
|
||||||
|
To preview the production build locally:
|
||||||
|
```bash
|
||||||
|
npm run preview
|
||||||
|
# or
|
||||||
|
yarn preview
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
seccodesmith-frontend/
|
||||||
|
├── src/
|
||||||
|
│ ├── assets/ # Images, fonts, and other static assets
|
||||||
|
│ ├── components/ # React components
|
||||||
|
│ ├── styles/ # SCSS files
|
||||||
|
│ ├── pages/ # Page components
|
||||||
|
│ ├── utils/ # Utility functions
|
||||||
|
│ ├── App.tsx # Main App component
|
||||||
|
│ └── main.tsx # Application entry point
|
||||||
|
├── public/ # Public static files
|
||||||
|
├── index.html # HTML template
|
||||||
|
├── vite.config.ts # Vite configuration
|
||||||
|
├── tsconfig.json # TypeScript configuration
|
||||||
|
├── package.json # Project dependencies and scripts
|
||||||
|
└── README.md # Project documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
- Responsive design that works on all devices
|
||||||
|
- Interactive animations and transitions
|
||||||
|
- Dark/Light theme toggle
|
||||||
|
- Project showcase with detailed descriptions
|
||||||
|
- Contact form integration
|
||||||
|
- Performance optimized with Vite
|
||||||
|
|
||||||
|
## 🧪 Available Scripts
|
||||||
|
|
||||||
|
- `npm run dev` - Start development server
|
||||||
|
- `npm run build` - Build for production
|
||||||
|
- `npm run preview` - Preview production build
|
||||||
|
- `npm run lint` - Run ESLint
|
||||||
|
- `npm run type-check` - Run TypeScript compiler check
|
||||||
|
|
||||||
|
## 🎨 Customization
|
||||||
|
|
||||||
|
To customize the portfolio for your own use:
|
||||||
|
|
||||||
|
1. Update personal information in `src/data/personal.ts`
|
||||||
|
2. Replace projects in `src/data/projects.ts`
|
||||||
|
3. Modify color schemes in `src/styles/variables.scss`
|
||||||
|
4. Update images in `src/assets/`
|
||||||
|
|
||||||
|
## 📄 License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
## 🤝 Contributing
|
||||||
|
|
||||||
|
While this is a personal portfolio project, suggestions and feedback are welcome! Feel free to:
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create a feature branch (`git checkout -b feature/AmazingFeature`)
|
||||||
|
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
||||||
|
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
||||||
|
5. Open a Pull Request
|
||||||
|
|
||||||
|
## 📬 Contact
|
||||||
|
|
||||||
|
**SecCodeSmith** - [contact@seccodesmith.pl](mailto:contact@seccodesmith.pl)
|
||||||
|
|
||||||
|
Project Link: [https://git.seccodesmith.pl/seccodesmith/seccodesmith-frontend](https://git.seccodesmith.pl/seccodesmith/seccodesmith-frontend)
|
||||||
|
|
||||||
|
## 🙏 Acknowledgments
|
||||||
|
|
||||||
|
- Inspiration from fantasy blacksmith and dragon themes
|
||||||
|
- [React Icons](https://react-icons.github.io/react-icons/) for icon library
|
||||||
|
- [Vite Documentation](https://vitejs.dev/guide/) for build tool guidance
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
⚔️ Forged with passion by SecCodeSmith 🐲
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"coreValues": [
|
||||||
|
{
|
||||||
|
"title": "Security by Design",
|
||||||
|
"icon": "fas fa-shield-alt",
|
||||||
|
"description": "Security is not an afterthought but the very foundation upon which robust systems are built. Every line of code is crafted with defensive principles in mind."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-tachometer-alt",
|
||||||
|
"title": "Performance Optimization",
|
||||||
|
"description": "Like a finely-honed blade, code should be both effective and efficient. I meticulously optimize every component for maximum speed and minimal resource consumption."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-gem",
|
||||||
|
"title": "Elegant Simplicity",
|
||||||
|
"description": "True mastery is revealed not in complexity but in elegant simplicity. I strive to create solutions that are accessible, maintainable, and beautifully crafted."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-sync-alt",
|
||||||
|
"title": "Continuous Evolution",
|
||||||
|
"description": "The digital landscape changes with the seasons. I embrace continuous learning and adaptation, integrating new techniques and technologies to forge ever-better solutions."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"technicalArsenal": [
|
||||||
|
{
|
||||||
|
"icon": "fas fa-microchip",
|
||||||
|
"title": "Embedded Systems",
|
||||||
|
"skills": [
|
||||||
|
"STM32 microcontroller programming (I2C, SPI, UART)",
|
||||||
|
"ESP32 wireless solutions",
|
||||||
|
"Firmware development with C/C++",
|
||||||
|
"Raspberry Pi and Pico-SDK integration",
|
||||||
|
"RTOS implementation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-brain",
|
||||||
|
"title": "AI & Data Analysis",
|
||||||
|
"skills": [
|
||||||
|
"Machine learning with PyTorch",
|
||||||
|
"Data manipulation with Pandas",
|
||||||
|
"Predictive modeling via Scikit-learn",
|
||||||
|
"Computer vision with Scikit-image",
|
||||||
|
"Edge AI deployment"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-window-maximize",
|
||||||
|
"title": "Web Development",
|
||||||
|
"skills": [
|
||||||
|
"Web Development",
|
||||||
|
"Backend development with ASP.NET",
|
||||||
|
"Database management with Entity Framework",
|
||||||
|
"Frontend frameworks: Blazor, React",
|
||||||
|
"Responsive design with Bootstrap",
|
||||||
|
"Python-based web solutions with Django"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-server",
|
||||||
|
"title": "DevOps & Infrastructure",
|
||||||
|
"skills": [
|
||||||
|
"Containerization with Docker",
|
||||||
|
"Multi-container orchestration via Docker-compose",
|
||||||
|
"Linux server administration",
|
||||||
|
"CI/CD pipeline implementation",
|
||||||
|
"Build system configuration with CMake"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"professionalJourney": [
|
||||||
|
{
|
||||||
|
"title": "Student at Rzeszów University of Technology",
|
||||||
|
"description": "Specialization: Computer Science",
|
||||||
|
"duration": "2021.10 - 2025.6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "intern software engineer at Opeteam S.A.",
|
||||||
|
"description": "- Performing programming tasks in R&D projects within the product development department,\n - Database administration, \n - Defining unit tests and manual testing of solutions, \n - Selecting technologies for basic problems, - Documenting the source code (technical documentation)., \n",
|
||||||
|
"duration": "2022.8 - 2023.4"
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
"testimonials": [
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"slug": "StartOFJurney",
|
||||||
|
"title": "Something ends, something begins.",
|
||||||
|
"excerpt": "",
|
||||||
|
"image": "images/Begining.jpg",
|
||||||
|
"category": "Story",
|
||||||
|
"date": "27-05-2025",
|
||||||
|
"author": "SecCodeSmith (Jakub)",
|
||||||
|
"commentCount": 0,
|
||||||
|
"readTime": "10m",
|
||||||
|
"featured": true,
|
||||||
|
"tags": [
|
||||||
|
"journey"
|
||||||
|
],
|
||||||
|
"content": "# I created this blog as the start of building my professional image, \n a place to document my projects and share my experiences. It's also a personal challenge for me. \n I am about to finish my studies and step into a new chapter of my professional life. \n On this blog, I will describe my projects and the lessons I've learned along the way. \n My first project will be creating my own website, featuring a blog, information about me, and descriptions of my work. \n See you soon!"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"email": "forge@seccodesmith.pl",
|
||||||
|
"businessEmail": "business@seccodesmith.pl",
|
||||||
|
"socialLinks": [
|
||||||
|
{ "platform": "LinkedIn", "url": "https://www.linkedin.com/in/jakub-berechowski", "icon": "fab fa-linkedin" },
|
||||||
|
{ "platform": "GitHub", "url": "https://github.com/seccodesmith", "icon": "fab fa-github" },
|
||||||
|
{ "platform": "Facebook", "url": "https://www.facebook.com/people/Seccodesmith/61575058536717/", "icon": "fab fa-facebook" }
|
||||||
|
],
|
||||||
|
"questionsAndAnswers": [
|
||||||
|
{ "question": "What is your typical project timeline?", "answer": "Project timelines vary based on complexity and scope. Small projects typically take 2-4 weeks, medium-sized projects 1-2 months, and larger enterprise solutions 3-6 months. I provide detailed timeline estimates during the initial consultation, and maintain transparent communication about progress throughout the development cycle." },
|
||||||
|
{ "question": "How does your collaboration process work?", "answer": "My collaboration process consists of five phases: initial consultation, requirements gathering, design and planning, implementation, and testing/deployment. I use agile methodologies with regular check-ins to ensure your vision is being realized. Communication is maintained through your preferred channels (email, Slack, etc.), and you\"ll have access to development milestones through shared repositories and project management tools." },
|
||||||
|
{ "question": "What are your payment terms and methods?", "answer": "I typically work with a milestone-based payment structure: 30% upfront to begin work, 30% at the midpoint after key deliverables are approved, and 40% upon project completion. For longer projects, we can establish additional milestones. I accept bank transfers, PayPal, and cryptocurrency payments. All payment terms are clearly outlined in the project contract before work begins."},
|
||||||
|
{ "question": "Who owns the code and deliverables?", "answer": "Upon final payment, you receive full ownership rights to all custom code and deliverables created specifically for your project. I maintain no proprietary claim to custom solutions developed for clients. For projects that incorporate open-source components, those elements remain under their original licenses, and I provide clear documentation of all third-party code used in your project." },
|
||||||
|
{ "question": "Do you offer support and maintenance?", "answer": "Yes, I offer a 30-day warranty period for all projects, during which bug fixes and minor adjustments are covered at no additional cost. For ongoing support, I provide maintenance packages that include regular updates, security patches, and priority response times. These can be tailored to your specific needs and budget, whether you require occasional support or dedicated monthly maintenance."}
|
||||||
|
],
|
||||||
|
"MapIframeUrl": "https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d82077.2903513271!2d21.9433946!3d50.0411861!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x473cfae3cc14d449%3A0xd2240d31b33eb2ed!2zUnplc3rDs3c!5e0!3m2!1sen!2spl!4v1651813309336!5m2!1sen!2spl",
|
||||||
|
"phone": ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "SecCodeSmithFrontend",
|
||||||
|
"title": "SecCodeSmith Portfolio Page - Frontend",
|
||||||
|
"description": "A modern, responsive portfolio page showcasing my projects, skills, and blog posts. Built with React and styled-components for a sleek user interface.",
|
||||||
|
"image": "/images/SecCodeSmithFrontProj/Main.png",
|
||||||
|
"category": ["Web"],
|
||||||
|
"featured": true,
|
||||||
|
"technologies": [
|
||||||
|
{ "name": "React", "icon": "devicon-react-original tech-icon" },
|
||||||
|
{ "name": "TypeScript", "icon": "devicon-typescript-plain tech-icon" },
|
||||||
|
{ "name": "SCSS", "icon": "devicon-sass-original tech-icon" },
|
||||||
|
{ "name": "Vite", "icon": "devicon-vitejs-plain tech-icon" }
|
||||||
|
],
|
||||||
|
"links": {
|
||||||
|
"github": "https://github.com/SecCodeSmith/",
|
||||||
|
"demo": "https://seccodesmith.pl"
|
||||||
|
},
|
||||||
|
"projectDetails": {
|
||||||
|
"descriptions": [
|
||||||
|
"This portfolio page is designed to highlight my skills and projects in a visually appealing way. It features a clean layout, smooth animations, and responsive design for optimal viewing on all devices.",
|
||||||
|
"The project utilizes React for building the user interface, TypeScript for type safety, and SCSS for styling. The use of Vite ensures fast development and build times."
|
||||||
|
],
|
||||||
|
"startDate": "12-05-2025",
|
||||||
|
"endDate": "",
|
||||||
|
"dateFormatted": "DD MMMM YYYY",
|
||||||
|
"role": "Frontend Developer",
|
||||||
|
"status": "In Progress",
|
||||||
|
"keyFeatures": [
|
||||||
|
"Responsive design with mobile-first approach",
|
||||||
|
"Dynamic project showcase with filtering options",
|
||||||
|
"Interactive blog section with latest posts"
|
||||||
|
],
|
||||||
|
"gallery": ["/images/SecCodeSmithFrontProj/1.png", "/images/SecCodeSmithFrontProj/2.png", "/images/SecCodeSmithFrontProj/3.png", "/images/SecCodeSmithFrontProj/4.png" ],
|
||||||
|
"fullTechStack": [
|
||||||
|
{ "name": "React", "icons": "devicon-react-original" },
|
||||||
|
{ "name": "TypeScript", "icons": "devicon-typescript-plain" },
|
||||||
|
{ "name": "SCSS", "icons": "devicon-sass-original" },
|
||||||
|
{ "name": "Vite", "icons": "devicon-vitejs-plain" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"categoryIcon": "fa-code",
|
||||||
|
"categoryTitle": "Languages",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "C/C++", "icon": "devicon-cplusplus-plain" },
|
||||||
|
{ "name": "Python", "icon": "devicon-python-plain" },
|
||||||
|
{ "name": ".NET", "icon": "devicon-dotnetcore-plain" },
|
||||||
|
{ "name": "C#", "icon": "devicon-csharp-plain" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"categoryIcon": "fa-microchip",
|
||||||
|
"categoryTitle": "Embedded Systems",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "STM32 (I2C, SPI, UART)", "icon": "fas fa-microchip" },
|
||||||
|
{ "name": "ESP32", "icon": "fas fa-wifi" },
|
||||||
|
{ "name": "Pico-SDK", "icon": "fas fa-memory" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"categoryIcon": "fa-brain",
|
||||||
|
"categoryTitle": "Data & ML",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "Pandas", "icon": "devicon-pandas-plain" },
|
||||||
|
{ "name": "Scikit-learn", "icon": "devicon-scikitlearn-plain" },
|
||||||
|
{ "name": "Scikit-image", "icon": "fas fa-image" },
|
||||||
|
{ "name": "PyTorch", "icon": "devicon-pytorch-plain" },
|
||||||
|
{ "name": "OpenCV", "icon": "devicon-opencv-plain" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"categoryIcon": "fas fa-window-maximize",
|
||||||
|
"categoryTitle": "Web Development",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "ASP.NET Core", "icon": "devicon-dot-net-plain" },
|
||||||
|
{ "name": "Entity Framework", "icon": "fas fa-database" },
|
||||||
|
{ "name": "Blazor", "icon": "devicon-dotnetcore-plain" },
|
||||||
|
{ "name": "React", "icon": "devicon-react-original" },
|
||||||
|
{ "name": "Django", "icon": "devicon-django-plain" },
|
||||||
|
{ "name": "Bootstrap", "icon": "devicon-bootstrap-plain" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"categoryIcon": "fas fa-cloud",
|
||||||
|
"categoryTitle": "DevOps & Systems",
|
||||||
|
"skills": [
|
||||||
|
{ "name": "Docker", "icon": "devicon-docker-plain" },
|
||||||
|
{ "name": "Docker-compose", "icon": "fas fa-layer-group" },
|
||||||
|
{ "name": "Linux CLI", "icon": "devicon-bash-plain" },
|
||||||
|
{ "name": "Git", "icon": "devicon-git-plain" },
|
||||||
|
{ "name": "CI/CD", "icon": "fas fa-cogs" },
|
||||||
|
{ "name": "Cmake", "icon": "devicon-cmake-plain" },
|
||||||
|
{ "name": "Linux", "icon": "devicon-linux-plain" },
|
||||||
|
{ "name": "Jenkins", "icon": "devicon-jenkins-plain" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"icon": "fab fa-github",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fab fa-linkedin",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fab fa-twitter",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fab fa-discord",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"icon": "fas fa-envelope",
|
||||||
|
"url": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
After Width: | Height: | Size: 518 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 847 KiB |
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
@@ -0,0 +1,41 @@
|
|||||||
|
@use './variables.scss' as *;
|
||||||
|
|
||||||
|
/* Accordion styling */
|
||||||
|
.accordion-button {
|
||||||
|
background-color: $card-bg !important;
|
||||||
|
color: $text-light !important;
|
||||||
|
border-color: $card-border !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
font-family: 'Cinzel', serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-button:not(.collapsed) {
|
||||||
|
color: $accent-fire !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-button:focus {
|
||||||
|
border-color: $accent-fire !important;
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.25) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-button::after {
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ff6400'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-item {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-body {
|
||||||
|
background-color: $card-bg;
|
||||||
|
border: 1px solid $card-border;
|
||||||
|
border-top: none;
|
||||||
|
color: $text-ash;
|
||||||
|
padding: 1.25rem;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
border-bottom-left-radius: 0.375rem;
|
||||||
|
border-bottom-right-radius: 0.375rem;
|
||||||
|
}
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
@use './variables' as *;
|
||||||
|
@use './card.scss' as card;
|
||||||
|
|
||||||
|
@include card.card;
|
||||||
|
|
||||||
|
/* Card styling */
|
||||||
|
.contactCard {
|
||||||
|
position: relative;
|
||||||
|
border-left: 3px solid $accent-fire;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactIcon {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgba(255, 100, 0, 0.1);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: $accent-fire;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactTitle {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
color: $text-light;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactContent {
|
||||||
|
color: $text-ash;
|
||||||
|
line-height: 1.6;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactLink {
|
||||||
|
color: $accent-fire;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contactLink:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: $accent-ember;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button styling */
|
||||||
|
.btnPrimary {
|
||||||
|
background: linear-gradient(45deg, $accent-dragon, $accent-fire);
|
||||||
|
border: none;
|
||||||
|
padding: 0.75rem 2rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
box-shadow: 0 4px 15px rgba(139, 0, 0, 0.3);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 7px 25px rgba(139, 0, 0, 0.5);
|
||||||
|
background-color: $accent-fire;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary:focus {
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
transition: 0.6s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btnPrimary:disabled {
|
||||||
|
background: linear-gradient(45deg, rgba(139, 0, 0, 0.5), rgba(255, 100, 0, 0.5));
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Social links styling */
|
||||||
|
.socialGrid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||||
|
gap: 15px;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.socialItem {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.socialItem:hover {
|
||||||
|
background-color: rgba(255, 100, 0, 0.1);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.socialIconLg {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
color: $accent-fire;
|
||||||
|
}
|
||||||
|
|
||||||
|
.socialName {
|
||||||
|
color: $text-ash;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map styling */
|
||||||
|
.mapContainer {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid $card-border;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapContainer::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
background: linear-gradient(to right, $accent-dragon, $accent-fire);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapFrame {
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
border: none;
|
||||||
|
background-color: $card-bg;
|
||||||
|
filter: grayscale(90%) invert(92%) hue-rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Binary background effect */
|
||||||
|
.binaryLine {
|
||||||
|
position: absolute;
|
||||||
|
font-family: 'Fira Code', monospace;
|
||||||
|
color: $accent-fire;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: 0.15;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ember effect */
|
||||||
|
.emberParticle {
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 3px;
|
||||||
|
background-color: $accent-fire;
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.6;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 2;
|
||||||
|
box-shadow: 0 0 5px $accent-fire;
|
||||||
|
animation: float 3s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0% {
|
||||||
|
transform: translateY(0) rotate(0deg);
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateY(-100px) rotate(360deg);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table styling */
|
||||||
|
.table {
|
||||||
|
color: $text-ash;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td {
|
||||||
|
padding: 0.5rem 0.25rem;
|
||||||
|
border-color: rgba(255, 255, 255, 0.05);
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.schedule-container {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social-grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-frame {
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
.social-grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-floating>label {
|
||||||
|
padding: 0.75rem 0.75rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
@use './variables.scss' as *;
|
||||||
|
|
||||||
|
/* Form styling */
|
||||||
|
.form-control {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid var(--card-border);
|
||||||
|
color: var(--text-light);
|
||||||
|
padding: 0.75rem 0.9375rem;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus {
|
||||||
|
background-color: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: var(--accent-fire);
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.25);
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control::placeholder {
|
||||||
|
color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.form-control {
|
||||||
|
min-height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
color: var(--text-ash);
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-text {
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
border: 1px solid var(--card-border);
|
||||||
|
color: var(--text-light);
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ff6400' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select:focus {
|
||||||
|
background-color: rgba(255, 255, 255, 0.08);
|
||||||
|
border-color: var(--accent-fire);
|
||||||
|
box-shadow: 0 0 0 0.25rem rgba(255, 100, 0, 0.25);
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select option {
|
||||||
|
background-color: var(--card-bg);
|
||||||
|
color: var(--text-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alert styling */
|
||||||
|
.alert-success {
|
||||||
|
background-color: rgba(25, 135, 84, 0.1);
|
||||||
|
border-color: rgba(25, 135, 84, 0.3);
|
||||||
|
color: #75b798;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-danger {
|
||||||
|
background-color: rgba(220, 53, 69, 0.1);
|
||||||
|
border-color: rgba(220, 53, 69, 0.3);
|
||||||
|
color: #ea868f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form validation styling */
|
||||||
|
.was-validated .form-control:invalid,
|
||||||
|
.form-control.is-invalid {
|
||||||
|
border-color: #dc3545;
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right calc(0.375em + 0.1875rem) center;
|
||||||
|
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.was-validated .form-control:valid,
|
||||||
|
.form-control.is-valid {
|
||||||
|
border-color: #198754;
|
||||||
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right calc(0.375em + 0.1875rem) center;
|
||||||
|
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.invalid-feedback {
|
||||||
|
color: #dc3545;
|
||||||
|
font-size: 0.875em;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ $text-ash: #aaaaaa;
|
|||||||
$card-bg: #141414;
|
$card-bg: #141414;
|
||||||
$card-border: #2a2a2a;
|
$card-border: #2a2a2a;
|
||||||
$code-bg: #1e1e1e;
|
$code-bg: #1e1e1e;
|
||||||
|
$font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
|
||||||
// Effects
|
// Effects
|
||||||
$glow-effect: 0 0 10px $accent-fire, 0 0 20px rgba(255, 100, 0, 0.4);
|
$glow-effect: 0 0 10px $accent-fire, 0 0 20px rgba(255, 100, 0, 0.4);
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
@use './variables.scss' as *;
|
||||||
|
|
||||||
|
/* Card styling */
|
||||||
|
@mixin card {
|
||||||
|
.card {
|
||||||
|
background-color: $card-bg;
|
||||||
|
border: 1px solid $card-border;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-7px);
|
||||||
|
border-color: rgba(255, 100, 0, 0.3);
|
||||||
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 5px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: linear-gradient(to right, $accent-dragon, $accent-fire);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
.card-body {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ export const BlogCard: React.FC<BlogCardProps> = ({ post }) => {
|
|||||||
return (
|
return (
|
||||||
<div className={`card ${styles.card} ${post.featured ? styles.featuredCard : ''}`}>
|
<div className={`card ${styles.card} ${post.featured ? styles.featuredCard : ''}`}>
|
||||||
<div className="position-relative">
|
<div className="position-relative">
|
||||||
<img src={post.image} className={`card-img-top ${post.featured ? styles.featuredImg : ''}`} alt={post.title} />
|
<img src={`${import.meta.env.BASE_URL}${post.image}`} className={`card-img-top ${post.featured ? styles.featuredImg : ''}`} alt={post.title} />
|
||||||
<div className={styles.categoryBadge}>{post.category}</div>
|
<div className={styles.categoryBadge}>{post.category}</div>
|
||||||
|
|
||||||
{post.featured && (
|
{post.featured && (
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { useState, type FormEvent } from 'react';
|
import { useState, type FormEvent } from 'react';
|
||||||
|
import '@styles/FormControl.scss'
|
||||||
|
import styles from '@styles/Contact.module.scss'
|
||||||
|
|
||||||
export const ContactForm = () => {
|
export const ContactForm = () => {
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
@@ -47,11 +49,11 @@ export const ContactForm = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card h-100">
|
<div className={`card h-100 ${styles.card}`}>
|
||||||
<div className="card-header bg-transparent">
|
<div className={`card-header bg-transparent ${styles.cardHeader}`}>
|
||||||
<h2 className="mb-0 py-2">Send a Message to the Forge</h2>
|
<h2 className="mb-0 py-2">Send a Message to the Forge</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body p-4">
|
<div className={`card-body p-4 ${styles.cardBody}`}>
|
||||||
{/* Success message */}
|
{/* Success message */}
|
||||||
{showSuccess && (
|
{showSuccess && (
|
||||||
<div className="alert alert-success" role="alert">
|
<div className="alert alert-success" role="alert">
|
||||||
@@ -176,7 +178,7 @@ export const ContactForm = () => {
|
|||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-primary position-relative"
|
className={`btn btn-primary position-relative ${styles.btnPrimary}`}
|
||||||
id="submit-button"
|
id="submit-button"
|
||||||
disabled={isSubmitting}
|
disabled={isSubmitting}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import {socialLinkData} from '../data/socialLinkData'
|
import {socialLinkData} from '../data/socialLinkData'
|
||||||
export interface socialLink {
|
import type {SocialLink} from '../untils/SocialLink'
|
||||||
icon: string;
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Footer = () => {
|
export const Footer = () => {
|
||||||
const socialLinks: socialLink[] = socialLinkData;
|
const socialLinks: SocialLink[] = socialLinkData;
|
||||||
|
|
||||||
const currentYear = new Date().getFullYear()
|
const currentYear = new Date().getFullYear()
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export const ProjectCard: React.FC<ProjectCardProps> = ({ project, onOpenDetails
|
|||||||
onMouseEnter={() => setHovered(true)}
|
onMouseEnter={() => setHovered(true)}
|
||||||
onMouseLeave={() => setHovered(false)}>
|
onMouseLeave={() => setHovered(false)}>
|
||||||
<div className={`position-relative`}>
|
<div className={`position-relative`}>
|
||||||
<img src={project.image} className={style.cardImgTop} alt={project.title} />
|
<img src={`${import.meta.env.BASE_URL}${project.image}`} className={style.cardImgTop} alt={project.title} />
|
||||||
<CategoryBadge category={project.category} />
|
<CategoryBadge category={project.category} />
|
||||||
</div>
|
</div>
|
||||||
<div className={`card-body d-flex flex-column ${style.cardBody}`}>
|
<div className={`card-body d-flex flex-column ${style.cardBody}`}>
|
||||||
|
|||||||
@@ -68,14 +68,15 @@ export const ProjectModal: React.FC<ProjectModalProps> = ({ project }) => {
|
|||||||
project.projectDetails?.keyFeatures && project.projectDetails.keyFeatures.length > 0 && (
|
project.projectDetails?.keyFeatures && project.projectDetails.keyFeatures.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<h4 className="mt-4 mb-3">Key Features</h4>
|
<h4 className="mt-4 mb-3">Key Features</h4>
|
||||||
|
<ul className={style.featuresList}>
|
||||||
{
|
{
|
||||||
project.projectDetails?.keyFeatures.map((feature, index) => (
|
project.projectDetails?.keyFeatures.map((feature, index) => (
|
||||||
<p key={index} className="mb-2">
|
<li key={index}>
|
||||||
<i className="fas fa-check-circle text-success me-2"></i>
|
|
||||||
{feature}
|
{feature}
|
||||||
</p>
|
</li>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
</ul>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,7 @@
|
|||||||
import styles from '@styles/SkillCard.module.scss';
|
import styles from '@styles/SkillCard.module.scss';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
export interface Skill {
|
import type {SkillCardProps} from '../untils/SkillCardProps';
|
||||||
name: string;
|
|
||||||
icon: React.ReactNode; // Or string if using CSS classes for icons
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SkillCardProps {
|
|
||||||
categoryTitle: string;
|
|
||||||
categoryIcon: React.ReactNode; // Or string
|
|
||||||
skills: Skill[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const SkillCard: React.FC<SkillCardProps> = ({ categoryTitle, categoryIcon, skills }) => {
|
const SkillCard: React.FC<SkillCardProps> = ({ categoryTitle, categoryIcon, skills }) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,127 +1,3 @@
|
|||||||
/* About Page Styles */
|
|
||||||
.profile-image {
|
|
||||||
width: 100%;
|
|
||||||
aspect-ratio: 1/1;
|
|
||||||
border-radius: 8px;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 3px solid rgba(255, 100, 0, 0.3);
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-image::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(45deg, rgba(255, 100, 0, 0.2), transparent);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-image img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
filter: contrast(1.1) brightness(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-text {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
line-height: 1.8;
|
|
||||||
color: var(--text-ash);
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-text p {
|
|
||||||
margin-bottom: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-text strong {
|
|
||||||
color: var(--text-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-text .accent {
|
|
||||||
color: var(--accent-fire);
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-link {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 8px 20px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
|
||||||
border-radius: 4px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: var(--text-light);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border: 1px solid var(--card-border);
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-link:hover {
|
|
||||||
background-color: rgba(255, 100, 0, 0.1);
|
|
||||||
transform: translateY(-3px);
|
|
||||||
border-color: var(--accent-fire);
|
|
||||||
color: var(--text-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.connect-icon {
|
|
||||||
color: var(--accent-fire);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Value cards */
|
|
||||||
.value-card {
|
|
||||||
background-color: var(--card-bg);
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 1.875rem;
|
|
||||||
border: 1px solid var(--card-border);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-card:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
border-color: rgba(255, 100, 0, 0.3);
|
|
||||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-icon {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
color: var(--accent-fire);
|
|
||||||
margin-bottom: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-title {
|
|
||||||
font-size: 1.3rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
color: var(--text-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-title::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
width: 40px;
|
|
||||||
height: 2px;
|
|
||||||
background: var(--accent-fire);
|
|
||||||
bottom: -5px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-text {
|
|
||||||
color: var(--text-ash);
|
|
||||||
line-height: 1.6;
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skills card */
|
/* Skills card */
|
||||||
.skill-card {
|
.skill-card {
|
||||||
background-color: var(--card-bg);
|
background-color: var(--card-bg);
|
||||||
@@ -532,17 +408,6 @@
|
|||||||
transform: translateY(-5px);
|
transform: translateY(-5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-icon-lg {
|
|
||||||
font-size: 1.8rem;
|
|
||||||
color: var(--accent-fire);
|
|
||||||
}
|
|
||||||
|
|
||||||
.social-name {
|
|
||||||
color: var(--text-ash);
|
|
||||||
font-size: 0.9rem;
|
|
||||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 404 page styles */
|
/* 404 page styles */
|
||||||
.error-container {
|
.error-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import type {AboutProps} from '../untils/AboutProps'
|
||||||
|
|
||||||
|
const url = `${import.meta.env.BASE_URL}data/AboutProps.json`;
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch about props: ${res.status}`);
|
||||||
|
|
||||||
|
export const aboutProps: AboutProps = await res.json();
|
||||||
@@ -1,131 +1,7 @@
|
|||||||
import type {BlogPostProps} from '../untils/BlogPostProps'
|
import type {BlogPostProps} from '../untils/BlogPostProps'
|
||||||
|
|
||||||
export const blogPostsData: BlogPostProps[] = [
|
const url = `${import.meta.env.BASE_URL}data/BlogPosts.json`;
|
||||||
{
|
const res = await fetch(url);
|
||||||
id: "1",
|
if (!res.ok) throw new Error(`Failed to fetch blog posts: ${res.status}`);
|
||||||
slug: "summoning-digital-entities-stm32-techniques",
|
|
||||||
title: "Summoning Digital Entities: Advanced STM32 Techniques for IoT Communication",
|
|
||||||
excerpt: "Delve into the arcane arts of STM32 microcontroller programming as we explore advanced techniques for establishing robust communication between IoT devices. This comprehensive guide reveals how to optimize I2C, SPI, and UART protocols for maximum efficiency in your embedded systems projects.",
|
|
||||||
image: "/images/blog/stm32-communication.jpg",
|
|
||||||
category: "Embedded Systems",
|
|
||||||
date: "May 5, 2025",
|
|
||||||
author: "SecCodeSmith",
|
|
||||||
commentCount: 12,
|
|
||||||
readTime: "15 min read",
|
|
||||||
featured: true,
|
|
||||||
tags: ["STM32", "Embedded", "IoT", "Communication Protocols"],
|
|
||||||
content: `
|
|
||||||
In the digital forge where hardware meets software, the STM32 microcontroller family stands as a powerful conduit for summoning digital entities into our physical realm. Today, we shall delve into advanced techniques for establishing robust communication between these entities through the mystical arts of embedded systems programming.
|
|
||||||
|
|
||||||
The realm of IoT demands reliable, efficient communication protocols that can withstand the chaotic nature of real-world environments. Through careful implementation and optimization of the STM32's communication peripherals, we can craft resilient connections that bridge the gap between digital and physical domains.
|
export const blogPostsData: BlogPostProps[] = await res.json();
|
||||||
|
|
||||||
# The Three Elemental Protocols: I2C, SPI, and UART
|
|
||||||
|
|
||||||
Before we forge ahead into advanced territory, let us briefly recall the elemental forces at our disposal. Each protocol serves as a channel through which our digital entities communicate, each with its unique strengths and limitations:
|
|
||||||
* **I2C (Inter-Integrated Circuit)** - A two-wire interface requiring minimal physical connections, ideal for communication with multiple peripheral devices over short distances.
|
|
||||||
* **SPI (Serial Peripheral Interface)** - A faster, full-duplex protocol with dedicated select lines for each peripheral, allowing simultaneous transmission and reception of data.
|
|
||||||
* **UART (Universal Asynchronous Receiver-Transmitter)** - A simple two-wire asynchronous interface, perfect for direct device-to-device communication without a shared clock.
|
|
||||||
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "2",
|
|
||||||
slug: "forging-neural-networks-pytorch-blacksmith-approach",
|
|
||||||
title: "Forging Neural Networks with PyTorch: A Blacksmith's Approach",
|
|
||||||
excerpt: "Learn how to craft powerful neural networks using PyTorch, approaching the process with the precision and artistry of a master blacksmith. This tutorial combines theory with practical implementation.",
|
|
||||||
image: "/images/blog/neural-networks-pytorch.jpg",
|
|
||||||
category: "Machine Learning",
|
|
||||||
date: "April 28, 2025",
|
|
||||||
author: "SecCodeSmith",
|
|
||||||
commentCount: 8,
|
|
||||||
readTime: "12 min read",
|
|
||||||
tags: ["PyTorch", "Machine Learning", "Neural Networks", "Python"],
|
|
||||||
content: `
|
|
||||||
<p>The art of forging neural networks requires both scientific precision and creative intuition—much like the work of a master blacksmith. In this guide, we'll explore how to craft robust neural network architectures using PyTorch, one of the most flexible deep learning frameworks available.</p>
|
|
||||||
|
|
||||||
<h2>Preparing the Forge: Setting Up Your PyTorch Environment</h2>
|
|
||||||
|
|
||||||
<p>Before we begin crafting our neural networks, we need to prepare our digital forge with the proper tools and materials...</p>
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "3",
|
|
||||||
slug: "dark-arts-memory-management-cpp",
|
|
||||||
title: "The Dark Arts of Memory Management in C++",
|
|
||||||
excerpt: "Explore the shadowy realm of manual memory management in C++. From smart pointers to custom allocators, master techniques that will prevent memory leaks and boost performance.",
|
|
||||||
image: "/images/blog/cpp-memory.jpg",
|
|
||||||
category: "C++",
|
|
||||||
date: "April 22, 2025",
|
|
||||||
author: "SecCodeSmith",
|
|
||||||
commentCount: 15,
|
|
||||||
readTime: "18 min read",
|
|
||||||
tags: ["C++", "Memory Management", "Performance", "Smart Pointers"],
|
|
||||||
content: `
|
|
||||||
<p>Memory management in C++ is often viewed as a mysterious and perilous art, filled with potential hazards for the unwary programmer. Yet, mastering this art grants you unparalleled control over your program's resources and performance.</p>
|
|
||||||
|
|
||||||
<h2>The Ancient Runes: Raw Pointers and Manual Allocation</h2>
|
|
||||||
|
|
||||||
<p>At the foundation of C++ memory management lie raw pointers and manual allocation through the new and delete operators...</p>
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "4",
|
|
||||||
slug: "docker-containment-spells-isolating-digital-entities",
|
|
||||||
title: "Docker Containment Spells: Isolating Digital Entities",
|
|
||||||
excerpt: "Master the containment of digital entities with Docker. This guide covers advanced containerization techniques for creating isolated, reproducible environments for your applications.",
|
|
||||||
image: "/images/blog/docker-containers.jpg",
|
|
||||||
category: "DevOps",
|
|
||||||
date: "April 15, 2025",
|
|
||||||
author: "SecCodeSmith",
|
|
||||||
commentCount: 6,
|
|
||||||
readTime: "14 min read",
|
|
||||||
tags: ["Docker", "Containerization", "DevOps", "Microservices"],
|
|
||||||
content: `
|
|
||||||
<p>In the realm of modern software development, Docker has emerged as a powerful tool for containing and isolating digital entities. Like a master sorcerer binding spirits, Docker allows us to encapsulate applications and their dependencies into sealed containers, ensuring consistent behavior across different environments.</p>
|
|
||||||
|
|
||||||
<h2>The Fundamentals of Container Magic</h2>
|
|
||||||
|
|
||||||
<p>At its core, Docker utilizes Linux kernel features like namespaces and control groups to create isolated environments that share the host's OS kernel but are otherwise separated from one another...</p>
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "5",
|
|
||||||
slug: "blazor-incantations-building-reactive-web-uis-dotnet",
|
|
||||||
title: "Blazor Incantations: Building Reactive Web UIs with .NET",
|
|
||||||
excerpt: "Harness the power of Blazor to create dynamic, responsive web interfaces using C# and .NET. Learn component-based architecture and state management for modern web applications.",
|
|
||||||
image: "/images/blog/blazor-web.jpg",
|
|
||||||
category: "Web Dev",
|
|
||||||
date: "April 8, 2025",
|
|
||||||
author: "SecCodeSmith",
|
|
||||||
commentCount: 9,
|
|
||||||
readTime: "16 min read",
|
|
||||||
tags: ["Blazor", ".NET", "Web Development", "C#"],
|
|
||||||
content: `
|
|
||||||
<p>Blazor represents a paradigm shift in web development, allowing .NET developers to craft rich, interactive web applications using C# instead of JavaScript. This modern framework brings the power and elegance of .NET to the browser, opening new possibilities for web development.</p>
|
|
||||||
|
|
||||||
<h2>Understanding the Blazor Magic</h2>
|
|
||||||
|
|
||||||
<p>Blazor comes in two flavors: Blazor WebAssembly, which runs directly in the browser via WebAssembly, and Blazor Server, which executes on the server and communicates with the client via SignalR...</p>
|
|
||||||
`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "6",
|
|
||||||
slug: "esp32-ethereal-connections-wireless-sensor-network",
|
|
||||||
title: "ESP32 Ethereal Connections: Building a Wireless Sensor Network",
|
|
||||||
excerpt: "Create a mesh of interconnected ESP32 devices that communicate wirelessly. This tutorial covers WiFi, Bluetooth, and custom RF protocols for building resilient IoT systems.",
|
|
||||||
image: "/images/blog/esp32-network.jpg",
|
|
||||||
category: "IoT",
|
|
||||||
date: "March 30, 2025",
|
|
||||||
author: "SecCodeSmith",
|
|
||||||
commentCount: 11,
|
|
||||||
readTime: "20 min read",
|
|
||||||
tags: ["ESP32", "IoT", "Wireless", "Sensor Networks"],
|
|
||||||
content: `
|
|
||||||
<p>The ESP32 microcontroller has revolutionized the world of IoT with its powerful wireless capabilities, making it the perfect foundation for building ethereal connections between sensors and systems. In this guide, we'll explore how to craft a resilient wireless sensor network using these versatile devices.</p>
|
|
||||||
|
|
||||||
<h2>The Mystical Properties of ESP32</h2>
|
|
||||||
|
|
||||||
<p>Before diving into network architecture, let's examine what makes the ESP32 uniquely suited for wireless sensor networks. With dual-core processors, integrated WiFi and Bluetooth, and numerous GPIO pins...</p>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
];
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import type {ContactProps} from '../untils/ContactProps'
|
||||||
|
|
||||||
|
const url = `${import.meta.env.BASE_URL}data/Contact.json`;
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch blog posts: ${res.status}`);
|
||||||
|
|
||||||
|
export const contactData: ContactProps = await res.json();
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import { type AboutProps } from "../pages/About";
|
|
||||||
|
|
||||||
export const aboutProps: AboutProps = {
|
|
||||||
coreValues: [
|
|
||||||
{
|
|
||||||
title: "Security by Design",
|
|
||||||
icon: "fas fa-shield-alt",
|
|
||||||
description:
|
|
||||||
"Security is not an afterthought but the very foundation upon which robust systems are built. Every line of code is crafted with defensive principles in mind.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-tachometer-alt",
|
|
||||||
title: "Performance Optimization",
|
|
||||||
description:
|
|
||||||
"Like a finely-honed blade, code should be both effective and efficient. I meticulously optimize every component for maximum speed and minimal resource consumption.",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-gem",
|
|
||||||
title: "Elegant Simplicity",
|
|
||||||
description:
|
|
||||||
"True mastery is revealed not in complexity but in elegant simplicity. I strive to create solutions that are accessible, maintainable, and beautifully crafted."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-sync-alt",
|
|
||||||
title: "Continuous Evolution",
|
|
||||||
description:
|
|
||||||
"The digital landscape changes with the seasons. I embrace continuous learning and adaptation, integrating new techniques and technologies to forge ever-better solutions."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
technicalArsenal: [
|
|
||||||
{
|
|
||||||
icon: "fas fa-microchip",
|
|
||||||
title: "Embedded Systems",
|
|
||||||
skills: [
|
|
||||||
"STM32 microcontroller programming (I2C, SPI, UART)",
|
|
||||||
"ESP32 wireless solutions",
|
|
||||||
"Firmware development with C/C++",
|
|
||||||
"Raspberry Pi and Pico-SDK integration",
|
|
||||||
"RTOS implementation"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-brain",
|
|
||||||
title: "AI & Data Analysis",
|
|
||||||
skills: [
|
|
||||||
"Machine learning with PyTorch",
|
|
||||||
"Data manipulation with Pandas",
|
|
||||||
"Predictive modeling via Scikit-learn",
|
|
||||||
"Computer vision with Scikit-image",
|
|
||||||
"Edge AI deployment"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-window-maximize",
|
|
||||||
title: "Web Development",
|
|
||||||
skills: [
|
|
||||||
"Web Development",
|
|
||||||
"Backend development with ASP.NET",
|
|
||||||
"Database management with Entity Framework",
|
|
||||||
"Frontend frameworks: Blazor, React",
|
|
||||||
"Responsive design with Bootstrap",
|
|
||||||
"Python-based web solutions with Django"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-server",
|
|
||||||
title: "DevOps & Infrastructure",
|
|
||||||
skills: [
|
|
||||||
"Containerization with Docker",
|
|
||||||
"Multi-container orchestration via Docker-compose",
|
|
||||||
"Linux server administration",
|
|
||||||
"CI/CD pipeline implementation",
|
|
||||||
"Build system configuration with CMake"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
professionalJourney: [
|
|
||||||
{
|
|
||||||
title: "Student at Rzeszów University of Technology",
|
|
||||||
description: "Specialization: Computer Science",
|
|
||||||
duration: "2021.10 - 2025.6",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "intern software engineer at Opeteam S.A.",
|
|
||||||
description:
|
|
||||||
`- Performing programming tasks in R&D projects within the product development department,
|
|
||||||
- Database administration,
|
|
||||||
- Defining unit tests and manual testing of solutions,
|
|
||||||
- Selecting technologies for basic problems,
|
|
||||||
- Documenting the source code (technical documentation).`,
|
|
||||||
duration: "2022.8 - 2023.4",
|
|
||||||
},
|
|
||||||
|
|
||||||
],
|
|
||||||
testimonials: [
|
|
||||||
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
import type { ProjectProps, Category } from "../untils/ProjectProps";
|
import type { ProjectProps, Category } from "../untils/ProjectProps";
|
||||||
|
|
||||||
|
const url = `${import.meta.env.BASE_URL}data/ProjectProps.json`;
|
||||||
|
const res = await fetch(url);
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch projects: ${res.status}`);
|
||||||
|
|
||||||
type CategoryMap = Record<string, Category>
|
type CategoryMap = Record<string, Category>
|
||||||
export const Categories: CategoryMap = {
|
export const Categories: CategoryMap = {
|
||||||
Embedded: {
|
Embedded: {
|
||||||
@@ -29,128 +33,16 @@ export const Categories: CategoryMap = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const projectsData: ProjectProps[] = [
|
type RawProject = Omit<ProjectProps, 'category'> & { category: string[] };
|
||||||
{
|
|
||||||
id: "SecCodeSmithFrontend",
|
const rawProjects: RawProject[] = await res.json();
|
||||||
title: "SecCodeSmith Portfolio Page - Frontend",
|
|
||||||
description: "A modern, responsive portfolio page showcasing my projects, skills, and blog posts. Built with React and styled-components for a sleek user interface.",
|
// map the category-keys back to your CategoryMap objects
|
||||||
image: "/images/projects/shadowguardian.jpg",
|
export const projectsData: ProjectProps[] = rawProjects.map(p => ({
|
||||||
category: [Categories["Web"]],
|
...p,
|
||||||
featured: true,
|
category: p.category.map(key => {
|
||||||
technologies: [
|
const cat = Categories[key];
|
||||||
{ name: "React", icon: "devicon-react-original tech-icon" },
|
if (!cat) throw new Error(`Unknown project category key: ${key}`);
|
||||||
{ name: "TypeScript", icon: "devicon-typescript-plain tech-icon" },
|
return cat;
|
||||||
{ name: "SCSS", icon: "devicon-sass-original tech-icon" },
|
})
|
||||||
{ name: "Vite", icon: "devicon-vitejs-plain tech-icon" }
|
}));
|
||||||
],
|
|
||||||
links: {
|
|
||||||
github: "https://github.com/SecCodeSmith/shadowguardian",
|
|
||||||
demo: "https://seccodesmith.pl"
|
|
||||||
},
|
|
||||||
projectDetails: {
|
|
||||||
descriptions: [
|
|
||||||
"This portfolio page is designed to highlight my skills and projects in a visually appealing way. It features a clean layout, smooth animations, and responsive design for optimal viewing on all devices.",
|
|
||||||
"The project utilizes React for building the user interface, TypeScript for type safety, and SCSS for styling. The use of Vite ensures fast development and build times."
|
|
||||||
],
|
|
||||||
startDate: "12-05-2025",
|
|
||||||
endDate: "",
|
|
||||||
dateFormatted: "DD MMMM YYYY",
|
|
||||||
role: "Frontend Developer",
|
|
||||||
status: "In Progress",
|
|
||||||
keyFeatures: [
|
|
||||||
"Responsive design with mobile-first approach",
|
|
||||||
"Dynamic project showcase with filtering options",
|
|
||||||
"Interactive blog section with latest posts"
|
|
||||||
],
|
|
||||||
gallery: ["/images/projects/shadowguardian1.jpg", "/images/projects/shadowguardian2.jpg"],
|
|
||||||
fullTechStack: [
|
|
||||||
{ name: "React", icons: "devicon-react-original" },
|
|
||||||
{ name: "TypeScript", icons: "devicon-typescript-plain" },
|
|
||||||
{ name: "SCSS", icons: "devicon-sass-original" },
|
|
||||||
{ name: "Vite", icons: "devicon-vitejs-plain" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "pyrosight",
|
|
||||||
title: "PyroSight: Thermal Anomaly Detection",
|
|
||||||
description: "An intelligent system that uses computer vision and thermal imaging to detect anomalies in industrial equipment. Employs PyTorch for deep learning to predict potential failures before they occur.",
|
|
||||||
image: "/images/projects/pyrosight.jpg",
|
|
||||||
category: [Categories["ML"], Categories["IoT"]],
|
|
||||||
technologies: [
|
|
||||||
{ name: "Python", icon: "devicon-python-plain tech-icon" },
|
|
||||||
{ name: "PyTorch", icon: "devicon-pytorch-original tech-icon" },
|
|
||||||
{ name: "OpenCV", icon: "fas fa-camera tech-icon" },
|
|
||||||
{ name: "Raspberry Pi", icon: "fas fa-microchip tech-icon" }
|
|
||||||
],
|
|
||||||
links: {
|
|
||||||
github: "https://github.com/SecCodeSmith/pyrosight"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "nexusflow",
|
|
||||||
title: "NexusFlow: DevOps Dashboard",
|
|
||||||
description: "A real-time monitoring dashboard for DevOps teams that visualizes CI/CD pipelines, infrastructure metrics, and deployment statuses. Built with Blazor for seamless updates without page refreshes.",
|
|
||||||
image: "/images/projects/nexusflow.jpg",
|
|
||||||
category: [Categories["Web"]],
|
|
||||||
technologies: [
|
|
||||||
{ name: "C#", icon: "devicon-csharp-plain tech-icon" },
|
|
||||||
{ name: "Blazor", icon: "devicon-dotnetcore-plain tech-icon" },
|
|
||||||
{ name: "Entity Framework", icon: "fas fa-database tech-icon" },
|
|
||||||
{ name: "Docker", icon: "devicon-docker-plain tech-icon" }
|
|
||||||
],
|
|
||||||
links: {
|
|
||||||
github: "https://github.com/SecCodeSmith/nexusflow",
|
|
||||||
demo: "https://nexusflow.demo.com"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "etherwhisper",
|
|
||||||
title: "EtherWhisper: Secure Communication Node",
|
|
||||||
description: "A low-power, long-range communication node for IoT networks with military-grade encryption and mesh capabilities. Perfect for remote sensing applications in harsh environments.",
|
|
||||||
image: "/images/projects/etherwhisper.jpg",
|
|
||||||
category: [Categories["Embedded"], Categories["IoT"]],
|
|
||||||
technologies: [
|
|
||||||
{ name: "C", icon: "devicon-c-plain tech-icon" },
|
|
||||||
{ name: "STM32", icon: "fas fa-memory tech-icon" },
|
|
||||||
{ name: "LoRa", icon: "fas fa-broadcast-tower tech-icon" },
|
|
||||||
{ name: "AES-256", icon: "fas fa-shield-alt tech-icon" }
|
|
||||||
],
|
|
||||||
links: {
|
|
||||||
github: "https://github.com/SecCodeSmith/etherwhisper"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "dataforge",
|
|
||||||
title: "DataForge: Advanced Analytics Platform",
|
|
||||||
description: "A comprehensive data analytics platform with interactive visualization tools and automated reporting features. Integrates with various data sources and provides ML-powered insights.",
|
|
||||||
image: "/images/projects/dataforge.jpg",
|
|
||||||
category: [Categories["Web"]],
|
|
||||||
technologies: [
|
|
||||||
{ name: "Python", icon: "devicon-python-plain tech-icon" },
|
|
||||||
{ name: "Django", icon: "devicon-django-plain tech-icon" },
|
|
||||||
{ name: "React", icon: "devicon-react-original tech-icon" },
|
|
||||||
{ name: "Pandas", icon: "devicon-pandas-original tech-icon" }
|
|
||||||
],
|
|
||||||
links: {
|
|
||||||
github: "https://github.com/SecCodeSmith/dataforge",
|
|
||||||
demo: "https://dataforge.demo.com"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "visionkeeper",
|
|
||||||
title: "VisionKeeper: Object Recognition System",
|
|
||||||
description: "A real-time object recognition system optimized for edge devices. Capable of identifying and tracking objects with high accuracy even in challenging lighting conditions.",
|
|
||||||
image: "/images/projects/visionkeeper.jpg",
|
|
||||||
category: [Categories["ML"]],
|
|
||||||
technologies: [
|
|
||||||
{ name: "Python", icon: "devicon-python-plain tech-icon" },
|
|
||||||
{ name: "PyTorch", icon: "devicon-pytorch-original tech-icon" },
|
|
||||||
{ name: "OpenCV", icon: "fas fa-camera tech-icon" },
|
|
||||||
{ name: "NVIDIA Jetson", icon: "fas fa-microchip tech-icon" }
|
|
||||||
],
|
|
||||||
links: {
|
|
||||||
github: "https://github.com/SecCodeSmith/visionkeeper"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -1,60 +1,7 @@
|
|||||||
import {type SkillCardProps} from '../components/SkillCard';
|
import {type SkillCardProps} from '../untils/SkillCardProps';
|
||||||
|
|
||||||
export const skillCardData: SkillCardProps[] = [
|
const url = `${import.meta.env.BASE_URL}data/SkillCardProps.json`;
|
||||||
{
|
const res = await fetch(url);
|
||||||
categoryIcon: "fa-code",
|
if (!res.ok) throw new Error(`Failed to fetch skill card data: ${res.status}`);
|
||||||
categoryTitle: "Languages",
|
|
||||||
skills: [
|
export const skillCardData: SkillCardProps[] = await res.json();
|
||||||
{ name: "C/C++", icon: "devicon-cplusplus-plain" },
|
|
||||||
{ name: "Python", icon: "devicon-python-plain" },
|
|
||||||
{ name: ".NET", icon: "devicon-dotnetcore-plain" },
|
|
||||||
{ name: "C#", icon: "devicon-csharp-plain" },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
categoryIcon: "fa-microchip",
|
|
||||||
categoryTitle: "Embedded Systems",
|
|
||||||
skills: [
|
|
||||||
{ name: "STM32 (I2C, SPI, UART)", icon: "fas fa-microchip" },
|
|
||||||
{ name: "ESP32", icon: "fas fa-wifi" },
|
|
||||||
{ name: "Pico-SDK", icon: "fas fa-memory" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
categoryIcon: "fa-brain",
|
|
||||||
categoryTitle: "Data & ML",
|
|
||||||
skills: [
|
|
||||||
{ name: "Pandas", icon: "devicon-pandas-plain" },
|
|
||||||
{ name: "Scikit-learn", icon: "devicon-scikitlearn-plain" },
|
|
||||||
{ name: "Scikit-image", icon: "fas fa-image" },
|
|
||||||
{ name: "PyTorch", icon: "devicon-pytorch-plain" },
|
|
||||||
{ name: "OpenCV", icon: "devicon-opencv-plain" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
categoryIcon: "fas fa-window-maximize",
|
|
||||||
categoryTitle: "Web Development",
|
|
||||||
skills: [
|
|
||||||
{ name: "ASP.NET Core", icon: "devicon-dot-net-plain" },
|
|
||||||
{ name: "Entity Framework", icon: "fas fa-database" },
|
|
||||||
{ name: "Blazor", icon: "devicon-dotnetcore-plain"},
|
|
||||||
{ name: "React", icon: "devicon-react-original" },
|
|
||||||
{ name: "Django", icon: "devicon-django-plain" },
|
|
||||||
{ name: "Bootstrap", icon: "devicon-bootstrap-plain" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
categoryIcon: "fas fa-cloud",
|
|
||||||
categoryTitle: "DevOps & Systems",
|
|
||||||
skills: [
|
|
||||||
{ name: "Docker", icon: "devicon-docker-plain" },
|
|
||||||
{ name: "Docker-compose", icon: "fas fa-layer-group" },
|
|
||||||
{ name: "Linux CLI", icon: "devicon-bash-plain" },
|
|
||||||
{ name: "Git", icon: "devicon-git-plain" },
|
|
||||||
{ name: "CI/CD", icon: "fas fa-cogs" },
|
|
||||||
{ name: "Cmake", icon: "devicon-cmake-plain" },
|
|
||||||
{ name: "Linux", icon: "devicon-linux-plain" },
|
|
||||||
{ name: "Jenkins", icon: "devicon-jenkins-plain" },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
@@ -1,24 +1,7 @@
|
|||||||
import {type socialLink} from "../components/Footer";
|
import {type SocialLink} from "../untils/SocialLink";
|
||||||
|
|
||||||
export const socialLinkData: socialLink[] = [
|
const url = `${import.meta.env.BASE_URL}data/SocialLink.json`;
|
||||||
{
|
const res = await fetch(url);
|
||||||
icon: "fab fa-github",
|
if (!res.ok) throw new Error(`Failed to fetch skill card data: ${res.status}`);
|
||||||
url: ""
|
|
||||||
},
|
export const socialLinkData: SocialLink[] = await res.json();
|
||||||
{
|
|
||||||
icon: "fab fa-linkedin",
|
|
||||||
url: ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fab fa-twitter",
|
|
||||||
url: ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fab fa-discord",
|
|
||||||
url: ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: "fas fa-envelope",
|
|
||||||
url: ""
|
|
||||||
},
|
|
||||||
]
|
|
||||||
@@ -1,39 +1,8 @@
|
|||||||
import { PageHeader } from '../components/PageHeader';
|
import { PageHeader } from '../components/PageHeader';
|
||||||
import { aboutProps } from '../data/experienceData';
|
import { aboutProps } from '../data/AboutProps';
|
||||||
|
|
||||||
import style from '@styles/About.module.scss';
|
import style from '@styles/About.module.scss';
|
||||||
|
|
||||||
export interface AboutProps {
|
|
||||||
coreValues: CoreValue[];
|
|
||||||
technicalArsenal: TechnicalArsenal[];
|
|
||||||
professionalJourney: ProfessionalJourney[];
|
|
||||||
testimonials: Testimonial[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CoreValue {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
icon: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ProfessionalJourney {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
duration: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TechnicalArsenal {
|
|
||||||
title: string;
|
|
||||||
icon: string;
|
|
||||||
skills: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Testimonial {
|
|
||||||
content: string;
|
|
||||||
author: string;
|
|
||||||
position: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const About = () => {
|
export const About = () => {
|
||||||
const data = aboutProps;
|
const data = aboutProps;
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export const BlogPost = () => {
|
|||||||
<article>
|
<article>
|
||||||
{/* Post Header */}
|
{/* Post Header */}
|
||||||
<div className={style.postHeader}>
|
<div className={style.postHeader}>
|
||||||
<div className={style.postFeaturedImage} style={{ backgroundImage: `url(${post.image})` }}></div>
|
<div className={style.postFeaturedImage} style={{ backgroundImage: `url(${import.meta.env.BASE_URL}${post.image})` }}></div>
|
||||||
<div className={style.postCategory}>{post.category}</div>
|
<div className={style.postCategory}>{post.category}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -227,8 +227,8 @@ export const BlogPost = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/*Temporarily disable comments section */}
|
||||||
{/* Comments Section */}
|
{ 0 && (
|
||||||
<div className={style.commentsSection}>
|
<div className={style.commentsSection}>
|
||||||
<h3 className={style.commentsTitle}>Discussions ({post.commentCount})</h3>
|
<h3 className={style.commentsTitle}>Discussions ({post.commentCount})</h3>
|
||||||
|
|
||||||
@@ -264,6 +264,7 @@ export const BlogPost = () => {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import { PageHeader } from '../components/PageHeader';
|
import { PageHeader } from '../components/PageHeader';
|
||||||
import { ContactForm } from '../components/ContactForm';
|
import { ContactForm } from '../components/ContactForm';
|
||||||
|
import style from '@styles/Contact.module.scss';
|
||||||
|
import '@styles/Accordion.scss';
|
||||||
|
|
||||||
|
import { contactData } from '../data/contactData'
|
||||||
|
import type { ContactProps } from '../untils/ContactProps';
|
||||||
|
|
||||||
export const Contact = () => {
|
export const Contact = () => {
|
||||||
|
const data: ContactProps = contactData;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
@@ -20,24 +27,24 @@ export const Contact = () => {
|
|||||||
{/* Contact Info Column */}
|
{/* Contact Info Column */}
|
||||||
<div className="col-lg-5">
|
<div className="col-lg-5">
|
||||||
{/* Email Info */}
|
{/* Email Info */}
|
||||||
<div className="card mb-4">
|
<div className={`card mb-4 ${style.card}`}>
|
||||||
<div className="card-body p-4">
|
<div className={`card-body p-4 ${style.cardBody}`}>
|
||||||
<div className="contact-card">
|
<div className={`${style.contactCard}`}>
|
||||||
<div className="contact-icon">
|
<div className={`${style.contactIcon}`}>
|
||||||
<i className="fas fa-envelope"></i>
|
<i className="fas fa-envelope"></i>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="contact-title">Email</h3>
|
<h3 className={style.contactTitle}>Email</h3>
|
||||||
<div className="contact-content">
|
<div className="contact-content">
|
||||||
<p>For project inquiries or questions:</p>
|
<p>For project inquiries or questions:</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="mailto:forge@seccodesmtih.com" className="contact-link">
|
<a href={`mailto:${data.email}`} className={style.contactLink}>
|
||||||
forge@seccodesmtih.com
|
{data.email}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>For business collaborations:</p>
|
<p>For business collaborations:</p>
|
||||||
<p>
|
<p>
|
||||||
<a href="mailto:business@seccodesmtih.com" className="contact-link">
|
<a href={`mailto:${data.businessEmail}`} className={style.contactLink}>
|
||||||
business@seccodesmtih.com
|
{data.businessEmail}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,53 +52,41 @@ export const Contact = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Connect Through Socials */}
|
{
|
||||||
<div className="card">
|
data.socialLinks.length > 0 && (
|
||||||
<div className="card-body p-4">
|
<div className={`card ${style.card}`}>
|
||||||
<div className="contact-card">
|
<div className={`card-body p-4 ${style.cardBody}`}>
|
||||||
<div className="contact-icon">
|
<div className={style.contactCard}>
|
||||||
<i className="fas fa-link"></i>
|
<div className={style.contactIcon}>
|
||||||
</div>
|
<i className="fas fa-link"></i>
|
||||||
<h3 className="contact-title">Connect Through the Ether</h3>
|
</div>
|
||||||
<div className="contact-content">
|
<h3 className={style.contactTitle}>Connect Through the Ether</h3>
|
||||||
<p>You can also reach me through these digital pathways:</p>
|
<div className={style.contactContent}>
|
||||||
<div className="social-grid">
|
<p>You can also reach me through these digital pathways:</p>
|
||||||
<a href="#" className="social-item">
|
<div className={style.socialGrid}>
|
||||||
<i className="fab fa-github social-icon-lg"></i>
|
{data.socialLinks.map((link, index) => (
|
||||||
<span className="social-name">GitHub</span>
|
|
||||||
</a>
|
<a key={index} href={link.url} className={`social-item ${style.socialItem}`}>
|
||||||
<a href="#" className="social-item">
|
<i className={`${link.icon} social-icon-lg ${style.socialIconLg}`}></i>
|
||||||
<i className="fab fa-linkedin social-icon-lg"></i>
|
<span className={`social-name ${style.socialName}`}>{link.platform}</span>
|
||||||
<span className="social-name">LinkedIn</span>
|
</a>
|
||||||
</a>
|
|
||||||
<a href="#" className="social-item">
|
))}
|
||||||
<i className="fab fa-twitter social-icon-lg"></i>
|
</div>
|
||||||
<span className="social-name">Twitter</span>
|
</div>
|
||||||
</a>
|
|
||||||
<a href="#" className="social-item">
|
|
||||||
<i className="fab fa-discord social-icon-lg"></i>
|
|
||||||
<span className="social-name">Discord</span>
|
|
||||||
</a>
|
|
||||||
<a href="#" className="social-item">
|
|
||||||
<i className="fab fa-telegram social-icon-lg"></i>
|
|
||||||
<span className="social-name">Telegram</span>
|
|
||||||
</a>
|
|
||||||
<a href="#" className="social-item">
|
|
||||||
<i className="fab fa-stack-overflow social-icon-lg"></i>
|
|
||||||
<span className="social-name">Stack Overflow</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
</div>
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section >
|
||||||
|
|
||||||
{/* FAQ Section */}
|
{/* FAQ Section */}
|
||||||
<section className="py-5 bg-dark">
|
< section className="py-5 bg-dark" >
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row mb-4">
|
<div className="row mb-4">
|
||||||
<div className="col-12 text-center">
|
<div className="col-12 text-center">
|
||||||
@@ -102,91 +97,42 @@ export const Contact = () => {
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-8 mx-auto">
|
<div className="col-lg-8 mx-auto">
|
||||||
<div className="accordion" id="faqAccordion">
|
<div className="accordion" id="faqAccordion">
|
||||||
{/* FAQ Item 1 */}
|
{
|
||||||
<div className="accordion-item">
|
data.questionsAndAnswers.map((item, index) => (
|
||||||
<h2 className="accordion-header" id="headingOne">
|
<div className={`accordion-item`} key={index}>
|
||||||
<button
|
<h2 className={`accordion-header`} id={`heading${index}`}>
|
||||||
className="accordion-button collapsed"
|
<button
|
||||||
type="button"
|
className={`accordion-button collapsed`}
|
||||||
data-bs-toggle="collapse"
|
type="button"
|
||||||
data-bs-target="#collapseOne"
|
data-bs-toggle="collapse"
|
||||||
aria-expanded="false"
|
data-bs-target={`#collapse${index}`}
|
||||||
aria-controls="collapseOne"
|
aria-expanded="false"
|
||||||
>
|
aria-controls={`collapse${index}`}
|
||||||
What is your typical project timeline?
|
>
|
||||||
</button>
|
{item.question}
|
||||||
</h2>
|
</button>
|
||||||
<div
|
</h2>
|
||||||
id="collapseOne"
|
<div
|
||||||
className="accordion-collapse collapse"
|
id={`collapse${index}`}
|
||||||
aria-labelledby="headingOne"
|
className="accordion-collapse collapse"
|
||||||
data-bs-parent="#faqAccordion"
|
aria-labelledby={`heading${index}`}
|
||||||
>
|
data-bs-parent="#faqAccordion"
|
||||||
<div className="accordion-body">
|
>
|
||||||
Project timelines vary based on complexity and scope. Small projects typically take 2-4 weeks, medium-sized projects 1-2 months, and larger enterprise solutions 3-6 months. I provide detailed timeline estimates during the initial consultation, and maintain transparent communication about progress throughout the development cycle.
|
<div className={`accordion-body`}>
|
||||||
|
{item.answer}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))
|
||||||
</div>
|
}
|
||||||
|
|
||||||
{/* FAQ Item 2 */}
|
|
||||||
<div className="accordion-item">
|
|
||||||
<h2 className="accordion-header" id="headingTwo">
|
|
||||||
<button
|
|
||||||
className="accordion-button collapsed"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#collapseTwo"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-controls="collapseTwo"
|
|
||||||
>
|
|
||||||
How does your collaboration process work?
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div
|
|
||||||
id="collapseTwo"
|
|
||||||
className="accordion-collapse collapse"
|
|
||||||
aria-labelledby="headingTwo"
|
|
||||||
data-bs-parent="#faqAccordion"
|
|
||||||
>
|
|
||||||
<div className="accordion-body">
|
|
||||||
My collaboration process consists of five phases: initial consultation, requirements gathering, design and planning, implementation, and testing/deployment. I use agile methodologies with regular check-ins to ensure your vision is being realized. Communication is maintained through your preferred channels (email, Slack, etc.), and you'll have access to development milestones through shared repositories and project management tools.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* FAQ Item 3 */}
|
|
||||||
<div className="accordion-item">
|
|
||||||
<h2 className="accordion-header" id="headingThree">
|
|
||||||
<button
|
|
||||||
className="accordion-button collapsed"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="collapse"
|
|
||||||
data-bs-target="#collapseThree"
|
|
||||||
aria-expanded="false"
|
|
||||||
aria-controls="collapseThree"
|
|
||||||
>
|
|
||||||
What are your payment terms and methods?
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div
|
|
||||||
id="collapseThree"
|
|
||||||
className="accordion-collapse collapse"
|
|
||||||
aria-labelledby="headingThree"
|
|
||||||
data-bs-parent="#faqAccordion"
|
|
||||||
>
|
|
||||||
<div className="accordion-body">
|
|
||||||
I typically work with a milestone-based payment structure: 30% upfront to begin work, 30% at the midpoint after key deliverables are approved, and 40% upon project completion. For longer projects, we can establish additional milestones. I accept bank transfers, PayPal, and cryptocurrency payments. All payment terms are clearly outlined in the project contract before work begins.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section >
|
||||||
|
|
||||||
{/* Map Section */}
|
{/* Map Section */}
|
||||||
<section className="py-5">
|
< section className="py-5" >
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row mb-4">
|
<div className="row mb-4">
|
||||||
<div className="col-12 text-center">
|
<div className="col-12 text-center">
|
||||||
@@ -196,9 +142,9 @@ export const Contact = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<div className="map-container">
|
<div className={style.mapContainer}>
|
||||||
<iframe
|
<iframe
|
||||||
className="map-frame"
|
className={style.mapFrame}
|
||||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d82077.2903513271!2d21.9433946!3d50.0411861!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x473cfae3cc14d449%3A0xd2240d31b33eb2ed!2zUnplc3rDs3c!5e0!3m2!1sen!2spl!4v1651813309336!5m2!1sen!2spl"
|
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d82077.2903513271!2d21.9433946!3d50.0411861!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x473cfae3cc14d449%3A0xd2240d31b33eb2ed!2zUnplc3rDs3c!5e0!3m2!1sen!2spl!4v1651813309336!5m2!1sen!2spl"
|
||||||
allowFullScreen
|
allowFullScreen
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
@@ -208,7 +154,7 @@ export const Contact = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section >
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
export interface AboutProps {
|
||||||
|
coreValues: CoreValue[];
|
||||||
|
technicalArsenal: TechnicalArsenal[];
|
||||||
|
professionalJourney: ProfessionalJourney[];
|
||||||
|
testimonials: Testimonial[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CoreValue {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProfessionalJourney {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
duration: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TechnicalArsenal {
|
||||||
|
title: string;
|
||||||
|
icon: string;
|
||||||
|
skills: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Testimonial {
|
||||||
|
content: string;
|
||||||
|
author: string;
|
||||||
|
position: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
export interface ContactProps {
|
||||||
|
email: string;
|
||||||
|
businessEmail: string;
|
||||||
|
socialLinks: SocialLink[];
|
||||||
|
questionsAndAnswers: QuestionAndAnswer[];
|
||||||
|
MapIframeUrl: string;
|
||||||
|
phone: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SocialLink {
|
||||||
|
platform: string;
|
||||||
|
url: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QuestionAndAnswer {
|
||||||
|
question: string;
|
||||||
|
answer: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export interface Skill {
|
||||||
|
name: string;
|
||||||
|
icon: React.ReactNode; // Or string if using CSS classes for icons
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SkillCardProps {
|
||||||
|
categoryTitle: string;
|
||||||
|
categoryIcon: React.ReactNode; // Or string
|
||||||
|
skills: Skill[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface SocialLink {
|
||||||
|
icon: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
@@ -1,23 +1,46 @@
|
|||||||
{
|
{
|
||||||
"files": [],
|
"files": [],
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "./tsconfig.app.json" },
|
{
|
||||||
{ "path": "./tsconfig.node.json" }
|
"path": "./tsconfig.app.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.node.json"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["src/*"],
|
"@/*": [
|
||||||
"@assets/*": ["src/assets/*"],
|
"src/*"
|
||||||
"@components/*": ["src/components/*"],
|
],
|
||||||
"@pages/*": ["src/pages/*"],
|
"@assets/*": [
|
||||||
"@data/*": ["src/data/*"],
|
"src/assets/*"
|
||||||
"@styles/*": ["src/styles/*"],
|
],
|
||||||
"@tests/*": ["src/tests/*"],
|
"@components/*": [
|
||||||
"@images/*": ["src/assets/images/*"],
|
"src/components/*"
|
||||||
|
],
|
||||||
|
"@pages/*": [
|
||||||
|
"src/pages/*"
|
||||||
|
],
|
||||||
|
"@data/*": [
|
||||||
|
"src/data/*"
|
||||||
|
],
|
||||||
|
"@styles/*": [
|
||||||
|
"src/styles/*"
|
||||||
|
],
|
||||||
|
"@tests/*": [
|
||||||
|
"src/tests/*"
|
||||||
|
],
|
||||||
|
"@images/*": [
|
||||||
|
"src/assets/images/*"
|
||||||
|
],
|
||||||
},
|
},
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"types": ["node"]
|
"types": [
|
||||||
|
"node"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,4 +22,10 @@ export default defineConfig({
|
|||||||
react(),
|
react(),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
publicDir: 'public',
|
||||||
|
|
||||||
|
build: {
|
||||||
|
target: ['es2022', 'chrome100', 'firefox100', 'safari15']
|
||||||
|
},
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|||||||