feat: portfolio redesign with i18n, RBC project showcase, CI/CD
- Add i18n support (EN/ZH) with language toggle - Redesign header with education dropdown, contact copy buttons - Add RBC project showcase with bullet points, skills highlighting - Create terraform-drift placeholder page - Add ProjectShowcase component with media toggle (image/video) - Update experience timeline with action-driven descriptions - Add Docker + Forgejo CI workflow for image builds - Update K8s manifests for riotpiao.com ingress - Add DESIGN.md documenting design system patterns
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import { motion } from 'framer-motion'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useTerminal } from '@/lib/TerminalContext'
|
||||
|
||||
const commands: Record<string, string> = {
|
||||
help: `Available commands:
|
||||
@@ -46,10 +47,15 @@ Open Source: go-flink (distributed DataLakeHouse)`,
|
||||
export function InteractiveTerminal() {
|
||||
const [input, setInput] = useState('')
|
||||
const [history, setHistory] = useState<{ cmd: string; output: string }[]>([])
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const { isOpen, setIsOpen } = useTerminal()
|
||||
const [isMac, setIsMac] = useState(true)
|
||||
const terminalRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
// Detect if user is on Mac
|
||||
const isMacOS = /Mac|iPhone|iPad|iPod/.test(navigator.platform)
|
||||
setIsMac(isMacOS)
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
||||
e.preventDefault()
|
||||
@@ -59,7 +65,7 @@ export function InteractiveTerminal() {
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
return () => window.removeEventListener('keydown', handleKeyDown)
|
||||
}, [isOpen])
|
||||
}, [isOpen, setIsOpen])
|
||||
|
||||
const handleCommand = (cmd: string) => {
|
||||
const trimmed = cmd.trim().toLowerCase()
|
||||
@@ -89,7 +95,7 @@ export function InteractiveTerminal() {
|
||||
onClick={() => setIsOpen(true)}
|
||||
className="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg font-mono text-sm shadow-lg"
|
||||
>
|
||||
Terminal (Cmd+K)
|
||||
Ask Poimen ({isMac ? 'Cmd' : 'Ctrl'}+K)
|
||||
</button>
|
||||
) : (
|
||||
<motion.div
|
||||
@@ -98,7 +104,7 @@ export function InteractiveTerminal() {
|
||||
className="bg-gray-950 border border-gray-700 rounded-lg shadow-2xl w-96 h-96 flex flex-col"
|
||||
>
|
||||
<div className="bg-gray-900 border-b border-gray-700 px-4 py-3 flex justify-between items-center">
|
||||
<span className="text-gray-300 font-mono text-xs">ZSH_THEME="robbyrussell"</span>
|
||||
<span className="text-gray-300 font-mono text-xs">Poimen (Agent Terminal)</span>
|
||||
<button
|
||||
onClick={() => setIsOpen(false)}
|
||||
className="text-gray-400 hover:text-white"
|
||||
|
||||
Reference in New Issue
Block a user