pages terminal scripts
This commit is contained in:
@@ -39,8 +39,23 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.workspaces.desktop-only,
|
||||||
|
.window-title.desktop-only {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.desktop-only {
|
.desktop-only,
|
||||||
|
.workspaces.desktop-only,
|
||||||
|
.window-title.desktop-only {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-left {
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-center {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +119,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.35rem;
|
gap: 0.35rem;
|
||||||
padding: 0.35rem 0.6rem;
|
padding: 0.35rem 0.4rem;
|
||||||
color: var(--bar-muted);
|
color: var(--bar-muted);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -193,7 +208,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: calc(100% + 0.5rem);
|
top: calc(100% + 0.5rem);
|
||||||
right: 0;
|
right: 0;
|
||||||
min-width: 160px;
|
min-width: 175px;
|
||||||
background: var(--bar-bg);
|
background: var(--bar-bg);
|
||||||
border: 1px solid var(--bar-border);
|
border: 1px solid var(--bar-border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -251,7 +266,7 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
z-index: 999;
|
z-index: 997;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
@@ -264,10 +279,11 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
background: var(--bar-bg);
|
background: var(--bar-bg);
|
||||||
border-bottom: 1px solid var(--bar-border);
|
border-bottom: 1px solid var(--bar-border);
|
||||||
z-index: 998;
|
z-index: 1000;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||||
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav-links {
|
.mobile-nav-links {
|
||||||
@@ -286,10 +302,18 @@
|
|||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
transition: all 0.15s ease;
|
transition: all 0.15s ease;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav-link:hover {
|
.mobile-nav-link:hover {
|
||||||
background: var(--bar-bg-module);
|
background: var(--bar-bg-module);
|
||||||
|
color: var(--bar-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-link:active {
|
||||||
|
transform: scale(0.98);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-nav-link.active {
|
.mobile-nav-link.active {
|
||||||
@@ -341,11 +365,18 @@
|
|||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
transition: all 0.15s ease;
|
transition: all 0.15s ease;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-theme-btn:hover {
|
.mobile-theme-btn:hover {
|
||||||
background: color-mix(in srgb, var(--bar-primary) 15%, transparent);
|
background: color-mix(in srgb, var(--bar-primary) 15%, transparent);
|
||||||
border-color: var(--bar-primary);
|
border-color: var(--bar-primary);
|
||||||
|
color: var(--bar-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-theme-btn:active {
|
||||||
|
transform: scale(0.98);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-theme-btn.active {
|
.mobile-theme-btn.active {
|
||||||
@@ -369,9 +400,16 @@
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
transition: all 0.15s ease;
|
transition: all 0.15s ease;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mobile-mode-btn:hover {
|
.mobile-mode-btn:hover {
|
||||||
background: color-mix(in srgb, var(--bar-primary) 15%, transparent);
|
background: color-mix(in srgb, var(--bar-primary) 15%, transparent);
|
||||||
border-color: var(--bar-primary);
|
border-color: var(--bar-primary);
|
||||||
|
color: var(--bar-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-mode-btn:active {
|
||||||
|
transform: scale(0.98);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,22 +6,40 @@
|
|||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
background: var(--terminal-bg-light);
|
background: var(--terminal-bg-light);
|
||||||
border-color: var(--terminal-border);
|
border-color: var(--terminal-border);
|
||||||
|
gap: 1rem;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tui-statusbar.top {
|
.tui-statusbar.top {
|
||||||
border-bottom: 1px solid var(--terminal-border);
|
border-bottom: 1px solid var(--terminal-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-left, .status-right {
|
.status-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
color: var(--terminal-muted);
|
color: var(--terminal-muted);
|
||||||
|
flex-shrink: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
color: var(--terminal-muted);
|
||||||
|
flex-shrink: 0;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-center {
|
.status-center {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
color: var(--terminal-primary);
|
color: var(--terminal-primary);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hint {
|
.hint {
|
||||||
@@ -31,8 +49,23 @@
|
|||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-host {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.hint {
|
.hint {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-host {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-center {
|
||||||
|
position: static;
|
||||||
|
transform: none;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -218,24 +218,43 @@
|
|||||||
<div class="dropdown-header">Mode</div>
|
<div class="dropdown-header">Mode</div>
|
||||||
<button class="theme-option" onclick={toggleMode}>
|
<button class="theme-option" onclick={toggleMode}>
|
||||||
<Icon icon={$mode === 'dark' ? 'mdi:weather-sunny' : 'mdi:weather-night'} width="16" />
|
<Icon icon={$mode === 'dark' ? 'mdi:weather-sunny' : 'mdi:weather-night'} width="16" />
|
||||||
<span>{$mode === 'dark' ? 'Light Mode' : 'Dark Mode'}</span>
|
<span>{$mode === 'dark' ? 'Light Mode' : 'Dark Mode'} (T)</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Backdrop -->
|
<!-- Backdrop for theme dropdown only -->
|
||||||
{#if themeDropdownOpen || mobileMenuOpen}
|
{#if themeDropdownOpen}
|
||||||
<button
|
<button
|
||||||
class="backdrop"
|
class="backdrop"
|
||||||
transition:fade={{ duration: 100 }}
|
transition:fade={{ duration: 100 }}
|
||||||
onclick={() => { themeDropdownOpen = false; mobileMenuOpen = false; }}
|
onclick={() => { themeDropdownOpen = false; }}
|
||||||
aria-label="Close"
|
aria-label="Close"
|
||||||
></button>
|
></button>
|
||||||
{/if}
|
{/if}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
<!-- Mobile menu backdrop (separate, behind the menu) -->
|
||||||
|
{#if mobileMenuOpen}
|
||||||
|
<button
|
||||||
|
class="mobile-backdrop"
|
||||||
|
transition:fade={{ duration: 100 }}
|
||||||
|
onclick={() => { mobileMenuOpen = false; }}
|
||||||
|
aria-label="Close menu"
|
||||||
|
style="
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
top: var(--navbar-height);
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 997;
|
||||||
|
border: none;
|
||||||
|
cursor: default;
|
||||||
|
"
|
||||||
|
></button>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<!-- Mobile menu dropdown -->
|
<!-- Mobile menu dropdown -->
|
||||||
{#if mobileMenuOpen}
|
{#if mobileMenuOpen}
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<div class="tui-statusbar top">
|
<div class="tui-statusbar top">
|
||||||
<span class="status-left">
|
<span class="status-left">
|
||||||
<Icon icon={getThemeIcon($colorTheme)} width="14" />
|
<Icon icon={getThemeIcon($colorTheme)} width="14" />
|
||||||
<span>{user.username}@{user.hostname}</span>
|
<span class="user-host">{user.username}@{user.hostname}</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="status-center">{title}</span>
|
<span class="status-center">{title}</span>
|
||||||
<span class="status-right">
|
<span class="status-right">
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ export const pageSpeedSettings: Record<string, SpeedPreset | number> = {
|
|||||||
'home': 'fast',
|
'home': 'fast',
|
||||||
'portfolio': 'fast',
|
'portfolio': 'fast',
|
||||||
'models': 'fast',
|
'models': 'fast',
|
||||||
'projects': 'fast'
|
'projects': 'fast',
|
||||||
|
'components': 'fast'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Per-page autoscroll settings (whether to auto-scroll as content types)
|
// Per-page autoscroll settings (whether to auto-scroll as content types)
|
||||||
|
|||||||
@@ -9,9 +9,10 @@ export const user = {
|
|||||||
hostname: 'engineering',
|
hostname: 'engineering',
|
||||||
title: 'Engineering Student',
|
title: 'Engineering Student',
|
||||||
email: 'sirblob0@gmail.com',
|
email: 'sirblob0@gmail.com',
|
||||||
location: 'Washington DC-Baltimore Area',
|
location: 'USA (EAST)',
|
||||||
bio: `Hi, I am Sir Blob — a engineer who loves making things. ` +
|
bio: `Hi, I am Sir Blob — a engineer who loves making things. ` +
|
||||||
`I build fun coding projects, participate in game jams and hackathons, and enjoy games like Minecraft and Pokémon TCG Live.`,
|
`I build fun coding projects, participate in game jams and hackathons, and enjoy games like Minecraft and Pokémon TCG Live. ` +
|
||||||
|
`I'm interested in Open Source, Game Development, Embedded Systems, and AI/ML.`,
|
||||||
|
|
||||||
// Prefer an absolute avatar URL if you want to pull directly from GitHub
|
// Prefer an absolute avatar URL if you want to pull directly from GitHub
|
||||||
avatar: '/blob_nerd.png',
|
avatar: '/blob_nerd.png',
|
||||||
@@ -32,10 +33,10 @@ export const user = {
|
|||||||
|
|
||||||
export const skills = {
|
export const skills = {
|
||||||
languages: ['Python', 'JavaScript', 'TypeScript', 'C', 'C++', 'Java', 'Node.js'],
|
languages: ['Python', 'JavaScript', 'TypeScript', 'C', 'C++', 'Java', 'Node.js'],
|
||||||
frameworks: ['Arduino', 'Bootstrap', 'TailwindCSS', 'Discord.js', 'React', 'Electron', 'Svelte'],
|
frameworks: ['React', 'Electron', 'Svelte', 'Bootstrap', 'TailwindCSS', 'Discord.js', ],
|
||||||
applications: ['Windows', 'Linux', 'macOS', 'IntelliJ', 'VS Code', 'Git', 'Blender', 'Godot'],
|
applications: ['IntelliJ', 'VS Code', 'Git', 'Blender', 'Godot'],
|
||||||
platforms: ['Windows', 'Linux', 'macOS', 'Arduino', 'Raspberry Pi'],
|
platforms: ['Windows', 'Linux', 'macOS', 'Arduino', 'Raspberry Pi'],
|
||||||
tools: ['Git', 'Docker', 'Neovim', 'VS Code'],
|
tools: ['Git', 'Docker', 'Neovim', 'VS Code'],
|
||||||
databases: ['MongoDB', 'Redis', 'SQLite'],
|
databases: ['MongoDB', 'SQLite'],
|
||||||
interests: ['Open Source', '3D Graphics', 'Game Development', 'Embedded Systems', 'AI/ML']
|
interests: ['Open Source', 'Game Development', 'Embedded Systems', 'AI/ML']
|
||||||
};
|
};
|
||||||
|
|||||||
519
src/lib/pages/components.ts
Normal file
519
src/lib/pages/components.ts
Normal file
@@ -0,0 +1,519 @@
|
|||||||
|
import type { TerminalLine } from '$lib/components/tui/types';
|
||||||
|
import { user } from '$lib/config';
|
||||||
|
|
||||||
|
const sampleTableHeaders = ['Name', 'Type', 'Status'];
|
||||||
|
const sampleTableRows = [
|
||||||
|
['Button', 'Interactive', 'Ready'],
|
||||||
|
['Progress', 'Display', 'Active'],
|
||||||
|
['Card', 'Container', 'Ready']
|
||||||
|
];
|
||||||
|
|
||||||
|
const sampleAccordionItems = [
|
||||||
|
{ title: 'What is this?', content: 'A showcase of all TUI components available in this terminal.' },
|
||||||
|
{ title: 'How to use?', content: 'Copy the code examples and customize for your needs.' },
|
||||||
|
{ title: 'Can I add more?', content: 'Yes! Check the types.ts file for the full API.' }
|
||||||
|
];
|
||||||
|
|
||||||
|
// Build comprehensive component showcase
|
||||||
|
export const lines: TerminalLine[] = [
|
||||||
|
// Header
|
||||||
|
{ type: 'command', content: 'cat ~/components/README.md' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'header', content: '(&primary,bold)Terminal UI Components(&)' },
|
||||||
|
{ type: 'output', content: '(&muted)A comprehensive showcase of all available TUI components(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// TEXT FORMATTING
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'TEXT FORMATTING' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Colors(&)' },
|
||||||
|
{ type: 'output', content: '(&red)red(&) (&green)green(&) (&yellow)yellow(&) (&blue)blue(&) (&magenta)magenta(&) (&cyan)cyan(&) (&orange)orange(&) (&pink)pink(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Semantic Colors(&)' },
|
||||||
|
{ type: 'output', content: '(&primary)primary(&) (&accent)accent(&) (&muted)muted(&) (&error)error(&) (&success)success(&) (&warning)warning(&) (&info)info(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Text Styles(&)' },
|
||||||
|
{ type: 'output', content: '(&bold)bold(&) (&dim)dim(&) (&italic)italic(&) (&underline)underline(&) (&strikethrough)strikethrough(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Combined Styles(&)' },
|
||||||
|
{ type: 'output', content: '(&bold,red)bold red(&) (&italic,cyan)italic cyan(&) (&bold,underline,yellow)bold underline yellow(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Inline Icons(&)' },
|
||||||
|
{ type: 'output', content: '(&icon, mdi:github) GitHub (&icon, mdi:twitter) Twitter (&icon, mdi:heart) Love (&icon, mdi:star) Star' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Background Colors(&)' },
|
||||||
|
{ type: 'output', content: '(&bg-surface)surface bg(&) (&bg-red)red bg(&) (&bg-blue)blue bg(&) (&bg-green)green bg(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// LINE TYPES
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'LINE TYPES' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'command', content: 'echo "This is a command line"' },
|
||||||
|
{ type: 'output', content: 'This is an output line' },
|
||||||
|
{ type: 'info', content: 'This is an info line' },
|
||||||
|
{ type: 'success', content: 'This is a success line' },
|
||||||
|
{ type: 'warning', content: 'This is a warning line' },
|
||||||
|
{ type: 'error', content: 'This is an error line' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// BUTTONS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'BUTTONS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Button Styles(&)' },
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'Primary Button',
|
||||||
|
icon: 'mdi:check',
|
||||||
|
style: 'primary',
|
||||||
|
action: () => console.log('Primary clicked')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'Secondary Button',
|
||||||
|
icon: 'mdi:information',
|
||||||
|
style: 'secondary',
|
||||||
|
action: () => console.log('Secondary clicked')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'Accent Button',
|
||||||
|
icon: 'mdi:star',
|
||||||
|
style: 'accent',
|
||||||
|
action: () => console.log('Accent clicked')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'Warning Button',
|
||||||
|
icon: 'mdi:alert',
|
||||||
|
style: 'warning',
|
||||||
|
action: () => console.log('Warning clicked')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'Error Button',
|
||||||
|
icon: 'mdi:close-circle',
|
||||||
|
style: 'error',
|
||||||
|
action: () => console.log('Error clicked')
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Link Buttons(&)' },
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'External Link (GitHub)',
|
||||||
|
icon: 'mdi:github',
|
||||||
|
style: 'primary',
|
||||||
|
href: 'https://github.com',
|
||||||
|
external: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
content: 'Internal Link (Home)',
|
||||||
|
icon: 'mdi:home',
|
||||||
|
style: 'accent',
|
||||||
|
href: '/'
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// LINKS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'LINKS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
content: 'Click here to visit GitHub',
|
||||||
|
href: 'https://github.com',
|
||||||
|
icon: 'mdi:github',
|
||||||
|
external: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
content: 'Go to portfolio page',
|
||||||
|
href: '/portfolio',
|
||||||
|
icon: 'mdi:folder'
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// PROGRESS BARS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'PROGRESS BARS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'progress',
|
||||||
|
content: 'Loading...',
|
||||||
|
progress: 25,
|
||||||
|
progressLabel: 'Installing packages'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'progress',
|
||||||
|
content: '',
|
||||||
|
progress: 50,
|
||||||
|
progressLabel: 'Building project'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'progress',
|
||||||
|
content: '',
|
||||||
|
progress: 75,
|
||||||
|
progressLabel: 'Running tests'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'progress',
|
||||||
|
content: '',
|
||||||
|
progress: 100,
|
||||||
|
progressLabel: 'Complete!'
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// IMAGES
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'IMAGES' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Image with Caption(&)' },
|
||||||
|
{
|
||||||
|
type: 'image',
|
||||||
|
content: 'User Avatar',
|
||||||
|
image: user.avatar,
|
||||||
|
imageAlt: 'Profile picture',
|
||||||
|
imageWidth: 100
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// CARDS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'CARDS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'card',
|
||||||
|
content: 'This is card content. Cards can contain formatted text and are great for highlighting information.',
|
||||||
|
cardTitle: 'Card Title',
|
||||||
|
cardFooter: 'Card Footer'
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// TABLES
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'TABLES' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'table',
|
||||||
|
content: '',
|
||||||
|
tableHeaders: sampleTableHeaders,
|
||||||
|
tableRows: sampleTableRows
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// ACCORDIONS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'ACCORDIONS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'accordion',
|
||||||
|
content: '',
|
||||||
|
accordionItems: sampleAccordionItems,
|
||||||
|
accordionOpen: false
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// TOOLTIPS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'TOOLTIPS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{
|
||||||
|
type: 'tooltip',
|
||||||
|
content: 'Hover over me for more info!',
|
||||||
|
tooltipText: 'This is tooltip content that appears on hover.',
|
||||||
|
tooltipPosition: 'top'
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// DIVIDERS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'DIVIDER STYLES' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'output', content: '(&muted)Dividers are simple horizontal separators with optional text:(&)' },
|
||||||
|
{ type: 'divider', content: 'SECTION A' },
|
||||||
|
{ type: 'output', content: '(&muted)Content for section A...(&)' },
|
||||||
|
{ type: 'divider', content: 'SECTION B' },
|
||||||
|
{ type: 'output', content: '(&muted)Content for section B...(&)' },
|
||||||
|
{ type: 'divider', content: '' },
|
||||||
|
{ type: 'output', content: '(&muted)Empty divider above (no text)(&)' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// FORM INPUTS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'FORM INPUTS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Text Input(&)' },
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
content: 'Username:',
|
||||||
|
icon: 'mdi:account',
|
||||||
|
inputPlaceholder: 'Enter your username',
|
||||||
|
style: 'primary'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
content: 'Email:',
|
||||||
|
icon: 'mdi:email',
|
||||||
|
inputPlaceholder: 'you@example.com',
|
||||||
|
inputType: 'email',
|
||||||
|
style: 'accent'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
content: 'With prefix/suffix:',
|
||||||
|
inputPlaceholder: '100',
|
||||||
|
inputPrefix: '$',
|
||||||
|
inputSuffix: '.00',
|
||||||
|
inputType: 'number'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
content: 'Error state:',
|
||||||
|
inputPlaceholder: 'Invalid input',
|
||||||
|
inputError: true,
|
||||||
|
inputErrorMessage: 'This field is required',
|
||||||
|
style: 'error'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'input',
|
||||||
|
content: 'Disabled:',
|
||||||
|
inputPlaceholder: 'Cannot edit',
|
||||||
|
inputDisabled: true
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// TEXTAREA
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'TEXTAREA' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Multi-line Text Area(&)' },
|
||||||
|
{
|
||||||
|
type: 'textarea',
|
||||||
|
content: 'Message:',
|
||||||
|
icon: 'mdi:message-text',
|
||||||
|
inputPlaceholder: 'Type your message here...',
|
||||||
|
textareaRows: 4,
|
||||||
|
style: 'primary'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'textarea',
|
||||||
|
content: 'With character limit:',
|
||||||
|
inputPlaceholder: 'Limited to 100 characters',
|
||||||
|
textareaRows: 3,
|
||||||
|
textareaMaxLength: 100,
|
||||||
|
style: 'accent'
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// CHECKBOX
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'CHECKBOXES' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Checkbox Options(&)' },
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
content: 'Enable notifications',
|
||||||
|
icon: 'mdi:bell',
|
||||||
|
style: 'primary'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
content: 'Accept terms and conditions',
|
||||||
|
style: 'accent'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
content: 'Indeterminate state',
|
||||||
|
checkboxIndeterminate: true,
|
||||||
|
style: 'warning'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
content: 'Disabled checkbox',
|
||||||
|
inputDisabled: true
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// RADIO BUTTONS
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'RADIO BUTTONS' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Radio Group (Vertical)(&)' },
|
||||||
|
{
|
||||||
|
type: 'radio',
|
||||||
|
content: 'Select theme:',
|
||||||
|
icon: 'mdi:palette',
|
||||||
|
style: 'primary',
|
||||||
|
radioOptions: [
|
||||||
|
{ value: 'dark', label: 'Dark Mode', icon: 'mdi:weather-night' },
|
||||||
|
{ value: 'light', label: 'Light Mode', icon: 'mdi:weather-sunny' },
|
||||||
|
{ value: 'system', label: 'System Default', icon: 'mdi:desktop-mac' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Radio Group (Horizontal)(&)' },
|
||||||
|
{
|
||||||
|
type: 'radio',
|
||||||
|
content: 'Size:',
|
||||||
|
style: 'accent',
|
||||||
|
radioHorizontal: true,
|
||||||
|
radioOptions: [
|
||||||
|
{ value: 'sm', label: 'Small' },
|
||||||
|
{ value: 'md', label: 'Medium' },
|
||||||
|
{ value: 'lg', label: 'Large' },
|
||||||
|
{ value: 'xl', label: 'Extra Large', disabled: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// SELECT DROPDOWN
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'SELECT DROPDOWN' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Basic Select(&)' },
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
content: 'Country:',
|
||||||
|
icon: 'mdi:earth',
|
||||||
|
inputPlaceholder: 'Select a country...',
|
||||||
|
style: 'primary',
|
||||||
|
selectOptions: [
|
||||||
|
{ value: 'us', label: 'United States', icon: 'emojione-v1:flag-for-united-states' },
|
||||||
|
{ value: 'uk', label: 'United Kingdom', icon: 'emojione-v1:flag-for-united-kingdom' },
|
||||||
|
{ value: 'de', label: 'Germany', icon: 'emojione-v1:flag-for-germany' },
|
||||||
|
{ value: 'fr', label: 'France', icon: 'emojione-v1:flag-for-france' },
|
||||||
|
{ value: 'jp', label: 'Japan', icon: 'emojione-v1:flag-for-japan' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Searchable Select(&)' },
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
content: 'Programming Language:',
|
||||||
|
icon: 'mdi:code-braces',
|
||||||
|
inputPlaceholder: 'Search languages...',
|
||||||
|
style: 'accent',
|
||||||
|
selectSearchable: true,
|
||||||
|
selectOptions: [
|
||||||
|
{ value: 'ts', label: 'TypeScript', icon: 'mdi:language-typescript' },
|
||||||
|
{ value: 'js', label: 'JavaScript', icon: 'mdi:language-javascript' },
|
||||||
|
{ value: 'py', label: 'Python', icon: 'mdi:language-python' },
|
||||||
|
{ value: 'rs', label: 'Rust', icon: 'mdi:language-rust' },
|
||||||
|
{ value: 'go', label: 'Go', icon: 'mdi:language-go' },
|
||||||
|
{ value: 'cpp', label: 'C++', icon: 'mdi:language-cpp' },
|
||||||
|
{ value: 'java', label: 'Java', icon: 'mdi:language-java' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// TOGGLE SWITCH
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'TOGGLE SWITCHES' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Toggle Options(&)' },
|
||||||
|
{
|
||||||
|
type: 'toggle',
|
||||||
|
content: 'Dark Mode',
|
||||||
|
icon: 'mdi:theme-light-dark',
|
||||||
|
style: 'primary'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'toggle',
|
||||||
|
content: 'Airplane Mode',
|
||||||
|
icon: 'mdi:airplane',
|
||||||
|
style: 'accent',
|
||||||
|
toggleOnLabel: 'ON',
|
||||||
|
toggleOffLabel: 'OFF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'toggle',
|
||||||
|
content: 'Custom Labels',
|
||||||
|
icon: 'mdi:toggle-switch',
|
||||||
|
style: 'warning',
|
||||||
|
toggleOnLabel: 'YES',
|
||||||
|
toggleOffLabel: 'NO'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'toggle',
|
||||||
|
content: 'No Labels',
|
||||||
|
toggleShowLabels: false,
|
||||||
|
style: 'accent'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'toggle',
|
||||||
|
content: 'Disabled Toggle',
|
||||||
|
inputDisabled: true
|
||||||
|
},
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// USAGE EXAMPLES
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
{ type: 'divider', content: 'USAGE' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'info', content: '(&blue,bold)Code Example(&)' },
|
||||||
|
{ type: 'output', content: "(&muted)// Text formatting(&)" },
|
||||||
|
{ type: 'output', content: "{ type: 'output', content: '(&green)colored text(&)' }" },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: "(&muted)// Button with action(&)" },
|
||||||
|
{ type: 'output', content: "{ type: 'button', content: 'Click', icon: 'mdi:check', style: 'primary', action: () => {} }" },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: "(&muted)// Form input(&)" },
|
||||||
|
{ type: 'output', content: "{ type: 'input', content: 'Label:', inputPlaceholder: 'Enter value...', style: 'primary' }" },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: "(&muted)// Checkbox(&)" },
|
||||||
|
{ type: 'output', content: "{ type: 'checkbox', content: 'Enable option', style: 'accent' }" },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: "(&muted)// Select dropdown(&)" },
|
||||||
|
{ type: 'output', content: "{ type: 'select', content: 'Choose:', selectOptions: [{ value: 'a', label: 'Option A' }] }" },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// End
|
||||||
|
{ type: 'success', content: '(&success)Component showcase complete!(&)' }
|
||||||
|
];
|
||||||
33
src/lib/pages/home.ts
Normal file
33
src/lib/pages/home.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import type { TerminalLine } from "$lib/components/tui/types";
|
||||||
|
import { user } from "$lib/config";
|
||||||
|
import { navigation } from "$lib/config";
|
||||||
|
|
||||||
|
export const lines: TerminalLine[] = [
|
||||||
|
// neofetch style intro
|
||||||
|
{ type: 'command', content: 'bash ~/startup.sh', delay: 300 },
|
||||||
|
|
||||||
|
// Color palette (moved below the art/stats block)
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: '(&red)███(&)(&orange)███(&)(&yellow)███(&)(&green)███(&)(&cyan)███(&)(&blue)███(&)(&magenta)███(&)(&pink)███(&)', inline: true },
|
||||||
|
{ type: 'output', content: '(&dim,red)███(&)(&dim,orange)███(&)(&dim,yellow)███(&)(&dim,green)███(&)(&dim,cyan)███(&)(&dim,blue)███(&)(&dim,magenta)███(&)(&dim,pink)███(&)', inline: true },
|
||||||
|
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'header', content: `Welcome to ${user.displayname}'s Portfolio` },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: `(&muted)${user.bio}(&)` },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'divider', content: 'NAVIGATION' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Interactive navigation buttons
|
||||||
|
...navigation.map(nav => ({
|
||||||
|
type: 'button' as const,
|
||||||
|
content: nav.name,
|
||||||
|
icon: nav.icon === '📁' ? 'mdi:folder' : nav.icon === '🎨' ? 'mdi:palette' : 'mdi:trophy',
|
||||||
|
style: 'primary' as const,
|
||||||
|
href: nav.path,
|
||||||
|
inline: true
|
||||||
|
})),
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
];
|
||||||
136
src/lib/pages/portfolio.ts
Normal file
136
src/lib/pages/portfolio.ts
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
|
||||||
|
import type { TerminalLine } from '$lib/components/tui/types';
|
||||||
|
import { user, skills, projects } from '$lib/config';
|
||||||
|
|
||||||
|
export const lines: TerminalLine[] = [
|
||||||
|
// Header command
|
||||||
|
{ type: 'command', content: 'cat ~/about.md' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Avatar image
|
||||||
|
{ type: 'image', content: '', image: user.avatar, imageAlt: user.name, imageWidth: 150 },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// User info
|
||||||
|
{ type: 'header', content: `(&primary,bold)${user.name}(&)` },
|
||||||
|
{ type: 'info', content: `(&accent)${user.title}(&)` },
|
||||||
|
{ type: 'output', content: `(&white)Location:(&) (&primary)${user.location}(&)` },
|
||||||
|
{ type: 'output', content: `(&muted)${user.bio}(&)` },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'output', content: `(&primary, bold)Links >(&)`, inline: true },
|
||||||
|
{ type: 'link', href: "/portfolio#contact", content: `(&bg-blue,black)Contact(&)`, inline: true },
|
||||||
|
{ type: 'link', href: "/portfolio#skills", content: `(&bg-orange,black)Skills(&)`, inline: true },
|
||||||
|
{ type: 'link', href: "/portfolio#projects", content: `(&bg-green,black)Projects(&)`, inline: true },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
{ type: 'divider', content: 'CONTACT', id: 'contact' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Contact buttons - dynamically generated from socials array
|
||||||
|
...user.socials.map(social => ({
|
||||||
|
type: 'button' as const,
|
||||||
|
content: `${social.name}`,
|
||||||
|
icon: social.icon,
|
||||||
|
style: 'primary' as const,
|
||||||
|
href: social.link,
|
||||||
|
inline: true
|
||||||
|
})),
|
||||||
|
// {
|
||||||
|
// type: 'button',
|
||||||
|
// content: `Email: ${user.email}`,
|
||||||
|
// icon: 'mdi:email',
|
||||||
|
// style: 'secondary',
|
||||||
|
// href: `mailto:${user.email}`
|
||||||
|
// },
|
||||||
|
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'divider', content: 'SKILLS', id: 'skills' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Skills as TUI sections
|
||||||
|
|
||||||
|
// Languages
|
||||||
|
{ type: 'info', content: '(&blue,bold)▸ Languages(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.languages.map(s => `(&cyan)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Frameworks
|
||||||
|
{ type: 'info', content: '(&magenta,bold)▸ Frameworks(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.frameworks.map(s => `(&pink)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Applications
|
||||||
|
{ type: 'info', content: '(&green,bold)▸ Tools(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.tools.map(s => `(&green)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Platforms
|
||||||
|
{ type: 'info', content: '(&yellow,bold)▸ Platforms(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.platforms.map(s => `(&yellow)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Applications
|
||||||
|
{ type: 'info', content: '(&purple,bold)▸ Applications(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.applications.map(s => `(&purple)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Databases
|
||||||
|
{ type: 'info', content: '(&cyan,bold)▸ Databases(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.databases.map(s => `(&cyan)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Interests
|
||||||
|
{ type: 'info', content: '(&accent,bold)▸ Interests(&)' },
|
||||||
|
{ type: 'output', content: ' ' + skills.interests.map(s => `(&muted)${s}(&)`).join(' (&muted)•(&) ') },
|
||||||
|
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'divider', content: 'PROJECTS', id: 'projects' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
|
||||||
|
// Featured projects with buttons
|
||||||
|
...projects.filter(p => p.featured).flatMap(project => [
|
||||||
|
{ type: 'header' as const, content: `(&primary,bold)${project.name}(&)` },
|
||||||
|
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
||||||
|
{ type: 'info' as const, content: `(&info)TechStack: (&primary)${project.tech.join(', ')}(&)` },
|
||||||
|
...(project.github ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View on GitHub',
|
||||||
|
icon: 'mdi:github',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.github
|
||||||
|
}] : []),
|
||||||
|
...(project.live ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View Live Demo',
|
||||||
|
icon: 'mdi:open-in-new',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.live
|
||||||
|
}] : []),
|
||||||
|
{ type: 'blank' as const, content: '' }
|
||||||
|
]),
|
||||||
|
|
||||||
|
// Other projects
|
||||||
|
...projects.filter(p => !p.featured).flatMap(project => [
|
||||||
|
{ type: 'success' as const, content: `(&success)${project.name}(&)` },
|
||||||
|
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
||||||
|
{ type: 'info' as const, content: `(&info)TechStack:(&) (&primary)${project.tech.join(', ')}(&)` },
|
||||||
|
...(project.github ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View on GitHub',
|
||||||
|
icon: 'mdi:github',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.github
|
||||||
|
}] : []),
|
||||||
|
...(project.live ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View Live',
|
||||||
|
icon: 'mdi:open-in-new',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.live
|
||||||
|
}] : []),
|
||||||
|
{ type: 'blank' as const, content: '' }
|
||||||
|
]),
|
||||||
|
|
||||||
|
// End
|
||||||
|
{ type: 'success', content: `(&success)Portfolio loaded successfully!(&)` }
|
||||||
|
];
|
||||||
64
src/lib/pages/projects.ts
Normal file
64
src/lib/pages/projects.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import type { TerminalLine } from '$lib/components/tui/types';
|
||||||
|
import { sortedCards, projects } from '$lib/config';
|
||||||
|
|
||||||
|
const totalHackathons = sortedCards.length;
|
||||||
|
const totalAwards = sortedCards.filter(c => c.awards && c.awards.length > 0).length;
|
||||||
|
const featuredCount = sortedCards.filter(c => c.featured).length;
|
||||||
|
|
||||||
|
// Build the terminal lines with card grid
|
||||||
|
export const lines: TerminalLine[] = [
|
||||||
|
{ type: 'divider', content: 'PROJECTS' },
|
||||||
|
{ type: 'command', content: 'ls ~/projects --grid' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
...projects.filter(p => p.featured).flatMap(project => [
|
||||||
|
{ type: 'header' as const, content: `(&primary,bold)${project.name}(&)` },
|
||||||
|
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
||||||
|
{ type: 'info' as const, content: `(&info)Tech: (&primary)${project.tech.join(', ')}(&)` },
|
||||||
|
...(project.github ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View on GitHub',
|
||||||
|
icon: 'mdi:github',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.github
|
||||||
|
}] : []),
|
||||||
|
...(project.live ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View Live Demo',
|
||||||
|
icon: 'mdi:open-in-new',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.live
|
||||||
|
}] : []),
|
||||||
|
{ type: 'blank' as const, content: '' }
|
||||||
|
]),
|
||||||
|
...projects.filter(p => !p.featured).flatMap(project => [
|
||||||
|
{ type: 'success' as const, content: `(&success)${project.name}(&)` },
|
||||||
|
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
||||||
|
{ type: 'info' as const, content: `(&info)Tech:(&) (&primary)${project.tech.join(', ')}(&)` },
|
||||||
|
...(project.github ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View on GitHub',
|
||||||
|
icon: 'mdi:github',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.github
|
||||||
|
}] : []),
|
||||||
|
...(project.live ? [{
|
||||||
|
type: 'button' as const,
|
||||||
|
content: 'View Live',
|
||||||
|
icon: 'mdi:open-in-new',
|
||||||
|
style: 'accent' as const,
|
||||||
|
href: project.live
|
||||||
|
}] : []),
|
||||||
|
{ type: 'blank' as const, content: '' }
|
||||||
|
]),
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'divider', content: 'HACKATHONS' },
|
||||||
|
{ type: 'command', content: 'ls ~/hackathons --grid' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'header', content: `Hackathon Journey` },
|
||||||
|
{ type: 'output', content: `(&muted)Total:(&) (&primary)${totalHackathons}(&) (&muted)| Awards:(&) (&yellow)${totalAwards}(&) (&muted)| Featured:(&) (&accent)${featuredCount}(&)` },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'cardgrid', content: '', cards: sortedCards },
|
||||||
|
{ type: 'blank', content: '' },
|
||||||
|
{ type: 'success', content: `(&success)Ready for the next hackathon! 🚀(&)` },
|
||||||
|
];
|
||||||
@@ -1,43 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
||||||
import type { TerminalLine } from '$lib/components/tui/types';
|
import { site } from '$lib/config';
|
||||||
import { user, skills, site, navigation } from '$lib/config';
|
|
||||||
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
||||||
import { colorTheme } from '$lib/stores/theme';
|
|
||||||
|
import { lines } from '$lib/pages/home';
|
||||||
|
|
||||||
const speed = getPageSpeedMultiplier('home');
|
const speed = getPageSpeedMultiplier('home');
|
||||||
const autoscroll = getPageAutoscroll('home');
|
const autoscroll = getPageAutoscroll('home');
|
||||||
|
|
||||||
// Build the terminal lines for the home page
|
|
||||||
const lines: TerminalLine[] = [
|
|
||||||
// neofetch style intro
|
|
||||||
{ type: 'command', content: 'bash ~/startup.sh', delay: 300 },
|
|
||||||
|
|
||||||
// Color palette (moved below the art/stats block)
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: '(&red)███(&)(&orange)███(&)(&yellow)███(&)(&green)███(&)(&cyan)███(&)(&blue)███(&)(&magenta)███(&)(&pink)███(&)', inline: true },
|
|
||||||
{ type: 'output', content: '(&dim,red)███(&)(&dim,orange)███(&)(&dim,yellow)███(&)(&dim,green)███(&)(&dim,cyan)███(&)(&dim,blue)███(&)(&dim,magenta)███(&)(&dim,pink)███(&)', inline: true },
|
|
||||||
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'header', content: `Welcome to ${user.displayname}'s Portfolio` },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: `(&muted)${user.bio}(&)` },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'divider', content: 'NAVIGATION' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// Interactive navigation buttons
|
|
||||||
...navigation.map(nav => ({
|
|
||||||
type: 'button' as const,
|
|
||||||
content: nav.name,
|
|
||||||
icon: nav.icon === '📁' ? 'mdi:folder' : nav.icon === '🎨' ? 'mdi:palette' : 'mdi:trophy',
|
|
||||||
style: 'primary' as const,
|
|
||||||
href: nav.path,
|
|
||||||
inline: true
|
|
||||||
})),
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|||||||
@@ -1,529 +1,12 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
||||||
import type { TerminalLine } from '$lib/components/tui/types';
|
|
||||||
import { user } from '$lib/config';
|
import { user } from '$lib/config';
|
||||||
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
||||||
|
import { lines } from '$lib/pages/components';
|
||||||
|
|
||||||
const speed = getPageSpeedMultiplier('components');
|
const speed = getPageSpeedMultiplier('components');
|
||||||
const autoscroll = getPageAutoscroll('components');
|
const autoscroll = getPageAutoscroll('components');
|
||||||
|
|
||||||
// Sample data for examples
|
|
||||||
const sampleTableHeaders = ['Name', 'Type', 'Status'];
|
|
||||||
const sampleTableRows = [
|
|
||||||
['Button', 'Interactive', 'Ready'],
|
|
||||||
['Progress', 'Display', 'Active'],
|
|
||||||
['Card', 'Container', 'Ready']
|
|
||||||
];
|
|
||||||
|
|
||||||
const sampleAccordionItems = [
|
|
||||||
{ title: 'What is this?', content: 'A showcase of all TUI components available in this terminal.' },
|
|
||||||
{ title: 'How to use?', content: 'Copy the code examples and customize for your needs.' },
|
|
||||||
{ title: 'Can I add more?', content: 'Yes! Check the types.ts file for the full API.' }
|
|
||||||
];
|
|
||||||
|
|
||||||
// Build comprehensive component showcase
|
|
||||||
const lines: TerminalLine[] = [
|
|
||||||
// Header
|
|
||||||
{ type: 'command', content: 'cat ~/components/README.md' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'header', content: '(&primary,bold)Terminal UI Components(&)' },
|
|
||||||
{ type: 'output', content: '(&muted)A comprehensive showcase of all available TUI components(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// TEXT FORMATTING
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'TEXT FORMATTING' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Colors(&)' },
|
|
||||||
{ type: 'output', content: '(&red)red(&) (&green)green(&) (&yellow)yellow(&) (&blue)blue(&) (&magenta)magenta(&) (&cyan)cyan(&) (&orange)orange(&) (&pink)pink(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Semantic Colors(&)' },
|
|
||||||
{ type: 'output', content: '(&primary)primary(&) (&accent)accent(&) (&muted)muted(&) (&error)error(&) (&success)success(&) (&warning)warning(&) (&info)info(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Text Styles(&)' },
|
|
||||||
{ type: 'output', content: '(&bold)bold(&) (&dim)dim(&) (&italic)italic(&) (&underline)underline(&) (&strikethrough)strikethrough(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Combined Styles(&)' },
|
|
||||||
{ type: 'output', content: '(&bold,red)bold red(&) (&italic,cyan)italic cyan(&) (&bold,underline,yellow)bold underline yellow(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Inline Icons(&)' },
|
|
||||||
{ type: 'output', content: '(&icon, mdi:github) GitHub (&icon, mdi:twitter) Twitter (&icon, mdi:heart) Love (&icon, mdi:star) Star' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Background Colors(&)' },
|
|
||||||
{ type: 'output', content: '(&bg-surface)surface bg(&) (&bg-red)red bg(&) (&bg-blue)blue bg(&) (&bg-green)green bg(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// LINE TYPES
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'LINE TYPES' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'command', content: 'echo "This is a command line"' },
|
|
||||||
{ type: 'output', content: 'This is an output line' },
|
|
||||||
{ type: 'info', content: 'This is an info line' },
|
|
||||||
{ type: 'success', content: 'This is a success line' },
|
|
||||||
{ type: 'warning', content: 'This is a warning line' },
|
|
||||||
{ type: 'error', content: 'This is an error line' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// BUTTONS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'BUTTONS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Button Styles(&)' },
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'Primary Button',
|
|
||||||
icon: 'mdi:check',
|
|
||||||
style: 'primary',
|
|
||||||
action: () => console.log('Primary clicked')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'Secondary Button',
|
|
||||||
icon: 'mdi:information',
|
|
||||||
style: 'secondary',
|
|
||||||
action: () => console.log('Secondary clicked')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'Accent Button',
|
|
||||||
icon: 'mdi:star',
|
|
||||||
style: 'accent',
|
|
||||||
action: () => console.log('Accent clicked')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'Warning Button',
|
|
||||||
icon: 'mdi:alert',
|
|
||||||
style: 'warning',
|
|
||||||
action: () => console.log('Warning clicked')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'Error Button',
|
|
||||||
icon: 'mdi:close-circle',
|
|
||||||
style: 'error',
|
|
||||||
action: () => console.log('Error clicked')
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Link Buttons(&)' },
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'External Link (GitHub)',
|
|
||||||
icon: 'mdi:github',
|
|
||||||
style: 'primary',
|
|
||||||
href: 'https://github.com',
|
|
||||||
external: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'button',
|
|
||||||
content: 'Internal Link (Home)',
|
|
||||||
icon: 'mdi:home',
|
|
||||||
style: 'accent',
|
|
||||||
href: '/'
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// LINKS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'LINKS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'link',
|
|
||||||
content: 'Click here to visit GitHub',
|
|
||||||
href: 'https://github.com',
|
|
||||||
icon: 'mdi:github',
|
|
||||||
external: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'link',
|
|
||||||
content: 'Go to portfolio page',
|
|
||||||
href: '/portfolio',
|
|
||||||
icon: 'mdi:folder'
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// PROGRESS BARS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'PROGRESS BARS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'progress',
|
|
||||||
content: 'Loading...',
|
|
||||||
progress: 25,
|
|
||||||
progressLabel: 'Installing packages'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'progress',
|
|
||||||
content: '',
|
|
||||||
progress: 50,
|
|
||||||
progressLabel: 'Building project'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'progress',
|
|
||||||
content: '',
|
|
||||||
progress: 75,
|
|
||||||
progressLabel: 'Running tests'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'progress',
|
|
||||||
content: '',
|
|
||||||
progress: 100,
|
|
||||||
progressLabel: 'Complete!'
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// IMAGES
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'IMAGES' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Image with Caption(&)' },
|
|
||||||
{
|
|
||||||
type: 'image',
|
|
||||||
content: 'User Avatar',
|
|
||||||
image: user.avatar,
|
|
||||||
imageAlt: 'Profile picture',
|
|
||||||
imageWidth: 100
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// CARDS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'CARDS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'card',
|
|
||||||
content: 'This is card content. Cards can contain formatted text and are great for highlighting information.',
|
|
||||||
cardTitle: 'Card Title',
|
|
||||||
cardFooter: 'Card Footer'
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// TABLES
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'TABLES' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'table',
|
|
||||||
content: '',
|
|
||||||
tableHeaders: sampleTableHeaders,
|
|
||||||
tableRows: sampleTableRows
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// ACCORDIONS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'ACCORDIONS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'accordion',
|
|
||||||
content: '',
|
|
||||||
accordionItems: sampleAccordionItems,
|
|
||||||
accordionOpen: false
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// TOOLTIPS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'TOOLTIPS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{
|
|
||||||
type: 'tooltip',
|
|
||||||
content: 'Hover over me for more info!',
|
|
||||||
tooltipText: 'This is tooltip content that appears on hover.',
|
|
||||||
tooltipPosition: 'top'
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// DIVIDERS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'DIVIDER STYLES' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'output', content: '(&muted)Dividers are simple horizontal separators with optional text:(&)' },
|
|
||||||
{ type: 'divider', content: 'SECTION A' },
|
|
||||||
{ type: 'output', content: '(&muted)Content for section A...(&)' },
|
|
||||||
{ type: 'divider', content: 'SECTION B' },
|
|
||||||
{ type: 'output', content: '(&muted)Content for section B...(&)' },
|
|
||||||
{ type: 'divider', content: '' },
|
|
||||||
{ type: 'output', content: '(&muted)Empty divider above (no text)(&)' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// FORM INPUTS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'FORM INPUTS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Text Input(&)' },
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
content: 'Username:',
|
|
||||||
icon: 'mdi:account',
|
|
||||||
inputPlaceholder: 'Enter your username',
|
|
||||||
style: 'primary'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
content: 'Email:',
|
|
||||||
icon: 'mdi:email',
|
|
||||||
inputPlaceholder: 'you@example.com',
|
|
||||||
inputType: 'email',
|
|
||||||
style: 'accent'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
content: 'With prefix/suffix:',
|
|
||||||
inputPlaceholder: '100',
|
|
||||||
inputPrefix: '$',
|
|
||||||
inputSuffix: '.00',
|
|
||||||
inputType: 'number'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
content: 'Error state:',
|
|
||||||
inputPlaceholder: 'Invalid input',
|
|
||||||
inputError: true,
|
|
||||||
inputErrorMessage: 'This field is required',
|
|
||||||
style: 'error'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
content: 'Disabled:',
|
|
||||||
inputPlaceholder: 'Cannot edit',
|
|
||||||
inputDisabled: true
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// TEXTAREA
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'TEXTAREA' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Multi-line Text Area(&)' },
|
|
||||||
{
|
|
||||||
type: 'textarea',
|
|
||||||
content: 'Message:',
|
|
||||||
icon: 'mdi:message-text',
|
|
||||||
inputPlaceholder: 'Type your message here...',
|
|
||||||
textareaRows: 4,
|
|
||||||
style: 'primary'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'textarea',
|
|
||||||
content: 'With character limit:',
|
|
||||||
inputPlaceholder: 'Limited to 100 characters',
|
|
||||||
textareaRows: 3,
|
|
||||||
textareaMaxLength: 100,
|
|
||||||
style: 'accent'
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// CHECKBOX
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'CHECKBOXES' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Checkbox Options(&)' },
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
content: 'Enable notifications',
|
|
||||||
icon: 'mdi:bell',
|
|
||||||
style: 'primary'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
content: 'Accept terms and conditions',
|
|
||||||
style: 'accent'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
content: 'Indeterminate state',
|
|
||||||
checkboxIndeterminate: true,
|
|
||||||
style: 'warning'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
content: 'Disabled checkbox',
|
|
||||||
inputDisabled: true
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// RADIO BUTTONS
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'RADIO BUTTONS' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Radio Group (Vertical)(&)' },
|
|
||||||
{
|
|
||||||
type: 'radio',
|
|
||||||
content: 'Select theme:',
|
|
||||||
icon: 'mdi:palette',
|
|
||||||
style: 'primary',
|
|
||||||
radioOptions: [
|
|
||||||
{ value: 'dark', label: 'Dark Mode', icon: 'mdi:weather-night' },
|
|
||||||
{ value: 'light', label: 'Light Mode', icon: 'mdi:weather-sunny' },
|
|
||||||
{ value: 'system', label: 'System Default', icon: 'mdi:desktop-mac' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Radio Group (Horizontal)(&)' },
|
|
||||||
{
|
|
||||||
type: 'radio',
|
|
||||||
content: 'Size:',
|
|
||||||
style: 'accent',
|
|
||||||
radioHorizontal: true,
|
|
||||||
radioOptions: [
|
|
||||||
{ value: 'sm', label: 'Small' },
|
|
||||||
{ value: 'md', label: 'Medium' },
|
|
||||||
{ value: 'lg', label: 'Large' },
|
|
||||||
{ value: 'xl', label: 'Extra Large', disabled: true }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// SELECT DROPDOWN
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'SELECT DROPDOWN' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Basic Select(&)' },
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
content: 'Country:',
|
|
||||||
icon: 'mdi:earth',
|
|
||||||
inputPlaceholder: 'Select a country...',
|
|
||||||
style: 'primary',
|
|
||||||
selectOptions: [
|
|
||||||
{ value: 'us', label: 'United States', icon: 'emojione-v1:flag-for-united-states' },
|
|
||||||
{ value: 'uk', label: 'United Kingdom', icon: 'emojione-v1:flag-for-united-kingdom' },
|
|
||||||
{ value: 'de', label: 'Germany', icon: 'emojione-v1:flag-for-germany' },
|
|
||||||
{ value: 'fr', label: 'France', icon: 'emojione-v1:flag-for-france' },
|
|
||||||
{ value: 'jp', label: 'Japan', icon: 'emojione-v1:flag-for-japan' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Searchable Select(&)' },
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
content: 'Programming Language:',
|
|
||||||
icon: 'mdi:code-braces',
|
|
||||||
inputPlaceholder: 'Search languages...',
|
|
||||||
style: 'accent',
|
|
||||||
selectSearchable: true,
|
|
||||||
selectOptions: [
|
|
||||||
{ value: 'ts', label: 'TypeScript', icon: 'mdi:language-typescript' },
|
|
||||||
{ value: 'js', label: 'JavaScript', icon: 'mdi:language-javascript' },
|
|
||||||
{ value: 'py', label: 'Python', icon: 'mdi:language-python' },
|
|
||||||
{ value: 'rs', label: 'Rust', icon: 'mdi:language-rust' },
|
|
||||||
{ value: 'go', label: 'Go', icon: 'mdi:language-go' },
|
|
||||||
{ value: 'cpp', label: 'C++', icon: 'mdi:language-cpp' },
|
|
||||||
{ value: 'java', label: 'Java', icon: 'mdi:language-java' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// TOGGLE SWITCH
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'TOGGLE SWITCHES' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Toggle Options(&)' },
|
|
||||||
{
|
|
||||||
type: 'toggle',
|
|
||||||
content: 'Dark Mode',
|
|
||||||
icon: 'mdi:theme-light-dark',
|
|
||||||
style: 'primary'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'toggle',
|
|
||||||
content: 'Airplane Mode',
|
|
||||||
icon: 'mdi:airplane',
|
|
||||||
style: 'accent',
|
|
||||||
toggleOnLabel: 'ON',
|
|
||||||
toggleOffLabel: 'OFF'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'toggle',
|
|
||||||
content: 'Custom Labels',
|
|
||||||
icon: 'mdi:toggle-switch',
|
|
||||||
style: 'warning',
|
|
||||||
toggleOnLabel: 'YES',
|
|
||||||
toggleOffLabel: 'NO'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'toggle',
|
|
||||||
content: 'No Labels',
|
|
||||||
toggleShowLabels: false,
|
|
||||||
style: 'accent'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'toggle',
|
|
||||||
content: 'Disabled Toggle',
|
|
||||||
inputDisabled: true
|
|
||||||
},
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
// USAGE EXAMPLES
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
|
||||||
{ type: 'divider', content: 'USAGE' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'info', content: '(&blue,bold)Code Example(&)' },
|
|
||||||
{ type: 'output', content: "(&muted)// Text formatting(&)" },
|
|
||||||
{ type: 'output', content: "{ type: 'output', content: '(&green)colored text(&)' }" },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: "(&muted)// Button with action(&)" },
|
|
||||||
{ type: 'output', content: "{ type: 'button', content: 'Click', icon: 'mdi:check', style: 'primary', action: () => {} }" },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: "(&muted)// Form input(&)" },
|
|
||||||
{ type: 'output', content: "{ type: 'input', content: 'Label:', inputPlaceholder: 'Enter value...', style: 'primary' }" },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: "(&muted)// Checkbox(&)" },
|
|
||||||
{ type: 'output', content: "{ type: 'checkbox', content: 'Enable option', style: 'accent' }" },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: "(&muted)// Select dropdown(&)" },
|
|
||||||
{ type: 'output', content: "{ type: 'select', content: 'Choose:', selectOptions: [{ value: 'a', label: 'Option A' }] }" },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// End
|
|
||||||
{ type: 'success', content: '(&success)Component showcase complete!(&)' }
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|||||||
@@ -1,125 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
||||||
import type { TerminalLine } from '$lib/components/tui/types';
|
import { site, user } from '$lib/config';
|
||||||
import { user, skills, projects, site } from '$lib/config';
|
|
||||||
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
||||||
|
import { lines } from '$lib/pages/portfolio';
|
||||||
|
|
||||||
const speed = getPageSpeedMultiplier('portfolio');
|
const speed = getPageSpeedMultiplier('portfolio');
|
||||||
const autoscroll = getPageAutoscroll('portfolio');
|
const autoscroll = getPageAutoscroll('portfolio');
|
||||||
|
|
||||||
// Build the terminal lines for the portfolio page
|
|
||||||
const lines: TerminalLine[] = [
|
|
||||||
// Header command
|
|
||||||
{ type: 'command', content: 'cat ~/about.md' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// Avatar image
|
|
||||||
{ type: 'image', content: '', image: user.avatar, imageAlt: user.name, imageWidth: 150 },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// User info
|
|
||||||
{ type: 'header', content: `(&primary,bold)${user.name}(&)` },
|
|
||||||
{ type: 'info', content: `(&accent)${user.title}(&)` },
|
|
||||||
{ type: 'output', content: `(&muted)${user.bio}(&)` },
|
|
||||||
{ type: 'output', content: `(&muted)Location:(&) (&primary)${user.location}(&)` },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'output', content: `(&primary, bold)Links >(&)`, inline: true },
|
|
||||||
{ type: 'link', href: "/portfolio#contact", content: `(&bg-blue,black)Contact(&)`, inline: true },
|
|
||||||
{ type: 'link', href: "/portfolio#skills", content: `(&bg-orange,black)Skills(&)`, inline: true },
|
|
||||||
{ type: 'link', href: "/portfolio#projects", content: `(&bg-green,black)Projects(&)`, inline: true },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
{ type: 'divider', content: 'CONTACT', id: 'contact' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// Contact buttons - dynamically generated from socials array
|
|
||||||
...user.socials.map(social => ({
|
|
||||||
type: 'button' as const,
|
|
||||||
content: `${social.name}`,
|
|
||||||
icon: social.icon,
|
|
||||||
style: 'primary' as const,
|
|
||||||
href: social.link,
|
|
||||||
inline: true
|
|
||||||
})),
|
|
||||||
// {
|
|
||||||
// type: 'button',
|
|
||||||
// content: `Email: ${user.email}`,
|
|
||||||
// icon: 'mdi:email',
|
|
||||||
// style: 'secondary',
|
|
||||||
// href: `mailto:${user.email}`
|
|
||||||
// },
|
|
||||||
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'divider', content: 'SKILLS', id: 'skills' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// Skills as TUI sections
|
|
||||||
{ type: 'info', content: '(&blue,bold)▸ Languages(&)' },
|
|
||||||
{ type: 'output', content: ' ' + skills.languages.map(s => `(&cyan)${s}(&)`).join(' (&muted)•(&) ') },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'info', content: '(&magenta,bold)▸ Frameworks(&)' },
|
|
||||||
{ type: 'output', content: ' ' + skills.frameworks.map(s => `(&pink)${s}(&)`).join(' (&muted)•(&) ') },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'info', content: '(&green,bold)▸ Tools(&)' },
|
|
||||||
{ type: 'output', content: ' ' + skills.tools.map(s => `(&green)${s}(&)`).join(' (&muted)•(&) ') },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'info', content: '(&cyan,bold)▸ Databases(&)' },
|
|
||||||
{ type: 'output', content: ' ' + skills.databases.map(s => `(&cyan)${s}(&)`).join(' (&muted)•(&) ') },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'info', content: '(&accent,bold)▸ Interests(&)' },
|
|
||||||
{ type: 'output', content: ' ' + skills.interests.map(s => `(&muted)${s}(&)`).join(' (&muted)•(&) ') },
|
|
||||||
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'divider', content: 'PROJECTS', id: 'projects' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
|
|
||||||
// Featured projects with buttons
|
|
||||||
...projects.filter(p => p.featured).flatMap(project => [
|
|
||||||
{ type: 'header' as const, content: `(&primary,bold)${project.name}(&)` },
|
|
||||||
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
|
||||||
{ type: 'info' as const, content: `(&info)TechStack: (&primary)${project.tech.join(', ')}(&)` },
|
|
||||||
...(project.github ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View on GitHub',
|
|
||||||
icon: 'mdi:github',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.github
|
|
||||||
}] : []),
|
|
||||||
...(project.live ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View Live Demo',
|
|
||||||
icon: 'mdi:open-in-new',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.live
|
|
||||||
}] : []),
|
|
||||||
{ type: 'blank' as const, content: '' }
|
|
||||||
]),
|
|
||||||
|
|
||||||
// Other projects
|
|
||||||
...projects.filter(p => !p.featured).flatMap(project => [
|
|
||||||
{ type: 'success' as const, content: `(&success)${project.name}(&)` },
|
|
||||||
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
|
||||||
{ type: 'info' as const, content: `(&info)TechStack:(&) (&primary)${project.tech.join(', ')}(&)` },
|
|
||||||
...(project.github ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View on GitHub',
|
|
||||||
icon: 'mdi:github',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.github
|
|
||||||
}] : []),
|
|
||||||
...(project.live ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View Live',
|
|
||||||
icon: 'mdi:open-in-new',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.live
|
|
||||||
}] : []),
|
|
||||||
{ type: 'blank' as const, content: '' }
|
|
||||||
]),
|
|
||||||
|
|
||||||
// End
|
|
||||||
{ type: 'success', content: `(&success)Portfolio loaded successfully!(&)` }
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|||||||
@@ -1,74 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
import TerminalTUI from '$lib/components/TerminalTUI.svelte';
|
||||||
import type { TerminalLine } from '$lib/components/tui/types';
|
import { user } from '$lib/config';
|
||||||
import { user, sortedCards, projects } from '$lib/config';
|
|
||||||
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
import { getPageSpeedMultiplier, getPageAutoscroll } from '$lib';
|
||||||
|
import { lines } from '$lib/pages/projects';
|
||||||
|
|
||||||
const speed = getPageSpeedMultiplier('projects');
|
const speed = getPageSpeedMultiplier('projects');
|
||||||
const autoscroll = getPageAutoscroll('projects');
|
const autoscroll = getPageAutoscroll('projects');
|
||||||
|
|
||||||
// Count stats
|
|
||||||
const totalHackathons = sortedCards.length;
|
|
||||||
const totalAwards = sortedCards.filter(c => c.awards && c.awards.length > 0).length;
|
|
||||||
const featuredCount = sortedCards.filter(c => c.featured).length;
|
|
||||||
|
|
||||||
// Build the terminal lines with card grid
|
|
||||||
const lines: TerminalLine[] = [
|
|
||||||
{ type: 'divider', content: 'PROJECTS' },
|
|
||||||
{ type: 'command', content: 'ls ~/projects --grid' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
...projects.filter(p => p.featured).flatMap(project => [
|
|
||||||
{ type: 'header' as const, content: `(&primary,bold)${project.name}(&)` },
|
|
||||||
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
|
||||||
{ type: 'info' as const, content: `(&info)Tech: (&primary)${project.tech.join(', ')}(&)` },
|
|
||||||
...(project.github ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View on GitHub',
|
|
||||||
icon: 'mdi:github',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.github
|
|
||||||
}] : []),
|
|
||||||
...(project.live ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View Live Demo',
|
|
||||||
icon: 'mdi:open-in-new',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.live
|
|
||||||
}] : []),
|
|
||||||
{ type: 'blank' as const, content: '' }
|
|
||||||
]),
|
|
||||||
...projects.filter(p => !p.featured).flatMap(project => [
|
|
||||||
{ type: 'success' as const, content: `(&success)${project.name}(&)` },
|
|
||||||
{ type: 'output' as const, content: `(&muted)${project.description}(&)` },
|
|
||||||
{ type: 'info' as const, content: `(&info)Tech:(&) (&primary)${project.tech.join(', ')}(&)` },
|
|
||||||
...(project.github ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View on GitHub',
|
|
||||||
icon: 'mdi:github',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.github
|
|
||||||
}] : []),
|
|
||||||
...(project.live ? [{
|
|
||||||
type: 'button' as const,
|
|
||||||
content: 'View Live',
|
|
||||||
icon: 'mdi:open-in-new',
|
|
||||||
style: 'accent' as const,
|
|
||||||
href: project.live
|
|
||||||
}] : []),
|
|
||||||
{ type: 'blank' as const, content: '' }
|
|
||||||
]),
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'divider', content: 'HACKATHONS' },
|
|
||||||
{ type: 'command', content: 'ls ~/hackathons --grid' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'header', content: `Hackathon Journey` },
|
|
||||||
{ type: 'output', content: `(&muted)Total:(&) (&primary)${totalHackathons}(&) (&muted)| Awards:(&) (&yellow)${totalAwards}(&) (&muted)| Featured:(&) (&accent)${featuredCount}(&)` },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'cardgrid', content: '', cards: sortedCards },
|
|
||||||
{ type: 'blank', content: '' },
|
|
||||||
{ type: 'success', content: `(&success)Ready for the next hackathon! 🚀(&)` },
|
|
||||||
];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|||||||
Reference in New Issue
Block a user