Skip to content
This repository has been archived by the owner on May 12, 2024. It is now read-only.

Commit

Permalink
terminal page
Browse files Browse the repository at this point in the history
  • Loading branch information
pranav-deshmukh committed Feb 26, 2024
1 parent c0f7007 commit e4fec92
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 41 deletions.
137 changes: 98 additions & 39 deletions devsoc24-landing/src/components/terminal/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useState, useEffect, useRef } from "react";
interface Command {
command: string;
output: string[];
displayOutput: string[];
}
const Terminal = () => {
const [inputValue, setInputValue] = useState("");
Expand All @@ -21,30 +22,37 @@ const Terminal = () => {

const commandOutputs: CommandOutputs = {
whatisdevsoc: [
"Hey, hjdsbc ADFH Ga dsfhLA a",
"hasbfdsf DIF KJa dfiu AIF ahidf UADHFIpdfhIAFafnFa",
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
],
whoisdevsoc: [
"The paradox of “Who am I?” is: we never know, but, we constantly find out.",
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
],
whyisdevsoc: [
"Because exploring the unknown and innovating is at the heart of human nature.",
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
],
secret: [
'<span class="command">sudo</span> Only use if you\'re admin',
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
],
aditansh: [
"Still curating... most projects are offline, on GitHub, or confidential.",
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
],
adityabhaiya: [
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
],
adityabhaiya: ["Hello"],
help: [
'<span class="command">whatisdevsoc</span> What is Devsoc?',
'<span class="command">whoisdevsoc</span> Who is devsoc?',
'<span class="command">whyisdevsoc</span> Why is devsoc',
'<span class="command">aditansh</span> Aditansh',
'<span class="command">adityabhaiya</span> Adityabhaiya',
'<span class="command">help</span> Help',
'<span class="command">clear</span> Clear terminal',
'<span class="command">whatisdevsoc</span>What is Devsoc?',
'<span class="command">whoisdevsoc</span>Who is devsoc?',
'<span class="command">whyisdevsoc</span>Why is devsoc',
'<span class="command">aditansh</span>Aditansh',
'<span class="command">adityabhaiya</span>Adityabhaiya',
'<span class="command">help</span>Help',
'<span class="command">clear</span>Clear terminal',
"<br>",
],
clear: [],
Expand All @@ -60,23 +68,73 @@ const Terminal = () => {
],
};

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));


const handleKeyPress = (event: React.KeyboardEvent) => {
if (event.key === "Enter") {
event.preventDefault();
const trimmedInput = inputValue.trim();
if (trimmedInput === "clear") {
setCommands([]);
} else {
const output = commandOutputs[trimmedInput] ?? [
`Command not found: ${trimmedInput}`,
];
setCommands([...commands, { command: trimmedInput, output }]);
console.log(output);
}
setCommands([]);
} else {
const output = commandOutputs[trimmedInput] ?? [`Command not found: ${trimmedInput}`];
const displayOutput = output.map(() => "");
setCommands((prevCommands) => [...prevCommands, { command: trimmedInput, output, displayOutput }]);
}

setInputValue("");
}
};

useEffect(() => {
if (commands.length > 0) {
triggerTypewriterEffect(commands.length - 1);
}
}, [commands]);

const triggerTypewriterEffect = (commandIndex: number) => {
let currentLineIndex = 0;

if (commandIndex >= 0 && commandIndex < commands.length) {
const command = commands[commandIndex];
if (!command) return;
const outputLines = command.output;

const typeNextChar = () => {
if (currentLineIndex < outputLines.length) {
const line = outputLines[currentLineIndex]??'';
const currentDisplayLine = command.displayOutput[currentLineIndex] ?? '';
const nextCharIndex = currentDisplayLine.length;

if (nextCharIndex < line.length) {
setCommands((prevCommands) => {
const newCommands = [...prevCommands];
if (newCommands[commandIndex]) {
const newDisplayOutput = [...newCommands[commandIndex]?.displayOutput ?? []];
newDisplayOutput[currentLineIndex] = line.substr(0, nextCharIndex + 1);
newCommands[commandIndex].displayOutput = newDisplayOutput;
}
return newCommands;
});
setTimeout(typeNextChar, 50);
} else {

currentLineIndex++;
setTimeout(typeNextChar, 0);
}
}
};

typeNextChar();
}
};






const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputValue(event.target.value);
};
Expand Down Expand Up @@ -143,21 +201,22 @@ scrollToBottom()
{/* <span className="color2 ml-[15px]">Welcome to Devsoc web terminal.</span> */}
{/* <span className="color2 ml-[15px]">For a list of available commands, type</span> <span className="command">'help'</span><span className="color2">.</span> */}
{commands.map((cmdObj, index) => (
<div key={index}>
<div className="command-line">
<span>[email protected]:~${cmdObj.command}</span>
</div>
{cmdObj.output.map((line, lineIndex) => (
<div
key={lineIndex}
className="command-output"
dangerouslySetInnerHTML={{ __html: line }}
></div>
))}
</div>
))}
<div key={index}>
<div className="command-line">
<span>[email protected]:~${cmdObj.command}</span>
</div>
{cmdObj.displayOutput.map((line, lineIndex) => (
<div
key={lineIndex}
className="command-output"
dangerouslySetInnerHTML={{ __html: line }}
></div>
))}
</div>
))}

<div id="command" className="flex">
<div id="liner" className="ml-[15px] flex-1">
<div id="liner" className="ml-[10px] flex-1">
<span>[email protected]:~${inputValue}</span>
<b className="cursor"></b>
<div style={{ marginBottom: 100 }} ref={endRef} />
Expand All @@ -175,15 +234,15 @@ scrollToBottom()

<style jsx>{`
.command-output {
margin-left: 5px;
margin-left: 10px;
}
.command-line {
margin-bottom: 10px;
margin-left: 5px;
margin-left: 10px;
}
.command {
margin-bottom: 10px;
margin-left: 5px;
margin-left: 10px;
}
`}</style>
</div>
Expand Down
39 changes: 39 additions & 0 deletions devsoc24-landing/src/components/terminal/typewriter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useEffect, useState } from 'react';

interface TypewriterEffectProps {
textLines: string[];
onTypingComplete: () => void;
}

const TypewriterEffect = ({ textLines, onTypingComplete }: TypewriterEffectProps) => {
const [lineIndex, setLineIndex] = useState(0);
const [displayedLines, setDisplayedLines] = useState<(string | undefined)[]>([]);


useEffect(() => {
if (lineIndex < textLines.length) {
const timeoutId = setTimeout(() => {
setDisplayedLines((prevLines) => [...prevLines, textLines[lineIndex]]);
setLineIndex(lineIndex + 1);
}, lineIndex * 10);

return () => clearTimeout(timeoutId);
} else {
setTimeout(()=>{

onTypingComplete();
},600)
}
}, [lineIndex, textLines, onTypingComplete]);

return (
<div className='text-[#757575] text-sm font-diatype font-thin'>
{displayedLines.map((line, index) => (
<div key={index} dangerouslySetInnerHTML={{ __html: line ?? '' }} />

))}
</div>
);
};

export default TypewriterEffect
46 changes: 44 additions & 2 deletions devsoc24-landing/src/pages/terminal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client"
import { useState } from "react";
import React from 'react';
import TypewriterEffect from '../components/terminal/typewriter'

// import Image from "next/image";
import Card from "../components/card";
Expand All @@ -13,10 +14,38 @@ import Timeline from "../components/terminal/timeline";
import { IoMdClose } from "react-icons/io";


const help = [
'<span class="">WDWKJDCNWKJC</span>',
'<span class="">WUDC GWUDYGC WQUYDCG WQUODCG </span>',
'<span class="">WIDCHWCW</span>',
'<span class="">JQSCHNJ CIHQIE WQCNWIKCJNWKCWNDCKJW DN</span> ',
'<span class="">OKOEWKCWJDIOCJWI CWCJWQJDCJWC.........</span> ',
'<span class="">WDKNCWDKJ</span> ',
'<span class="">WDOCOWQCJQDWODC</span> ',
'<span class="">IBC QICUDH QINCQWIC UHDWCIUWDCHIWUDHCWDCJIWDCMWD W</span> ',
'<span class="">NJDJCDCNDJCND..................</span> ',
'<span class="">DCNQW CIQWC WQODC WDC Q</span>',
'<span class="">WDCQN WD QC</span> ',
'<span class="">WJDCN QWINCQJWCNQWCKJN DWCNWD CKNWDC.........</span> ',
'<span class="">QWIJNCI WDUHCIWDCN WIDCKJNW DICKJQWDDNCQW</span> ',
'<span class="">WQDCN WDKCNJWQLKDCJQWNDCKJLQWN CKLDNCQWKDC WJDCNQKLW DNCQWJK</span>',
'<span class="">WKDNCW KJDCNWKDNCWJKCWKDJCNWDLKJC</span> ',
'<span class="">WQDJCNIUWQHCUWHDCIUHWQUDCHUIWHDCW</span> ',
'<span class="">WDCIHWDCIUHWIUDCHIUWQHCQWHCU.........</span> ',
'<span class="">JWD N28DH 92NJK IWCJIJDWCNW</span> ',
'<span class="">WQINJC IUWCINWCD</span> ',
'<span class="">JIWEIUCIUWHCIU</span> ',
'<span class="">LOADING....................................</span> ',

"<br>",
];

export default function Home() {
const cardTypes = ["About", "Timeline", "Tracks", "Prizepool", "Sponsors", "Portal", "FAQs"]
const cardImage = ["personabout 2.svg", "Frame 13.svg", "Frame 13 2.svg", "Frame 13 3.svg", "Frame 13 4.svg", "Frame 13 5.svg","Frame 13 6.svg"]

const [typingCompleted, setTypingCompleted] = useState(false);

type CardKey = 'About' | 'FAQs' | 'Prizepool' | 'Tracks' | 'Timeline';

const cardComponents: {
Expand All @@ -36,11 +65,21 @@ const [activeCard, setActiveCard] = React.useState<CardKey | ''>('');
const handleClick = (cardName: CardKey) => {
setActiveCard(cardName);
};
const handleTypingComplete = () => {
setTypingCompleted(true);
};

const SelectedComponent = activeCard ? cardComponents[activeCard] : null;
return (
<main className="font-diatype">
<div className="w-full bg-[#494848] h-[2.4%] fixed font-diatype flex justify-center z-30">
<main className="font-diatype bg-[#232323] h-[100vh]">
{!typingCompleted ? (
<div className="pl-3">
<TypewriterEffect textLines={help} onTypingComplete={handleTypingComplete}/>

</div>
) : (
<>
<div className="content-after-typing w-full bg-[#494848] h-[2.4%] fixed font-diatype flex justify-center z-30">
<div style={{
backgroundImage: `url('/Topborder.svg')`,
backgroundSize: 'cover',
Expand Down Expand Up @@ -104,6 +143,9 @@ const handleClick = (cardName: CardKey) => {
className=""
/> */}
</div>
</>
)}

</main>
);
}

0 comments on commit e4fec92

Please sign in to comment.