### Next.js Application Build and Run Commands (Bash) Source: https://context7.com/danusprout/portofolio-danu/llms.txt Provides essential bash commands for managing a Next.js application, including installing dependencies using Bun or npm, starting the development server, building the application for production, and starting the production server. These commands are crucial for the development lifecycle and deployment of the portfolio. ```bash # Install dependencies (using Bun or npm) bun install # or npm install # Start development server bun dev # or npm run dev # Build for production bun run build # or npm run build # Start production server bun start # or npm start # Access the portfolio ``` -------------------------------- ### Create ChatBot Component with Predefined Questions (React/TypeScript) Source: https://context7.com/danusprout/portofolio-danu/llms.txt Implements an interactive ChatBot component using React and TypeScript. It displays messages, handles user question clicks, and simulates bot responses based on predefined Q&A data. Future integration with AI APIs is considered. Dependencies include React state management and potentially UI libraries for dialogs and buttons. ```tsx // app/components/ChatBot.tsx import { predefinedQuestions } from "@/app/data/chatbots"; import { useState } from "react"; import { Button } from "@/components/ui/button"; // Assuming Button is from a UI library import { MessageCircle } from "lucide-react"; // Assuming MessageCircle is an icon component export default function ChatBot() { const [isOpen, setIsOpen] = useState(false); const [messages, setMessages] = useState([ { text: "Hello! How can I assist you today?", isUser: false }, ]); const handleQuestionClick = async (question: string) => { setMessages((prev) => [...prev, { text: question, isUser: true }]); const botResponse = await simulateBotResponse(question); setMessages((prev) => [...prev, { text: botResponse, isUser: false }]); }; const simulateBotResponse = async (question: string): Promise => { await new Promise((resolve) => setTimeout(resolve, 1000)); const matchedQuestion = predefinedQuestions.find( (item) => item.question === question ); return matchedQuestion?.answer || "I don't have information about that."; }; return ( // Dialog content with messages and question carousel would go here ); } // app/data/chatbots.ts - Predefined Q&A interface Question { question: string; answer: string; } export const predefinedQuestions: Question[] = [ { question: "Who is Danu?", answer: "Syahrial Danu is a Fullstack Developer from Indonesia...", }, { question: "What's your tech stack?", answer: "Danu works with Flutter, Next.js, NestJS, Express.js...", }, { question: "Are you open for freelance?", answer: "Yes! Danu is open for freelance projects...", }, ]; ``` -------------------------------- ### FloatingButton Component with Music Player (React/TypeScript) Source: https://context7.com/danusprout/portofolio-danu/llms.txt Manages background music playback with fade-in/fade-out effects using the use-sound hook. It provides a mute/unmute toggle button and integrates with toast notifications. Dependencies include 'use-sound' and potentially UI libraries for Button, VolumeX, and Volume2 icons. ```tsx // app/components/FloatingButton.tsx import useSound from "use-sound"; interface FloatingButtonProps { terminalWidth: number; initialMessageComplete?: boolean; } export default function FloatingButton({ terminalWidth, initialMessageComplete = false, }: FloatingButtonProps) { const [isMuted, setIsMuted] = useState(true); const [volume, setVolume] = useState(0.4); const fadeInterval = useRef(); const [play, { pause, sound }] = useSound("/music/background-music.mp3", { volume, loop: true, interrupt: false, onload: () => setIsLoading(false), }); const fadeIn = () => { if (fadeInterval.current) clearInterval(fadeInterval.current); let vol = 0; setVolume(vol); fadeInterval.current = setInterval(() => { if (vol < 0.4) { vol += 0.05; setVolume(vol); } else { clearInterval(fadeInterval.current); } }, 100); }; const fadeOut = () => { if (fadeInterval.current) clearInterval(fadeInterval.current); let vol = 0.4; fadeInterval.current = setInterval(() => { if (vol > 0) { vol -= 0.05; setVolume(vol); } else { clearInterval(fadeInterval.current); pause(); } }, 100); }; const toggleMute = () => { if (isMuted) { setIsMuted(false); fadeIn(); play(); toast("Music played"); } else { setIsMuted(true); fadeOut(); toast("Music muted"); } }; return (
); } ``` -------------------------------- ### Define Portfolio Data Structures (TypeScript) Source: https://context7.com/danusprout/portofolio-danu/llms.txt Defines TypeScript types and sample data for 'experiences', 'projects', and 'about' sections. These structures are used to organize and display portfolio content. Includes specific types for work/education experiences, paid/personal projects, and general about information. ```typescript // app/data/experiences.ts export type Experience = { id: number; title: string; company: string; date: string; description: string; skills?: { id: number; title: string }[]; type: "work" | "education"; }; export const experiences: Experience[] = [ { id: 4, title: "Software Engineer", company: "Sprout Digital Labs", date: "Feb 2025 - Present", description: "Currently working as a Software Engineer...", skills: [ { id: 1, title: "Flutter" }, { id: 2, title: "NestJS" }, { id: 3, title: "Next.js" }, ], type: "work", }, ]; // app/data/projects.ts export type Projects = { id: number; title: string; company: string; date: string; description: string; skills?: { id: number; title: string }[]; type: "paid" | "personal"; link: string; imageUrl: string; }; export const projects: Projects[] = [ { id: 1, title: "SentralPart.com", company: "PT Global Innovation Technology", date: "2025-10-10", description: "Led the development of an automotive parts e-commerce platform...", skills: [ { id: 1, title: "Next.js" }, { id: 2, title: "Express.js" }, ], type: "paid", link: "https://sentralpart.com", imageUrl: "/photos/LogoSentralPart-Horizontal.svg", }, ]; // app/data/about.ts export type About = { id: number; heading: string; description: string; }; export const aboutData: About[] = [ { id: 1, heading: "Howdy! Syahrial Danu here.", description: "A forward-thinking IT professional with a degree in Information Technology...", }, ]; ``` -------------------------------- ### Utility Functions for Class Names and Date Formatting (TypeScript) Source: https://context7.com/danusprout/portofolio-danu/llms.txt Provides helper functions 'cn' for merging CSS class names using clsx and twMerge, and 'formatDate' for user-friendly date display. These utilities are essential for dynamic styling and presenting dates in a readable format. The 'cn' function takes multiple class values and returns a single string, while 'formatDate' formats a Date object into 'Month Day, Year'. ```typescript // lib/utils.ts import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } export function formatDate(date: Date): string { return new Intl.DateTimeFormat("en-US", { month: "long", day: "numeric", year: "numeric", }).format(date); } // Usage example import { cn } from "@/lib/utils"; ``` -------------------------------- ### TypeScript Command Handler for Terminal Source: https://context7.com/danusprout/portofolio-danu/llms.txt Processes user commands entered in the terminal, returning formatted string output. It supports asynchronous operations for fetching data like experiences and projects, and includes basic command validation. ```typescript // app/data/commands.ts import { experiences, Experience } from "./experiences"; import { projects, Projects } from "./projects"; // Placeholder functions for fetching data const fetchExperiences = async (): Promise => { // In a real app, this would fetch data from an API or file return [ { title: "Software Engineer", company: "Sprout Digital Labs", date: "Feb 2025 - Present", description: "Currently working as a Software Engineer...", skills: ["Flutter", "NestJS", "Next.js"], type: "work" } ]; }; const fetchProjects = async (): Promise => { // In a real app, this would fetch data from an API or file return [ { name: "Portfolio Website", description: "Interactive portfolio using Next.js.", link: "#", technologies: ["Next.js", "TypeScript", "Tailwind CSS"] } ]; }; // Placeholder formatting functions const formatExperiences = (expData: Experience[]): string => { return expData.map(e => `[ • ] ${e.title} at ${e.company}\n Date: ${e.date}\n Description: ${e.description}\n Skills: ${e.skills.join(', ')}\n Type: ${e.type}`).join('\n\n'); }; const formatProjects = (projData: Projects[]): string => { return projData.map(p => `[ • ] ${p.name}\n Description: ${p.description}\n Link: ${p.link}\n Technologies: ${p.technologies.join(', ')}`).join('\n\n'); }; export const help = [ "whois", "experiences", "projects", "social", "banner", "clear", "help", "su", ]; export const handleCommand = async (command: string): Promise => { const args = command.trim().split(" "); let output = ""; switch (args[0]) { case "whois": output = "Hey there! I'm a tech enthusiast with an Information Technology degree..."; break; case "experiences": output = "Fetching experiences...\n"; const experiencesData = await fetchExperiences(); output += formatExperiences(experiencesData); break; case "projects": output = "Fetching projects...\n"; const projectsData = await fetchProjects(); output += formatProjects(projectsData); break; case "social": output = "LinkedIn: https://linkedin.com/in/dhanuwardhana\nGitHub: https://github.com/Dhanuwrdhn"; break; case "help": output = `Available commands: ${help.join(", ")}`; break; case "banner": output = "Re-displaying ASCII art banner..."; // Placeholder for banner logic break; case "clear": output = "Clearing terminal..."; // Placeholder for clear logic break; case "su": output = "Access denied. You are not root."; // Easter egg break; default: output = "Command not found. Type 'help' to see available commands."; } return output; }; // Example output from 'experiences' command: // [ • ] Software Engineer at Sprout Digital Labs // Date: Feb 2025 - Present // Description: Currently working as a Software Engineer... // Skills: Flutter, NestJS, Next.js // Type: work ``` -------------------------------- ### Reusable Button Component with Variants (React/TypeScript) Source: https://context7.com/danusprout/portofolio-danu/llms.txt A flexible and reusable button component using Radix UI and class-variance-authority for defining visual styles. It supports multiple variants (default, destructive, outline, secondary, ghost, link) and sizes (default, sm, lg, icon), allowing for consistent UI elements across the application. The 'asChild' prop enables composition with other elements like links. ```tsx // components/ui/button.tsx import { cva, type VariantProps } from "class-variance-authority"; import { Slot } from "@radix-ui/react-slot"; const buttonVariants = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors", { variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground", outline: "border border-input bg-background hover:bg-accent", secondary: "bg-secondary text-secondary-foreground", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline", }, size: { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10", }, }, defaultVariants: { variant: "default", size: "default", }, } ); export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { asChild?: boolean; } const Button = React.forwardRef( ({ className, variant, size, asChild = false, ...props }, ref) => { const Comp = asChild ? Slot : "button"; return ( ); } ); // Usage examples ``` -------------------------------- ### Next.js Terminal Component Integration Source: https://context7.com/danusprout/portofolio-danu/llms.txt Integrates the Terminal component into a Next.js page, managing content visibility based on banner completion. It allows users to interact with the portfolio via a command-line interface. ```tsx import Terminal from "@/app/components/Terminal/Terminal"; import About from "@/app/components/About"; import Experiences from "@/app/components/Experiences"; import Projects from "@/app/components/Projects"; import { useState } from "react"; // Usage in page component export default function Home() { const [showContent, setShowContent] = useState(false); const handleBannerComplete = () => { setShowContent(true); }; return (
{showContent && (
)}
); } // Terminal commands available: // - whois: Display personal bio // - experiences: Fetch and display work history // - projects: Fetch and display project portfolio // - social: Show social media links // - banner: Re-display ASCII art banner // - clear: Clear terminal output // - help: List available commands // - su: Easter egg command ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.