Fix-projects #8

Merged
seccodesmith merged 6 commits from Fix-projects into main 2025-05-26 20:40:51 +00:00
8 changed files with 214 additions and 182 deletions
Showing only changes of commit e8a3611dfb - Show all commits
+1 -15
View File
@@ -1,21 +1,7 @@
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import styles from '@styles/BlogCard.module.scss'; import styles from '@styles/BlogCard.module.scss';
export interface BlogPostProps { import type {BlogPostProps} from '../untils/BlogPostProps';
id: string;
slug: string;
title: string;
excerpt: string;
image: string;
category: string;
date: string;
author: string;
commentCount: number;
readTime: string;
featured?: boolean;
tags: string[];
content: string;
}
interface BlogCardProps { interface BlogCardProps {
post: BlogPostProps; post: BlogPostProps;
+1 -26
View File
@@ -1,32 +1,7 @@
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import style from '@styles/Project.module.scss' import style from '@styles/Project.module.scss'
import type {ProjectTech, Category, ProjectProps } from '../untils/ProjectProps'
export interface ProjectTech {
name: string;
icon: string;
}
export interface ProjectProps {
id: string;
title: string;
description: string;
image: string;
category: Category[];
featured?: boolean;
technologies: ProjectTech[];
links: {
github?: string;
demo?: string;
};
}
export interface Category {
[key: string]: string;
fullName: string;
shortName: string;
icon: string;
}
interface ProjectCardProps { interface ProjectCardProps {
project: ProjectProps; project: ProjectProps;
+150 -138
View File
@@ -1,154 +1,166 @@
import type { ProjectProps } from './ProjectCard'; import type { ProjectProps } from '../untils/ProjectProps';
import style from '@styles/Project.module.scss' import style from '@styles/Project.module.scss'
interface ProjectModalProps { interface ProjectModalProps {
project: ProjectProps | null; project: ProjectProps | null;
} }
export const ProjectModal: React.FC<ProjectModalProps> = ({ project }) => { export const ProjectModal: React.FC<ProjectModalProps> = ({ project }) => {
if (!project) return null; if (!project) return null;
return ( return (
<div className="modal fade" id="shadowguardianModal" tabIndex={-1} aria-labelledby="shadowguardianModalLabel" aria-hidden="true"> <div className="modal fade" id="shadowguardianModal" tabIndex={-1} aria-labelledby="shadowguardianModalLabel" aria-hidden="true">
<div className="modal-dialog modal-xl modal-dialog-scrollable"> <div className="modal-dialog modal-xl modal-dialog-scrollable">
<div className={`modal-content ${style.modalContent}`}> <div className={`modal-content ${style.modalContent}`}>
<div className="modal-header"> <div className={`modal-header ${style.modalHeader}`}>
<h5 className={style.modalHeader} id="shadowguardianModalLabel"> <h5 className={style.modalHeader} id="shadowguardianModalLabel">
{project.title} {project.title}
</h5> </h5>
<button type="button" className={`btn-close ${style.btnClose}`} data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" className={`btn-close ${style.btnClose}`} data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div className={`modal-body ${style.modalBody}`}> <div className={`modal-body ${style.modalBody}`}>
<div className="mb-4"> <div className="mb-4">
<img src="/api/placeholder/1000/400" className="img-fluid rounded mb-3" alt="ShadowGuardian Project" /> <img src={project.image} className="img-fluid rounded mb-3" alt={project.title} />
<div className="row"> <div className={`row ${style.row}`}>
<div className="col-md-8"> <div className="col-md-8">
<p>ShadowGuardian is a comprehensive security monitoring system designed for both residential and commercial applications. Built on a foundation of STM32 microcontrollers, it provides reliable, secure monitoring with extremely low power consumption, allowing for battery operation of up to 2 years.</p> {
<p>The system features end-to-end encryption for all communications, ensuring that sensitive security data remains private. Its modular architecture allows for easy expansion with additional sensors and integration with existing home automation systems.</p> project.projectDetails ? project.projectDetails.descriptions.map((desc, index) => (
</div> <p key={index} className="mb-3">{desc}</p>
<div className="col-md-4"> )) :
<div className="card h-100"> <p>{project.description}</p>
<div className="card-header"> }
<h5 className="mb-0">Project Overview</h5> </div>
</div> <div className="col-md-4">
<div className="card-body"> <div className={`card h-100 ${style.card}`}>
<p><strong>Duration:</strong> 6 months</p> <div className={`card-header ${style.cardHeader}`}>
<p><strong>Role:</strong> Lead Developer</p> <h5 className="mb-0">Project Overview</h5>
<p><strong>Status:</strong> Completed</p> </div>
<p><strong>Client:</strong> ConnectedWorld Technologies</p> <div className="card-body">
{project.projectDetails && project.projectDetails.startDate && project.projectDetails.endDate ? (
<p><strong>Duration:</strong> {new Date(project.projectDetails.startDate).toLocaleDateString()} - {new Date(project.projectDetails.endDate).toLocaleDateString()}</p>
) : (
<p><strong>Duration:</strong> Ongoing</p>
)
}
{
project.projectDetails && project.projectDetails.role ? (
<p><strong>Role:</strong> {project.projectDetails.role}</p>
) : (
<p><strong>Role:</strong> Developer</p>
)
}
{
project.projectDetails && project.projectDetails.client ? (
<p><strong>Client:</strong> {project.projectDetails.client}</p>
) : (
<p><strong>Client:</strong> Internal Project</p>
)
}
</div>
</div> </div>
</div> </div>
</div> </div>
{
project.projectDetails?.keyFeatures && project.projectDetails.keyFeatures.length > 0 && (
<>
<h4 className="mt-4 mb-3">Key Features</h4>
{
project.projectDetails?.keyFeatures.map((feature, index) => (
<p key={index} className="mb-2">
<i className="fas fa-check-circle text-success me-2"></i>
{feature}
</p>
))
}
</>
)
}
<h4 className="mt-4 mb-3">Technologies Used</h4>
<div className="mb-4">
<span className="tech-chip">
<i className="devicon-cplusplus-plain tech-chip-icon"></i>
<span className="tech-chip-name">C++</span>
</span>
<span className="tech-chip">
<i className="fas fa-microchip tech-chip-icon"></i>
<span className="tech-chip-name">STM32F4</span>
</span>
<span className="tech-chip">
<i className="fas fa-wifi tech-chip-icon"></i>
<span className="tech-chip-name">ESP32</span>
</span>
<span className="tech-chip">
<i className="fas fa-shield-alt tech-chip-icon"></i>
<span className="tech-chip-name">AES-256</span>
</span>
<span className="tech-chip">
<i className="devicon-react-original tech-chip-icon"></i>
<span className="tech-chip-name">React Native</span>
</span>
<span className="tech-chip">
<i className="fas fa-broadcast-tower tech-chip-icon"></i>
<span className="tech-chip-name">BLE 5.0</span>
</span>
<span className="tech-chip">
<i className="fas fa-network-wired tech-chip-icon"></i>
<span className="tech-chip-name">Zigbee</span>
</span>
<span className="tech-chip">
<i className="fas fa-server tech-chip-icon"></i>
<span className="tech-chip-name">Node.js</span>
</span>
<span className="tech-chip">
<i className="fas fa-database tech-chip-icon"></i>
<span className="tech-chip-name">PostgreSQL</span>
</span>
<span className="tech-chip">
<i className="devicon-docker-plain tech-chip-icon"></i>
<span className="tech-chip-name">Docker</span>
</span>
</div>
{
project.projectDetails?.gallery && project.projectDetails?.gallery.length > 0 && (
<>
<h4 className="mt-4 mb-3">Gallery</h4>
<div className="row">
<div className="col-md-4 col-6">
{
project.projectDetails.gallery.map((image, index) => (
<div key={index} className="gallery-item">
<img src={image} alt={`Gallery Image ${index + 1}`} className="gallery-image"></img>
</div>
))
}
</div>
</div>
</>
)
}
</div>
<div className={`modal-footer ${style.modalFooter}`}>
<a href="#" className={`btn btn-outline-secondary ${style.btnOutlineSecondary}`}>
<i className="fab fa-github btn-icon"></i>Source Code
</a>
<a href="#" className={`btn btn-outline-secondary ${style.btnOutlineSecondary}`}>
<i className="fas fa-external-link-alt btn-icon"></i>Live Demo
</a>
<a href="#" className={`btn btn-outline-secondary ${style.btnOutlineSecondary}`}>
<i className="fas fa-book btn-icon"></i>Documentation
</a>
<button type="button" className={`btn btn-secondary`} data-bs-dismiss="modal">Close</button>
</div> </div>
</div> </div>
<h4 className="mt-4 mb-3">Key Features</h4>
<ul className="features-list">
<li>Military-grade AES-256 encryption for all data transmission</li>
<li>Ultra-low power consumption with intelligent sleep modes</li>
<li>Modular sensor architecture supporting motion, contact, glass-break, and environmental sensors</li>
<li>Local processing to reduce cloud dependency and improve response times</li>
<li>Mesh networking for extended coverage without Wi-Fi dependencies</li>
<li>Real-time notifications via mobile app (iOS and Android)</li>
<li>Integration with popular home automation platforms including HomeKit, Google Home, and Alexa</li>
<li>Tamper detection and notification system</li>
<li>Optional cellular backup connection for critical deployments</li>
</ul>
<h4 className="mt-4 mb-3">Technologies Used</h4>
<div className="mb-4">
<span className="tech-chip">
<i className="devicon-cplusplus-plain tech-chip-icon"></i>
<span className="tech-chip-name">C++</span>
</span>
<span className="tech-chip">
<i className="fas fa-microchip tech-chip-icon"></i>
<span className="tech-chip-name">STM32F4</span>
</span>
<span className="tech-chip">
<i className="fas fa-wifi tech-chip-icon"></i>
<span className="tech-chip-name">ESP32</span>
</span>
<span className="tech-chip">
<i className="fas fa-shield-alt tech-chip-icon"></i>
<span className="tech-chip-name">AES-256</span>
</span>
<span className="tech-chip">
<i className="devicon-react-original tech-chip-icon"></i>
<span className="tech-chip-name">React Native</span>
</span>
<span className="tech-chip">
<i className="fas fa-broadcast-tower tech-chip-icon"></i>
<span className="tech-chip-name">BLE 5.0</span>
</span>
<span className="tech-chip">
<i className="fas fa-network-wired tech-chip-icon"></i>
<span className="tech-chip-name">Zigbee</span>
</span>
<span className="tech-chip">
<i className="fas fa-server tech-chip-icon"></i>
<span className="tech-chip-name">Node.js</span>
</span>
<span className="tech-chip">
<i className="fas fa-database tech-chip-icon"></i>
<span className="tech-chip-name">PostgreSQL</span>
</span>
<span className="tech-chip">
<i className="devicon-docker-plain tech-chip-icon"></i>
<span className="tech-chip-name">Docker</span>
</span>
</div>
<h4 className="mt-4 mb-3">Gallery</h4>
<div className="row">
<div className="col-md-4 col-6">
<div className="gallery-item">
<img src="/api/placeholder/300/300" alt="ShadowGuardian Hub" className="gallery-image"></img>
</div>
</div>
<div className="col-md-4 col-6">
<div className="gallery-item">
<img src="/api/placeholder/300/300" alt="ShadowGuardian Sensor" className="gallery-image"></img>
</div>
</div>
<div className="col-md-4 col-6">
<div className="gallery-item">
<img src="/api/placeholder/300/300" alt="Mobile App Dashboard" className="gallery-image" />
</div>
</div>
<div className="col-md-4 col-6">
<div className="gallery-item">
<img src="/api/placeholder/300/300" alt="Door Sensor Installation" className="gallery-image" />
</div>
</div>
<div className="col-md-4 col-6">
<div className="gallery-item">
<img src="/api/placeholder/300/300" alt="System Architecture Diagram" className="gallery-image" />
</div>
</div>
<div className="col-md-4 col-6">
<div className="gallery-item">
<img src="/api/placeholder/300/300" alt="PCB Design" className="gallery-image" />
</div>
</div>
</div>
</div>
<div className={`modal-footer ${style.modalFooter}`}>
<a href="#" className={`btn btn-outline-secondary ${style.btnOutlineSecondary}`}>
<i className="fab fa-github btn-icon"></i>Source Code
</a>
<a href="#" className={`btn btn-outline-secondary ${style.btnOutlineSecondary}`}>
<i className="fas fa-external-link-alt btn-icon"></i>Live Demo
</a>
<a href="#" className={`btn btn-outline-secondary ${style.btnOutlineSecondary}`}>
<i className="fas fa-book btn-icon"></i>Documentation
</a>
<button type="button" className={`btn btn-secondary`} data-bs-dismiss="modal">Close</button>
</div> </div>
</div> </div>
</div> </div>
</div> );
); };
}
+1 -1
View File
@@ -1,4 +1,4 @@
import type { BlogPostProps } from "../components/BlogCard"; import type {BlogPostProps} from '../untils/BlogPostProps'
export const blogPostsData: BlogPostProps[] = [ export const blogPostsData: BlogPostProps[] = [
{ {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { ProjectProps, Category } from "../components/ProjectCard"; import type { ProjectProps, Category } from "../untils/ProjectProps";
type CategoryMap = Record<string, Category> type CategoryMap = Record<string, Category>
export const Categories: CategoryMap = { export const Categories: CategoryMap = {
+6 -1
View File
@@ -1,8 +1,9 @@
import { useState } from 'react'; import { useState } from 'react';
import { PageHeader } from '../components/PageHeader'; import { PageHeader } from '../components/PageHeader';
import { ProjectCard, type ProjectProps } from '../components/ProjectCard'; import { ProjectCard } from '../components/ProjectCard';
import { ProjectModal } from '../components/ProjectModal'; import { ProjectModal } from '../components/ProjectModal';
import { projectsData, Categories } from '../data/projectsData'; import { projectsData, Categories } from '../data/projectsData';
import type {ProjectProps} from '../untils/ProjectProps';
import style from '@styles/Project.module.scss' import style from '@styles/Project.module.scss'
@@ -15,6 +16,10 @@ export const Projects = () => {
? projectsData ? projectsData
: projectsData.filter(project => project.category.some(cat => cat.shortName.toLowerCase() === activeFilter)); : projectsData.filter(project => project.category.some(cat => cat.shortName.toLowerCase() === activeFilter));
if (selectedProject == null && filteredProjects.length > 0)
setSelectedProject(filteredProjects[0]);
const categories = Categories; const categories = Categories;
const featuredProject = projectsData.find(project => project.featured); const featuredProject = projectsData.find(project => project.featured);
+15
View File
@@ -0,0 +1,15 @@
export interface BlogPostProps {
id: string;
slug: string;
title: string;
excerpt: string;
image: string;
category: string;
date: string;
author: string;
commentCount: number;
readTime: string;
featured?: boolean;
tags: string[];
content: string;
}
+39
View File
@@ -0,0 +1,39 @@
export interface ProjectProps {
id: string;
title: string;
description: string;
projectDetails?: ProjectDetails;
image: string;
category: Category[];
featured?: boolean;
technologies: ProjectTech[];
links: {
github?: string;
demo?: string;
};
}
export interface ProjectDetails {
descriptions: string[];
startDate: string;
endDate: string;
dateFormatted?: string;
role: string;
status: string;
client: string;
keyFeatures: string[];
gallery: string[];
}
export interface Category {
[key: string]: string;
fullName: string;
shortName: string;
icon: string;
}
export interface ProjectTech {
name: string;
icon: string;
}