Skip to content
Merged

V2 #27

Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions public/.well-known/ai-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"url": "https://rahulap.vercel.app/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "https://rahulap.vercel.app/favicon-192x192.png",
"contact_email": "rahulap.js@example.com",
"legal_info_url": "https://rahulap.vercel.app/contact"
"logo_url": "https://rahulap.vercel.app/favicon192.png",
"contact_email": "itsrahulap@gmail.com",
"legal_info_url": "https://rahulap.vercel.app/"
}
86 changes: 86 additions & 0 deletions public/data/projects.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
[
{
"name": "EnvScope",
"subtitle": "Context-Aware Frontend Security & Secret Detection Engine",
"description": "A Chrome extension that scans live JavaScript bundles for exposed secrets, combining regex and AST analysis to catch high-risk leaks with low false positives.",
"tech": ["JavaScript", "TypeScript", "Chrome Extensions API", "AST (Acorn)", "Regex Engine", "Web APIs"],
"url": "https://github.com/itsrahulap/EnvScope"
},
{
"name": "TestPilot",
"subtitle": "Intelligent Bug Detection & Telemetry Chrome Extension",
"description": "A silent telemetry layer for web apps that captures console errors, failed requests, and performance metrics in real time, with no backend required.",
"tech": ["JavaScript", "Chrome Extensions API", "Web APIs", "Performance API"],
"url": "https://github.com/itsrahulap/TestPilot"
},
{
"name": "AskSQLAI",
"subtitle": "Schema-Aware Natural Language to SQL Generation Engine",
"description": "Converts plain-English questions into safe, executable SQL by introspecting the live database schema, with layered guardrails against hallucinated tables or columns.",
"tech": ["React (Vite)", "TypeScript", "FastAPI", "PostgreSQL", "Gemini 2.5 Flash", "Gemini (Google ADK)", "Python"],
"url": "https://github.com/itsrahulap/AskSQLAI"
},
{
"name": "MeetlyAI",
"subtitle": "AI-Powered Meeting Notes, Decisions & Action Items Generator",
"description": "Turns raw meeting transcripts into structured summaries, decisions, and owned action items using strict JSON-schema-enforced prompting.",
"tech": ["React (Vite)", "TypeScript", "FastAPI", "Gemini 2.5 Flash", "Gemini (Google ADK)", "Python"],
"url": "https://github.com/itsrahulap/MeetlyAI"
},
{
"name": "SearchlyAI",
"subtitle": "Session-Based AI Search Engine using RAG over Documents & Web",
"description": "A full RAG pipeline for semantic Q&A over uploaded documents and web pages, using FAISS vector search and Gemini responses grounded strictly in retrieved context.",
"tech": ["React (Vite)", "TypeScript", "FastAPI", "FAISS", "Gemini 2.5 Flash", "Gemini (Google ADK)", "Python"],
"url": "https://github.com/itsrahulap/SearchlyAI"
},
{
"name": "SemanticFeed",
"subtitle": "AI-Powered Tech News Aggregation & Deduplication Platform",
"description": "Aggregates tech news from multiple sources, deduplicates related articles into unified stories, and generates concise AI summaries via scheduled background jobs.",
"tech": ["React (Vite)", "TypeScript", "Redux", "FastAPI", "PostgreSQL", "Gemini (Google ADK)", "Gemini 2.5 Flash", "Python"],
"url": "https://github.com/itsrahulap/SemanticFeed"
},
{
"name": "QueryDoc",
"subtitle": "Retrieval-Augmented Document Q&A System",
"description": "A secure RAG chat system for a single uploaded PDF, supporting multi-question conversations with session-isolated vector storage and no stored credentials.",
"tech": ["React (Vite)", "TypeScript", "FastAPI", "FAISS", "Gemini (Google ADK)", "Python"],
"url": "https://github.com/itsrahulap/QueryDoc"
},
{
"name": "AI-Powered SOAP Note Generator",
"subtitle": "Multi-Agent Medical Assistant",
"description": "A multi-agent pipeline that extracts structured clinical data from patient conversations and generates guideline-backed, safety-checked SOAP notes.",
"tech": ["Python", "Google ADK", "Gemini 2.5 Flash Lite", "Google Search Tool", "InMemoryRunner"],
"url": "https://www.kaggle.com/code/itsrahulap/multi-agent-medical-intake-soap-note-generator"
},
{
"name": "Readme Creator",
"subtitle": "AI-Powered README Generator",
"description": "A web app for building structured, professional READMEs from templates, with live markdown preview and Gemini-powered content optimization.",
"tech": ["React", "Redux", "Gemini", "Material-UI"],
"url": "https://github.com/itsrahulap/readmeGenerator"
},
{
"name": "Gemini PDF Analyzer",
"subtitle": "Streamlit + GenAI Resume Parsing Tool",
"description": "Extracts and parses resume PDFs into structured JSON, then generates a polished first-person summary using a selectable Gemini model.",
"tech": ["Streamlit", "Python", "Gemini 1.5 Flash/Pro"],
"url": "https://github.com/itsrahulap/ResumeParserAI"
},
{
"name": "EasyDiagno",
"subtitle": "AI-Powered Symptom Checker",
"description": "A cross-platform symptom-checking app with a chatbot interface, ML-based diagnosis, and a hospital locator with specialization filters.",
"tech": ["Flutter", "Firebase", "Python", "ML"],
"url": "https://github.com/itsrahulap/EasyDiagno"
},
{
"name": "Streamify",
"subtitle": "Full Stack Chat App",
"description": "A full-stack real-time messaging and video chat app supporting 100+ concurrent users, with screen sharing and image sharing built in.",
"tech": ["React", "Express", "WebRTC"],
"url": "https://github.com/itsrahulap/streamify"
}
]
62 changes: 62 additions & 0 deletions public/data/resume.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"basics": {
"name": "Rahul AP",
"label": "Software Engineer | Full-Stack & Generative AI Developer",
"location": "Kerala, India"
},
"contact": {
"email": "itsrahulap@gmail.com",
"linkedin": "https://linkedin.com/in/itsrahulap",
"github": "https://github.com/zccott",
"cv": "https://drive.google.com/file/d/1D4oUwmDywLL6vAoz3bP4P1gr9Emsp3ms/view?usp=sharing"
},
"education": [
{
"institution": "Kerala Government Polytechnic College",
"degree": "Diploma in Computer Engineering",
"year": "2021–2024"
}
],
"experience": [
{
"company": "AOT Technologies",
"role": "Software Engineer",
"year": "2024–Present",
"description": [
"Worked across frontend + backend for Canadian healthcare platforms.",
"Angular + MUI + reusable UI components.",
"Integrated REST APIs for user onboarding & appointment systems.",
"Implemented NgRx/RxJS application-wide state.",
"AI fax automation using Python + OpenAI/Gemini + Temporal.",
"Real-time SOAP note tool using FastAPI + WebSockets + Twilio + Whisper."
]
},
{
"company": "Nexus Technologies",
"role": "Intern",
"year": "2023–2024",
"description": [
"Healthcare mobile app (Find doctors by symptoms).",
"Designed UX/UI screens.",
"AI symptom analysis feature.",
"Flutter cross-platform development."
]
}
],
"skills": {
"frontend": ["React", "Angular", "TypeScript", "JavaScript (ES6+)", "SCSS", "HTML5", "CSS3"],
"backend": ["Node.js", "Express", "FastAPI", "Python", "PostgreSQL", "MongoDB", "REST APIs"],
"state": ["NgRx", "NGXS", "RxJS", "Redux Toolkit"],
"ai_tools": [
"GitHub Copilot",
"ChatGPT",
"Gemini CLI / AI Studio",
"Cloud Code (AI-assisted development)",
"Antigravity (AI dev tool)"
],
"ai": ["OpenAI", "Gemini", "Google ADK", "LangChain", "Whisper", "LLM Prompt Engineering"],
"tools": ["Docker", "Temporal", "Git", "Cypress", "Postman", "PyPDF2", "BeautifulSoup"],
"realtime": ["WebSockets", "WebRTC", "Twilio"],
"design": ["Figma", "UI/UX"]
}
}
53 changes: 53 additions & 0 deletions public/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,65 @@ components:
type: string
label:
type: string
location:
type: string
contact:
type: object
properties:
email:
type: string
linkedin:
type: string
github:
type: string
cv:
type: string
education:
type: array
items:
type: object
properties:
institution:
type: string
degree:
type: string
year:
type: string
experience:
type: array
items:
type: object
properties:
company:
type: string
role:
type: string
year:
type: string
description:
type: array
items:
type: string
skills:
type: object
additionalProperties:
type: array
items:
type: string
getProjectsResponse:
type: array
items:
type: object
properties:
name:
type: string
subtitle:
type: string
description:
type: string
tech:
type: array
items:
type: string
url:
type: string
26 changes: 1 addition & 25 deletions public/sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,8 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://rahulap.vercel.app/</loc>
<lastmod>2025-11-28</lastmod>
<lastmod>2026-07-02</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://rahulap.vercel.app/journey</loc>
<lastmod>2025-11-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://rahulap.vercel.app/skills</loc>
<lastmod>2025-11-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://rahulap.vercel.app/projects</loc>
<lastmod>2025-11-28</lastmod>
<changefreq>monthly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://rahulap.vercel.app/contact</loc>
<lastmod>2025-11-28</lastmod>
<changefreq>yearly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
15 changes: 14 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { AnimatePresence } from 'framer-motion';
import { ThemeProvider } from './context/ThemeContext';
import LoadingScreen from './components/LoadingScreen/LoadingScreen';
import Terminal from './components/Terminal/Terminal';
import PortfolioView from './components/PortfolioView/PortfolioView';
import ModeSwitch, { ViewMode } from './components/ModeSwitch/ModeSwitch';
import './styles/global.scss';

const App: React.FC = () => {
const [loading, setLoading] = useState(true);
const [view, setView] = useState<ViewMode>('terminal');
const handleComplete = useCallback(() => setLoading(false), []);

return (
Expand All @@ -19,7 +22,17 @@ const App: React.FC = () => {
)}
</AnimatePresence>

{!loading && <Terminal />}
{!loading && (
<>
<ModeSwitch mode={view} onChange={setView} />
<div style={{ display: view === 'terminal' ? 'contents' : 'none' }}>
<Terminal onSwitchToGui={() => setView('gui')} />
</div>
<div style={{ display: view === 'gui' ? 'contents' : 'none' }}>
<PortfolioView />
</div>
</>
)}
</ThemeProvider>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/components/LoadingScreen/LoadingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface Props {
}

const BOOT_LINES = [
{ ts: '0.0001', msg: 'Initializing RahulOS...' },
{ ts: '0.0001', msg: 'Initializing Rahul AP...' },
{ ts: '0.0042', msg: 'Loading kernel...' },
{ ts: '0.0125', msg: 'Loading React...' },
{ ts: '0.0210', msg: 'Loading portfolio...' },
Expand Down Expand Up @@ -74,7 +74,7 @@ const LoadingScreen: React.FC<Props> = ({ onComplete }) => {
>
<div className="ls-content">
<div className="ls-brand">
RAHUL_OS_V2.0
RAHUL_AP_V2.0
<span className="ls-cursor">▋</span>
</div>

Expand Down
59 changes: 59 additions & 0 deletions src/components/ModeSwitch/ModeSwitch.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.mode-switch {
position: fixed;
top: 14px;
right: 14px;
z-index: 30;
display: grid;
grid-template-columns: 1fr 1fr;
align-items: stretch;
padding: 3px;
background: var(--glass-bg);
border: 1px solid var(--border-color);
border-radius: 999px;
backdrop-filter: blur(var(--glass-blur, 0px));
font-family: var(--font-mono);
}

.mode-switch-option {
position: relative;
z-index: 1;
padding: 6px 14px;
border: none;
background: transparent;
border-radius: 999px;
color: var(--muted);
font-family: inherit;
font-size: 0.72rem;
letter-spacing: 0.02em;
cursor: pointer;
transition: color 0.2s ease;
white-space: nowrap;

&.is-active {
color: var(--on-primary, var(--bg));
}

&:hover:not(.is-active) {
color: var(--fg);
}
}

.mode-switch-thumb {
position: absolute;
top: 3px;
bottom: 3px;
left: 3px;
width: calc(50% - 3px);
background: var(--primary);
border-radius: 999px;
box-shadow: 0 0 12px 0 color-mix(in srgb, var(--primary) 50%, transparent);
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);

&.is-left {
transform: translateX(0);
}

&.is-right {
transform: translateX(100%);
}
}
Loading