Files
terminal-portfolio/src/content.cpp
2026-04-15 20:27:20 -05:00

249 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <ftxui/component/component.hpp>
#include <ftxui/component/component_base.hpp>
#include <ftxui/component/screen_interactive.hpp>
#include <ftxui/dom/elements.hpp>
#include <string>
#include <vector>
#include "content.hpp"
using namespace ftxui;
// Hacker-style reusable styles
const auto hacker_text_style = color(Color::Green);
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("CS Enthusiast | Robotics Developer | Linux and FOSS Advocate") | hacker_text_style | center,
}) | hacker_border_style,
}) |
flex; });
}
Component MakeProjectsPage()
{
const std::vector<std::pair<std::string, std::string>> projects = {
{"GaitGuardian: IMU Processing for Parkinsons Disease (2024-2026)",
"• Python project for data processing and machine learning\n"
"• Hybrid biLSTM + CNN model for Freezing of Gait prediction\n"
"• Signal filtering and preprocessing reduces subject dependence\n"
"• High accuracy, end-to-end functionality"},
{"TEG-Powered Self-Stirring Device (20232024)",
"• 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 (2023Present)",
"• Custom inverse kinematics, pathing, and Computer Vision autonomy\n"
"• Top-30 globally for software performance, FTC State Finalist"},
{"Self Hosted Server — (2025-Present)",
"• Started full-time Ubuntu Server on old Chromebook\n"
"• Hosting Git, Music, Nginx, SSH (this), Immich, SMB, Glance, Cinny"},
{"Terminal Interactive Portfolio GUI (This)",
"• C++ Application using FTXUI to create shell interactive\n"
"• Created hardened passwordless user to allow ssh access"},
};
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,
}) |
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 (20232027)") | color(Color::LightGreen) | bold,
text("STEM & Multidisciplinary Endorsement") | hacker_text_style,
text("GPA: 4.79, 4.0 Unweighted | Rank: 2/1225 | SAT: 1550 | ACT 36") | 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("• Differential Equations (via Collin College)") | hacker_text_style,
}) | hacker_border_style,
}) |
flex; });
}
Component MakeWorkPage()
{
const std::vector<std::pair<std::string, std::string>> activities = {
{"Vice President, LASER (School Science Fair Organization)",
"Guiding and mentoring 120+ students in research and experimentation"},
{"Lead Software Developer, Technical Turbulence (FTC 23344)",
"Writing Java code for robot pathing, sensing, and control\nSpecializing in autonomous code and driver-controlled assistance + automation"},
{"Director of Technical Operations, 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; organized matches with competing schools\nDirector of Technology for Texas Scholastic Cricket Board"},
{"Indian Film Music Performer",
"Bass guitar, keys, and arrangement ofTamil, Hindi songs\nKeyboard player for High Octavez Band"},
};
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,
}) |
hacker_border_style; });
container->Add(card);
}
return Renderer(container, [container]() -> Element
{ return vbox(container->Render()) | vscroll_indicator | yframe | flex; });
}
Component MakeAwardsPage()
{
const std::vector<std::pair<std::string, std::string>> awards = {
{"Thermoelectric Generator Research Project (2024)",
"Dallas Fair: 1st in Engineering | USAF Recognition | USMA Best SI Units\nISEF Finalist"},
{"GaitGuardian ML Research (2025, 2026)",
"2025 Dallas Fair: 1st in Systems Software, Grand Prize Runner-Up\n2025 ISEF Finalist | 3rd in Robotics & Intelligent Systems\n2026 Dallas Fair: 2nd in Systems Software"},
{"National Speech & Debate (2025)",
"Impromptu Quarterfinalist at National and State Level"},
{"FTC Robotics — Technical Turbulence",
"2024 TX State Finalist, Area Innovate Award Winner\n2025 NTX Area Finalist Captain, Michiana Control Award (SW)"},
};
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,
}) |
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++ (WIP), Kotlin (FTC), Rust (WIP), limited HTML/CSS/JS\n\n"
"Applications:\n"
" Machine Learning, Signal Processing, TensorFlow, Computer Vision, Sever Management\n\n"
"Miscellaneous:\n"
" Public Speaking, CAD, LaTeX, 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: keshavanand.dev@gmail.com\n"
"LinkedIn: linkedin.com/in/keshavganand\n"
"GitHub: git.keshavanand.net/KeshavAnandCode\n"
"Matrix: @keshavanand:matrix.org\n"
"Resume: resume.keshavanand.net\n"
"DFW Metroplex, Texas\n\n"
"Updated: April 2026";
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<std::string> labels = {"About", "Projects", "Education", "Activities", "Awards", "Skills", "Contact"};
std::vector<Component> 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);
}