martials.no/src/components/Terminal.svelte

98 lines
2.5 KiB
Svelte
Raw Normal View History

2024-09-25 22:20:47 +02:00
<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>