98 lines
2.5 KiB
Svelte
98 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from "svelte"
|
|
|
|
let history: string[] = []
|
|
let currentDir = "~"
|
|
|
|
type Command = "help" | "about" | "skills" | "projects" | "contact" | "clear"
|
|
|
|
const commands: Record<Command, () => string> = {
|
|
help: () => `Available commands:
|
|
about - Display information about me
|
|
skills - List my technical skills
|
|
projects - Show my notable projects
|
|
contact - Display my contact information
|
|
clear - Clear the terminal screen`,
|
|
about: () => `Hi, I'm John Doe!
|
|
I'm a passionate software developer with 5 years of experience.
|
|
I love creating elegant solutions to complex problems.`,
|
|
skills: () => `My technical skills include:
|
|
- JavaScript/TypeScript
|
|
- React & Next.js
|
|
- Node.js
|
|
- Python
|
|
- SQL & NoSQL databases`,
|
|
projects: () => `Some of my notable projects:
|
|
1. E-commerce Platform (React, Node.js, MongoDB)
|
|
2. Weather App (React Native, OpenWeatherMap API)
|
|
3. Task Management System (Python, Django, PostgreSQL)`,
|
|
contact: () => `You can reach me at:
|
|
Email: john.doe@example.com
|
|
GitHub: github.com/johndoe
|
|
LinkedIn: linkedin.com/in/johndoe`,
|
|
clear: () => {
|
|
history = []
|
|
return ""
|
|
},
|
|
}
|
|
|
|
const executeCommand = (input: string) => {
|
|
const [command, ...args] = input.trim().split(" ")
|
|
if (command in commands) {
|
|
return commands[command as Command]()
|
|
}
|
|
return `Command not found: ${command}. Type 'help' for available commands.`
|
|
}
|
|
|
|
let input = ""
|
|
let inputRef: HTMLInputElement | null = null
|
|
|
|
const handleSubmit = (e: Event) => {
|
|
e.preventDefault()
|
|
if (input.trim()) {
|
|
if (input === "clear") {
|
|
history = []
|
|
} else {
|
|
history = [
|
|
...history,
|
|
`${currentDir} $ ${input}`,
|
|
executeCommand(input),
|
|
]
|
|
}
|
|
input = ""
|
|
}
|
|
}
|
|
|
|
onMount(() => {
|
|
history = [
|
|
"Welcome to John Doe's Terminal Portfolio!",
|
|
"Type 'help' to see available commands.",
|
|
]
|
|
})
|
|
|
|
$: {
|
|
if (inputRef) {
|
|
inputRef.scrollIntoView({ behavior: "smooth" })
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="min-h-screen bg-black text-green-500 p-4 font-mono">
|
|
<div class="max-w-3xl mx-auto">
|
|
<div class="mb-4">
|
|
{#each history as line}
|
|
<pre class="whitespace-pre-wrap">{line}</pre>
|
|
{/each}
|
|
</div>
|
|
<form on:submit={handleSubmit} class="flex">
|
|
<span class="mr-2">{currentDir} $</span>
|
|
<input
|
|
bind:this={inputRef}
|
|
bind:value={input}
|
|
type="text"
|
|
class="flex-grow bg-transparent outline-none"
|
|
/>
|
|
</form>
|
|
</div>
|
|
</div>
|