From 8add252e731e1dc11a932428fef1830a65d725ed Mon Sep 17 00:00:00 2001 From: KeshavAnandCode Date: Sun, 9 Nov 2025 19:48:41 -0600 Subject: [PATCH] Changes --- .gitignore | 88 +++++++ CMakeLists.txt | 24 ++ CNAME | 1 + commands.sh | 65 ++++++ content.cpp | 223 ++++++++++++++++++ content.hpp | 111 +++++++++ index.html | 518 ++++++++++++++++++++++++++++++++++++++++++ main.cpp | 13 ++ run-linux.sh | 13 ++ run-mac.sh | 13 ++ run-windows.bat | 13 ++ terminalOneLiners.txt | 3 + 12 files changed, 1085 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 CNAME create mode 100644 commands.sh create mode 100644 content.cpp create mode 100644 content.hpp create mode 100644 index.html create mode 100644 main.cpp create mode 100644 run-linux.sh create mode 100644 run-mac.sh create mode 100644 run-windows.bat create mode 100644 terminalOneLiners.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d3ed558 --- /dev/null +++ b/.gitignore @@ -0,0 +1,88 @@ +# ------------------------------------------------------ +# Build folders (your own build directories) +# ------------------------------------------------------ +linuxbuild/ +macbuild/ +winbuild/ + +# External + + +ftxui/ + +# If you ever add a generic build folder: +build/ +build-*/ + +# ------------------------------------------------------ +# CMake generated files +# ------------------------------------------------------ +CMakeFiles/ +CMakeCache.txt +cmake_install.cmake +Makefile +install_manifest.txt + +# ninja build +.ninja_log +.ninja_deps +rules.ninja + +# ------------------------------------------------------ +# Compiled object files / binaries +# ------------------------------------------------------ +*.o +*.obj +*.lo +*.la +*.a +*.lib +*.so +*.dll +*.dylib +*.exe +*.out +*.app +*.pch + +# ------------------------------------------------------ +# Logs + temporary files +# ------------------------------------------------------ +*.log +*.tmp +*.temp + +# ------------------------------------------------------ +# OS-generated crap +# ------------------------------------------------------ +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini + +# Linux +*~ + +# ------------------------------------------------------ +# Editor / IDE files +# ------------------------------------------------------ +.vscode/ +.idea/ +*.code-workspace + +# ------------------------------------------------------ +# Shell script caches +# ------------------------------------------------------ +*.swp +*.swo + +# ------------------------------------------------------ +# Keep these files (GitHub Pages) +# ------------------------------------------------------ +!index.html +!CNAME \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8e5f96f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.16) +project(PortfolioApp LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Add local FTXUI directory +add_subdirectory(ftxui) + +# Add your source files (adjust paths if needed) +add_executable(portfolio + main.cpp + content.cpp +) + +# Link with FTXUI +target_link_libraries(portfolio + PRIVATE + ftxui::screen + ftxui::dom + ftxui::component +) + diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..faf8daa --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +terminalportfolio.keshavanand.net \ No newline at end of file diff --git a/commands.sh b/commands.sh new file mode 100644 index 0000000..329b734 --- /dev/null +++ b/commands.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +#macos + +cd ~/Downloads/Code/Terminal +rm -rf macbuild +mkdir macbuild +cd macbuild +cmake -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" .. +make + + + +#Linux + +cd ~/Downloads/Code/Terminal +rm -rf linuxbuild +mkdir linuxbuild +cd linuxbuild + +docker run --rm -v "$(pwd)/..":/src -w /src gcc:latest bash -c " +apt-get update && apt-get install -y cmake make +mkdir -p build && cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS='-static' .. +make +cd .. +mv build linuxbuild/ +" + +#Linux Test + +cd ~/Downloads/Code/Terminal + +docker run --rm -v "$(pwd)/linuxbuild":/build -w /build --platform linux/amd64 ubuntu:22.04 bash -c " +apt-get update && apt-get install -y libstdc++6 +./build/portfolio +" + +#Windows: + +cd ~/Downloads/Code/Terminal +rm -rf winbuild +mkdir winbuild + +# Download Dockcross helper +docker run --rm dockcross/windows-static-x64 > ./winbuild/dockcross-windows +chmod +x ./winbuild/dockcross-windows + +# Build Windows binary inside winbuild +# Note: we mount the repo root (current folder) as /work +./winbuild/dockcross-windows bash -c " +mkdir -p /work/winbuild/build +cd /work/winbuild/build +cmake -DCMAKE_BUILD_TYPE=Release -S /work -B . +make +cp portfolio.exe /work/winbuild/ +" + +#Windows Test (requires Wine) + +cd ~/Downloads/Code/Terminal + +docker run --rm -v "$(pwd)/winbuild":/winbuild -w /winbuild --platform linux/amd64 \ + scottyhardy/docker-wine:latest wine64 build/portfolio.exe + diff --git a/content.cpp b/content.cpp new file mode 100644 index 0000000..f79fd5f --- /dev/null +++ b/content.cpp @@ -0,0 +1,223 @@ +#include +#include +#include +#include +#include +#include +#include "content.hpp" + +using namespace ftxui; + +// Hacker-style reusable styles +const auto hacker_text_style = color(Color::Green) | bold | dim; +const auto hacker_border_style = border | color(Color::Green); +const auto hacker_link_style = color(Color::LightGreen) | underlined; +const auto hacker_button_style = color(Color::Green) | bold; +const auto hacker_button_active_style = color(Color::LightGreen) | bold; + +// ------------------ +// Pages +// ------------------ + +Component MakeAboutPage() { + return Renderer([]() -> Element { + return vbox({ + vbox({ + text("Keshav Anand") | color(Color::LightGreen) | bold | center, + text("Student Researcher | ML + Robotics Developer | CS + Math Enthusiast") | hacker_text_style | center, + }) | hacker_border_style, + + }) | flex; + }); +} + +Component MakeProjectsPage() { + const std::vector> projects = { + {"🧠 GaitGuardian: IMU Processing for Parkinson’s Disease (2024–Present)", + "β€’ Hybrid biLSTM + CNN model for Freezing of Gait prediction\n" + "β€’ Signal segmentation reduces subject dependence\n" + "β€’ State-of-the-art accuracy, end-to-end functionality"}, + {"πŸ”₯ TEG-Powered Self-Stirring Device (2023–2024)", + "β€’ Built thermal energy harvesting prototype for self-stirring cookware\n" + "β€’ Developed mechanical + electrical integration\n" + "β€’ Won 1st at Dallas Fair, ISEF Finalist"}, + {"πŸ€– FTC Technical Turbulence (23344) β€” Lead Software Developer (2023–Present)", + "β€’ Custom inverse kinematics, pathing, and Computer Vision autonomy\n" + "β€’ Top-30 globally for software performance, FTC State Finalist"}, + }; + + Component container = Container::Vertical({}); + for (auto& p : projects) { + Component card = Renderer([p]() -> Element { + return vbox({ + text(p.first) | color(Color::LightGreen) | bold, + paragraph(p.second) | hacker_text_style | dim, + }) | hacker_border_style; + }); + container->Add(card); + } + + return Renderer(container, [container]() -> Element { + return vbox(container->Render()) | vscroll_indicator | yframe | flex; + }); +} + +Component MakeEducationPage() { + return Renderer([]() -> Element { + return vbox({ + vbox({ + text("🏫 Plano East Senior High School (2023–2027)") | color(Color::LightGreen) | bold, + text("STEM & Multidisciplinary Endorsement") | hacker_text_style, + text("GPA: 4.73 | Rank: 1/1273 | SAT: 1550") | hacker_text_style, + }) | hacker_border_style, + + separator(), + + vbox({ + text("πŸ“š Current Coursework:") | color(Color::LightGreen) | bold, + text("β€’ AP Chemistry") | hacker_text_style, + text("β€’ AP Physics I") | hacker_text_style, + text("β€’ Digital Electronics") | hacker_text_style, + text("β€’ American Studies (AP US History + AP English Language)") | hacker_text_style, + text("β€’ Calculus III (via Collin College)") | hacker_text_style, + }) | hacker_border_style, + }) | flex; + }); +} + +Component MakeWorkPage() { + const std::vector> activities = { + {"πŸ§ͺ Vice President, LASER (Science Fair Organization)", + "Guiding and mentoring 120+ students in research and experimentation"}, + {"πŸ’» Technology Officer, National Honor Society", + "Developed and maintained React-based management portal for 1000+ members"}, + {"🏏 Founder & Captain, Plano East Cricket Club", + "Established first school tapeball cricket team; coached and led events"}, + {"🎢 Indian Film Music Performer", + "Bass guitar & keyboard player in charity concerts; arrangement and production"}, + }; + + Component container = Container::Vertical({}); + for (auto& a : activities) { + Component card = Renderer([a]() -> Element { + return vbox({ + text(a.first) | color(Color::LightGreen) | bold, + text(a.second) | hacker_text_style | dim, + }) | hacker_border_style; + }); + container->Add(card); + } + + return Renderer(container, [container]() -> Element { + return vbox(container->Render()) | vscroll_indicator | yframe | flex; + }); +} + +Component MakeAwardsPage() { + const std::vector> awards = { + {"πŸ₯‡ Thermoelectric Generator Research Project (2024)", + "Dallas Fair: 1st in Engineering | USAF Recognition | USMA Best SI Units\nISEF Finalist"}, + {"πŸ₯ˆ GaitGuardian ML Research (2025)", + "Dallas Fair: 1st in Systems Software, Grand Prize Runner-Up\nISEF Finalist | 3rd in Robotics & Intelligent Systems"}, + {"πŸ… National Speech & Debate (2025)", + "Impromptu Quarterfinalist at District and State Level"}, + }; + + Component container = Container::Vertical({}); + for (auto& a : awards) { + Component card = Renderer([a]() -> Element { + return vbox({ + text(a.first) | color(Color::LightGreen) | bold, + paragraph(a.second) | hacker_text_style | dim, + }) | hacker_border_style; + }); + container->Add(card); + } + + return Renderer(container, [container]() -> Element { + return vbox(container->Render()) | vscroll_indicator | yframe | flex; + }); +} + +Component MakeSkillsPage() { + const std::string skills = + "πŸ’» Programming Languages:\n" + " Java, Python, Bash, C++ (Arduino), Kotlin (FTC), limited HTML/CSS/JS\n\n" + "🧠 Applications:\n" + " Machine Learning, Signal Processing, TensorFlow, Computer Vision\n\n" + "βš™οΈ Miscellaneous:\n" + " Public Speaking, CAD, PCB Design, Electrical Systems, Competition Math"; + + return Renderer([skills]() -> Element { + return paragraph(skills) | hacker_text_style | flex; + }); +} + +Component MakeContactPage() { + const std::string contact_info = + "πŸ“« Email: keshavanandofficial@gmail.com\n" + "πŸ”— LinkedIn: linkedin.com/in/keshavganand\n" + "πŸ’» GitHub: github.com/keshavanandcode\n" + "🌐 Resume: resume.keshavanand.net\n" + "πŸ“ DFW Metroplex, Texas\n\n" + "Updated: November 2025"; + + return Renderer([contact_info]() -> Element { + return paragraph(contact_info) | hacker_text_style | flex; + }); +} + +// Constructor implementation +PortfolioApp::PortfolioApp() { + about_page_ = MakeAboutPage(); + projects_page_ = MakeProjectsPage(); + education_page_ = MakeEducationPage(); + work_page_ = MakeWorkPage(); + awards_page_ = MakeAwardsPage(); + skills_page_ = MakeSkillsPage(); + contact_page_ = MakeContactPage(); + + pages_ = {about_page_, projects_page_, education_page_, + work_page_, awards_page_, skills_page_, contact_page_}; + + std::vector labels = {"About", "Projects", "Education", "Activities", "Awards", "Skills", "Contact"}; + + std::vector buttons; + for (int i = 0; i < (int)labels.size(); ++i) { + Component button = Button(labels[i], [&, i] { SwitchPage(i); }) + | (i == current_page_ ? hacker_button_active_style : hacker_button_style); + buttons.push_back(button); + } + + navigation_ = Container::Vertical(buttons); + Component separator_component = Renderer([] { return separator(); }); + + Add(Container::Horizontal(Components{navigation_, separator_component, pages_[current_page_]})); +} + +void PortfolioApp::SwitchPage(int index) { + current_page_ = index; + DetachAllChildren(); + Component separator_component = Renderer([] { return separator(); }); + Add(Container::Horizontal(Components{navigation_, separator_component, pages_[current_page_]})); +} + +Element PortfolioApp::Render() { + return hbox({ + navigation_->Render() | hacker_border_style, + separator(), + pages_[current_page_]->Render() | hacker_border_style | flex + }); +} + +bool PortfolioApp::OnEvent(Event event) { + if (event == Event::ArrowRight) { + SwitchPage((current_page_ + 1) % pages_.size()); + return true; + } + if (event == Event::ArrowLeft) { + SwitchPage((current_page_ - 1 + pages_.size()) % pages_.size()); + return true; + } + return ComponentBase::OnEvent(event); +} diff --git a/content.hpp b/content.hpp new file mode 100644 index 0000000..cdb0971 --- /dev/null +++ b/content.hpp @@ -0,0 +1,111 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +// ------------------ +// Structs +// ------------------ +struct Project { + std::string title; + std::string link; // Leave empty if no link +}; + +// ------------------ +// PageFactory Functions +// + +// ------------------ +/** + * Creates the About page component + * @return Component containing personal introduction and focus areas + */ +ftxui::Component MakeAboutPage(); + +/** + * Creates the Projects page component + * @return Component displaying list of projects with links + */ +ftxui::Component MakeProjectsPage(); + +/** + * Creates the Education page component + * @return Component showing educational background and achievements + */ +ftxui::Component MakeEducationPage(); + +/** + * Creates the Work page component + * @return Component displaying work experience and competitions + */ +ftxui::Component MakeWorkPage(); + +/** + * Creates the Awards page component + * @return Component displaying awards, competitions, and achievements + */ +ftxui::Component MakeAwardsPage(); + +/** + * Creates the Skills page component + * @return Component showing technical skills and expertise + */ +ftxui::Component MakeSkillsPage(); + +/** + * Creates the Contact page component + * @return Component with contact information + */ +ftxui::Component MakeContactPage(); + +// ------------------ +// Main Application Class +// ------------------ +/** + * Main portfolio application class that manages navigation and page switching + * Inherits from ftxui::ComponentBase to provide custom rendering and event handling + */ +class PortfolioApp : public ftxui::ComponentBase { +public: + /** + * Constructor - initializes all pages and navigation + */ + PortfolioApp(); + + /** + * Switch to a specific page by index + * @param index The page index to switch to (0-6) + */ + void SwitchPage(int index); + + /** + * Render the current application state + * @return Element representing the full UI layout + */ + ftxui::Element Render(); + + /** + * Handle keyboard events for navigation + * @param event The keyboard event to process + * @return true if event was handled, false otherwise + */ + bool OnEvent(ftxui::Event event) override; + +private: + int current_page_ = 0; // Currently active page index + + // UI Components + ftxui::Component navigation_; // Navigation sidebar + ftxui::Component about_page_; // About page component + ftxui::Component projects_page_; // Projects page component + ftxui::Component education_page_; // Education page component + ftxui::Component work_page_; // Work page component + ftxui::Component awards_page_; // Awards page component + ftxui::Component skills_page_; // Skills page component + ftxui::Component contact_page_; // Contact page component + + std::vector pages_; // Vector of all page components +}; diff --git a/index.html b/index.html new file mode 100644 index 0000000..c9a5bf4 --- /dev/null +++ b/index.html @@ -0,0 +1,518 @@ + + + + + +Terminal Portfolio + + + + + + + + +
+ +
+
+$ Detecting your OS...
+    
+
+ +
+
+ + +
+
+ +
+
+ + +
+ +
+ + +
Run at Your Own Risk
+ + + +
+ +
+
+ +
    +
  1. + Terminal Command Execution: + The command you copy downloads a platform-specific script: +
      +
    • .sh for Mac/Linux
    • +
    • .bat for Windows
    • +
    + This script is hosted on my GitHub and automatically runs the corresponding binary. +
  2. + +
  3. + Binary Execution: + The binary is compiled in C++ separately for each OS and controls the standard input/output of your terminal to create a clean, interactive interface. +
  4. + +
  5. + FTXUI Integration: + It leverages the FTXUI library to render a web-like interactive menu directly inside your terminal, making navigation and presentation of my portfolio terminal-friendly but visually elegant. +
  6. + +
  7. + Cross-Platform Support: + Each OS has its own binary to ensure consistent behavior on Windows, Mac, and Linux. +
  8. +
+ +

+ + View Source on GitHub + +

+
+
+
+
+ + + + \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..aef7def --- /dev/null +++ b/main.cpp @@ -0,0 +1,13 @@ +#include "content.hpp" +#include +#include +#include +#include +#include + +int main() { + ftxui::ScreenInteractive screen = ftxui::ScreenInteractive::Fullscreen(); + ftxui::Component app = std::make_shared(); + screen.Loop(app); + return 0; +} diff --git a/run-linux.sh b/run-linux.sh new file mode 100644 index 0000000..76d9e9f --- /dev/null +++ b/run-linux.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Download the Linux executable +curl -L https://github.com/KeshavAnandCode/Terminal/releases/download/v2.0/portfolio-linux -o /tmp/portfolio + +# Make it executable +chmod +x /tmp/portfolio + +# Run it +/tmp/portfolio + +# Clean up +rm /tmp/portfolio \ No newline at end of file diff --git a/run-mac.sh b/run-mac.sh new file mode 100644 index 0000000..acfbfd7 --- /dev/null +++ b/run-mac.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Download the macOS executable +curl -L https://github.com/KeshavAnandCode/Terminal/releases/download/v2.0/portfolio-mac -o /tmp/portfolio + +# Make it executable +chmod +x /tmp/portfolio + +# Run it +/tmp/portfolio + +# Clean up +rm /tmp/portfolio \ No newline at end of file diff --git a/run-windows.bat b/run-windows.bat new file mode 100644 index 0000000..78b1055 --- /dev/null +++ b/run-windows.bat @@ -0,0 +1,13 @@ +@echo off +setlocal + +:: Download the Windows executable +powershell -Command "Invoke-WebRequest -Uri 'https://github.com/KeshavAnandCode/Terminal/releases/download/v2.0/portfolio-windows' -OutFile '%TEMP%\\portfolio.exe'" + +:: Run the executable +"%TEMP%\portfolio.exe" + +:: Clean up +del "%TEMP%\portfolio.exe" + +endlocal \ No newline at end of file diff --git a/terminalOneLiners.txt b/terminalOneLiners.txt new file mode 100644 index 0000000..0b44490 --- /dev/null +++ b/terminalOneLiners.txt @@ -0,0 +1,3 @@ +/bin/bash -c "$(curl -fsSL https://terminalportfolio.keshavanand.net/run-mac.sh)" for Mac +/bin/bash -c "$(curl -fsSL https://terminalportfolio.keshavanand.net/run-linux.sh)" for linux +iwr https://terminalportfolio.keshavanand.net/run-windows.bat -OutFile \$env:TEMP\run-windows.bat; Start-Process \$env:TEMP\run-windows.bat -Wait \ No newline at end of file