├── .DS_Store ├── LICENSE ├── package.json ├── README.md ├── .gitignore └── card.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lohitkolluri/NPX-Business-Card/HEAD/.DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Lohit Kolluri 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lohitkolluri", 3 | "version": "3.1.0", 4 | "description": "A personal card for Lohit Kolluri", 5 | "main": "card.js", 6 | "bin": { 7 | "lohitkolluri": "card.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/lohitkolluri/NPX-Business-Card.git" 12 | }, 13 | "homepage": "https://github.com/lohitkolluri/NPX-Business-Card", 14 | "bugs": { 15 | "url": "https://github.com/lohitkolluri/NPX-Business-Card/issues" 16 | }, 17 | "scripts": { 18 | "test": "jest", 19 | "pub": "npm version patch && npm publish" 20 | }, 21 | "type": "module", 22 | "dependencies": { 23 | "axios": "^1.7.9", 24 | "boxen": "^8.0.1", 25 | "chalk": "^5.4.0", 26 | "clear": "^0.1.0", 27 | "cli-spinners": "^2.9.2", 28 | "figlet": "^1.8.0", 29 | "gradient-string": "^3.0.0", 30 | "inquirer": "^12.2.0", 31 | "nanospinner": "^1.2.2", 32 | "open": "^7.4.2", 33 | "ora": "^5.4.1", 34 | "uuid": "^10.0.0" 35 | }, 36 | "devDependencies": { 37 | "jest": "^29.0.0" 38 | }, 39 | "keywords": [ 40 | "card", 41 | "npm", 42 | "npm card", 43 | "npx", 44 | "npx card", 45 | "business card" 46 | ], 47 | "author": "Lohit Kolluri (https://lohit.is-a.dev/)", 48 | "license": "MIT", 49 | "engines": { 50 | "node": ">=16.0.0" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NPX Business Card 2 | 3 | A modern, interactive CLI business card showcasing Lohit Kolluri's portfolio and contact information with beautiful animations and gradient colors. 4 | 5 | ![npm version](https://img.shields.io/npm/v/lohitkolluri) 6 | ![npm downloads](https://img.shields.io/npm/dt/lohitkolluri) 7 | ![license](https://img.shields.io/github/license/lohitkolluri/NPX-Buisness-Card) 8 | 9 | ## Features 10 | 11 | - Beautiful gradient colors and animations 12 | - Direct email contact 13 | - Quick resume access 14 | - Easy meeting scheduler 15 | - Portfolio website access 16 | - Professional links (GitHub, LinkedIn) 17 | - Fast and responsive interface 18 | - User-friendly CLI menu 19 | 20 | ## Quick Start 21 | 22 | Run the business card directly in your terminal: 23 | 24 | ```bash 25 | npx lohitkolluri 26 | ``` 27 | 28 | No installation required! Just run the command and interact with the card. 29 | 30 | ## Technologies Used 31 | 32 | - **Node.js** - Runtime environment 33 | - **Chalk** - Terminal styling 34 | - **Boxen** - Boxes in terminal 35 | - **Inquirer** - Interactive CLI 36 | - **Gradient-string** - Beautiful gradients 37 | - **Figlet** - ASCII art text 38 | - **Nanospinner** - Loading animations 39 | 40 | ## Connect with Lohit 41 | 42 | - **GitHub**: [github.com/lohitkolluri](https://github.com/lohitkolluri) 43 | - **LinkedIn**: [linkedin.com/in/kollurilohit](https://linkedin.com/in/kollurilohit) 44 | - **Website**: [lohit.is-a.dev](https://lohit.is-a.dev) 45 | - **Email**: [lohitkolluri@gmail.com](mailto:lohitkolluri@gmail.com) 46 | 47 | ## License 48 | 49 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details. 50 | 51 | ## Changelog 52 | 53 | ### Version 3.0.0 54 | - Reduced animation delays for better UX 55 | - Improved text formatting 56 | - Updated skill set display 57 | - Enhanced error handling 58 | - Added gradient effects 59 | - Optimized loading times -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---- Node ---- 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | *.lcov 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # Bower dependency directory (https://bower.io/) 34 | bower_components 35 | 36 | # node-waf configuration 37 | .lock-wscript 38 | 39 | # Compiled binary addons (https://nodejs.org/api/addons.html) 40 | build/Release 41 | 42 | # Dependency directories 43 | node_modules/ 44 | jspm_packages/ 45 | 46 | # Snowpack dependency directory (https://snowpack.dev/) 47 | web_modules/ 48 | 49 | # TypeScript cache 50 | *.tsbuildinfo 51 | 52 | # Optional npm cache directory 53 | .npm 54 | 55 | # Optional eslint cache 56 | .eslintcache 57 | 58 | # Optional stylelint cache 59 | .stylelintcache 60 | 61 | # Microbundle cache 62 | .rpt2_cache/ 63 | .rts2_cache_cjs/ 64 | .rts2_cache_es/ 65 | .rts2_cache_umd/ 66 | 67 | # Optional REPL history 68 | .node_repl_history 69 | 70 | # Output of 'npm pack' 71 | *.tgz 72 | 73 | # Yarn Integrity file 74 | .yarn-integrity 75 | 76 | # dotenv environment variable files 77 | .env 78 | .env.development.local 79 | .env.test.local 80 | .env.production.local 81 | .env.local 82 | 83 | # parcel-bundler cache (https://parceljs.org/) 84 | .cache 85 | .parcel-cache 86 | 87 | # Next.js build output 88 | .next 89 | out 90 | 91 | # Nuxt.js build / generate output 92 | .nuxt 93 | dist 94 | 95 | # Gatsby files 96 | .cache/ 97 | # Comment in the public line in if your project uses Gatsby and not Next.js 98 | # https://nextjs.org/blog/next-9-1#public-directory-support 99 | # public 100 | 101 | # vuepress build output 102 | .vuepress/dist 103 | 104 | # vuepress v2.x temp and cache directory 105 | .temp 106 | .cache 107 | 108 | # Docusaurus cache and generated files 109 | .docusaurus 110 | 111 | # Serverless directories 112 | .serverless/ 113 | 114 | # FuseBox cache 115 | .fusebox/ 116 | 117 | # DynamoDB Local files 118 | .dynamodb/ 119 | 120 | # TernJS port file 121 | .tern-port 122 | 123 | # Stores VSCode versions used for testing VSCode extensions 124 | .vscode-test 125 | 126 | # yarn v2 127 | .yarn/cache 128 | .yarn/unplugged 129 | .yarn/build-state.yml 130 | .yarn/install-state.gz 131 | .pnp.* 132 | -------------------------------------------------------------------------------- /card.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import boxen from 'boxen'; 4 | import chalk from 'chalk'; 5 | import inquirer from 'inquirer'; 6 | import { createSpinner } from 'nanospinner'; 7 | import gradient from 'gradient-string'; 8 | import figlet from 'figlet'; 9 | import { fileURLToPath } from 'url'; 10 | import { dirname } from 'path'; 11 | import openURL from 'open'; 12 | import { setTimeout as sleep } from 'timers/promises'; 13 | 14 | const __filename = fileURLToPath(import.meta.url); 15 | const __dirname = dirname(__filename); 16 | 17 | // Configuration object with contact information and theme settings 18 | const CONFIG = { 19 | PERSONAL_INFO: { 20 | NAME: 'Lohit Kolluri', 21 | TITLE: 'Full Stack Developer & Student', 22 | EDUCATION: 'SRM University', 23 | SKILLS: ['DevOps', 'Web Development', 'Cyber Security', 'Machine Learning'], 24 | }, 25 | URLS: { 26 | EMAIL: 'mailto:lohitkolluri@gmail.com', 27 | RESUME: 'https://drive.google.com/file/u/1/d/1KwoW5uTW2aUEoi14CnM6JGQatup_5aAf/view?usp=sharing', 28 | MEETING: 'https://calendly.com/lohitkolluri/30min', 29 | PORTFOLIO: 'https://lohit.is-a.dev/', 30 | GITHUB: 'https://github.com/lohitkolluri', 31 | LINKEDIN: 'https://linkedin.com/in/kollurilohit', 32 | }, 33 | THEME: { 34 | BORDER_COLOR: 'green', 35 | BG_COLOR: '#1a1a1a', 36 | ANIMATION_SPEED: { 37 | FAST: 10, 38 | MEDIUM: 30, 39 | SLOW: 50, 40 | }, 41 | }, 42 | }; 43 | 44 | // Utility functions 45 | const createAnimatedSpinner = async (text, duration = 500) => { 46 | const spinner = createSpinner(text).start(); 47 | await sleep(duration); 48 | return spinner; 49 | }; 50 | 51 | const animateText = async (text, speed = CONFIG.THEME.ANIMATION_SPEED.FAST) => { 52 | process.stdout.write('\n'); 53 | for (const char of text) { 54 | process.stdout.write(char); 55 | await sleep(speed); 56 | } 57 | process.stdout.write('\n'); 58 | }; 59 | 60 | // Component for welcome banner 61 | const WelcomeBanner = async () => { 62 | console.clear(); 63 | console.log('\n'); 64 | const spinner = await createAnimatedSpinner('Initializing...', 300); 65 | spinner.success(); 66 | 67 | return new Promise((resolve) => { 68 | figlet(CONFIG.PERSONAL_INFO.NAME, { 69 | font: 'Big', 70 | horizontalLayout: 'default', 71 | verticalLayout: 'default', 72 | }, async (err, data) => { 73 | if (!err) { 74 | const lines = data.split('\n'); 75 | for (const line of lines) { 76 | console.log(gradient.rainbow(line)); 77 | await sleep(CONFIG.THEME.ANIMATION_SPEED.MEDIUM); 78 | } 79 | await animateText( 80 | `{ ${CONFIG.PERSONAL_INFO.TITLE} }`, 81 | CONFIG.THEME.ANIMATION_SPEED.SLOW 82 | ); 83 | } 84 | resolve(); 85 | }); 86 | }); 87 | }; 88 | 89 | // Component for profile card 90 | const ProfileCard = async () => { 91 | const cardData = { 92 | name: gradient.pastel(CONFIG.PERSONAL_INFO.NAME), 93 | title: chalk.white(CONFIG.PERSONAL_INFO.TITLE), 94 | education: `${chalk.white('Student At')} ${gradient.morning(CONFIG.PERSONAL_INFO.EDUCATION)}`, 95 | github: `${chalk.white('{')} ${chalk.gray('github.com/')}${chalk.green('lohitkolluri')} ${chalk.white('}')}`, 96 | linkedin: `${chalk.white('{')} ${chalk.gray('linkedin.com/in/')}${chalk.blue('kollurilohit')} ${chalk.white('}')}`, 97 | web: `${chalk.white('{')} ${chalk.cyan(CONFIG.URLS.PORTFOLIO)} ${chalk.white('}')}`, 98 | npx: `${chalk.red('npx')} ${chalk.white('lohitkolluri')}`, 99 | skills: gradient.cristal(CONFIG.PERSONAL_INFO.SKILLS.join(' | ')), 100 | }; 101 | 102 | const card = boxen( 103 | [ 104 | cardData.name, 105 | cardData.title, 106 | '', 107 | `🎓 ${cardData.education}`, 108 | '', 109 | `⚡ Skills: ${cardData.skills}`, 110 | '', 111 | `📦 GitHub: ${cardData.github}`, 112 | `💼 LinkedIn: ${cardData.linkedin}`, 113 | `🌐 Website: ${cardData.web}`, 114 | '', 115 | `📇 Card: ${cardData.npx}`, 116 | '', 117 | gradient.passion('🚀 Available for exciting opportunities and collaborations!'), 118 | gradient.cristal('💭 Let\'s connect and create something amazing together!'), 119 | ].join('\n'), 120 | { 121 | padding: 1, 122 | margin: 1, 123 | borderStyle: 'round', 124 | borderColor: CONFIG.THEME.BORDER_COLOR, 125 | float: 'center', 126 | backgroundColor: CONFIG.THEME.BG_COLOR, 127 | title: chalk.green.bold('Lohit\'s Business Card'), 128 | titleAlignment: 'center', 129 | } 130 | ); 131 | 132 | for (const line of card.split('\n')) { 133 | console.log(line); 134 | await sleep(CONFIG.THEME.ANIMATION_SPEED.FAST); 135 | } 136 | }; 137 | 138 | // Action handlers 139 | const actionHandlers = { 140 | email: async () => { 141 | const spinner = await createAnimatedSpinner('Opening mail client...'); 142 | await openURL(CONFIG.URLS.EMAIL); 143 | spinner.success({ text: gradient.passion('📧 Email client opened!') }); 144 | await animateText(chalk.green('Looking forward to hearing from you!')); 145 | }, 146 | 147 | viewResume: async () => { 148 | const spinner = await createAnimatedSpinner('Preparing to open resume...'); 149 | try { 150 | await openURL(CONFIG.URLS.RESUME); 151 | spinner.success({ text: chalk.green('Resume opened in your browser! 🎉') }); 152 | await animateText(chalk.gray('Tip: You can download it directly from Google Drive')); 153 | } catch (err) { 154 | spinner.error({ text: chalk.red('Failed to open resume 😢') }); 155 | console.error(chalk.red('Error:'), err.message); 156 | throw err; 157 | } 158 | }, 159 | 160 | scheduleMeeting: async () => { 161 | const spinner = await createAnimatedSpinner('Opening scheduler...'); 162 | await openURL(CONFIG.URLS.MEETING); 163 | spinner.success({ text: gradient.fruit('📅 Scheduler opened!') }); 164 | await animateText(chalk.green('Excited to chat with you soon!')); 165 | }, 166 | 167 | viewPortfolio: async () => { 168 | const spinner = await createAnimatedSpinner('Loading portfolio...'); 169 | await openURL(CONFIG.URLS.PORTFOLIO); 170 | spinner.success({ text: gradient.teen('🌐 Portfolio opened!') }); 171 | await animateText(chalk.green('Hope you enjoy exploring my work!')); 172 | }, 173 | 174 | viewGitHub: async () => { 175 | const spinner = await createAnimatedSpinner('Opening GitHub...'); 176 | await openURL(CONFIG.URLS.GITHUB); 177 | spinner.success({ text: gradient.atlas('💻 GitHub profile opened!') }); 178 | await animateText(chalk.green('Check out my latest projects!')); 179 | }, 180 | }; 181 | 182 | // Menu options 183 | const menuOptions = [ 184 | { 185 | type: 'list', 186 | name: 'action', 187 | message: gradient.cristal('What would you like to do?'), 188 | choices: [ 189 | { name: `📧 ${gradient.passion('Send an Email')}`, value: 'email' }, 190 | { name: `📥 ${gradient.morning('View Resume')}`, value: 'viewResume' }, 191 | { name: `📅 ${gradient.fruit('Schedule a Meeting')}`, value: 'scheduleMeeting' }, 192 | { name: `🌐 ${gradient.teen('Visit Portfolio')}`, value: 'viewPortfolio' }, 193 | { name: `💻 ${gradient.atlas('View GitHub')}`, value: 'viewGitHub' }, 194 | { name: gradient.rainbow('🚪 Exit'), value: 'quit' }, 195 | ], 196 | }, 197 | ]; 198 | 199 | // Main application 200 | const main = async () => { 201 | try { 202 | await WelcomeBanner(); 203 | await ProfileCard(); 204 | 205 | console.log( 206 | gradient.passion('\n💡 Tip: Use ') + 207 | chalk.cyan('cmd/ctrl + click') + 208 | gradient.passion(' on links to open directly.\n') 209 | ); 210 | 211 | while (true) { 212 | const { action } = await inquirer.prompt(menuOptions); 213 | 214 | if (action === 'quit') { 215 | await animateText(gradient.rainbow('\n👋 Thanks for stopping by! Have a great day!\n')); 216 | break; 217 | } 218 | 219 | await actionHandlers[action](); 220 | } 221 | } catch (error) { 222 | console.error(chalk.red('\n❌ An error occurred:'), error.message); 223 | process.exit(1); 224 | } 225 | }; 226 | 227 | // Run the application 228 | main().catch(console.error); --------------------------------------------------------------------------------