Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 9 additions & 27 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
}

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
<body>{children}</body>
</html>
);
)
}
39 changes: 39 additions & 0 deletions src/app/page.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.container {
min-height: 90vh;
display: flex;
flex-direction: column;
}

.main {
flex: 1;
padding: 2rem;
display: flex;
flex-direction: column;
gap: 2rem;
}

.buttonContainer {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
background-color: #f8f9fa;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}


.actionButton {
padding: 0.75rem 1.5rem;
border: none;
border-radius: 6px;
background-color: #228be6;
color: white;
font-weight: 600;
cursor: pointer;
transition: background-color 0.2s;
}

.actionButton:hover {
background-color: #1c7ed6;
}
125 changes: 30 additions & 95 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,38 @@
import Image from "next/image";
'use client';

import React from 'react';
import Header from '@/components/common/Header';
import Terminal from '@/components/terminal/Terminal';
import LevelSelectModal from '@/components/learn/LevelSelectModal';
import ContainerListModal from '@/components/learn/ContainerListModal';
import CommandDictionaryModal from '@/components/learn/CommandDictionaryModal';
import styles from './page.module.css';

export default function Home() {
const [isLevelModalOpen, setIsLevelModalOpen] = React.useState(false);
const [isContainerListModalOpen, setIsContainerListModalOpen] = React.useState(false);
const [isCommandDictModalOpen, setIsCommandDictModalOpen] = React.useState(false);

return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="list-inside list-decimal text-sm/6 text-center sm:text-left font-[family-name:var(--font-geist-mono)]">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] px-1 py-0.5 rounded font-[family-name:var(--font-geist-mono)] font-semibold">
src/app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
<div className={styles.container}>
<Header />

<LevelSelectModal
isOpen={isLevelModalOpen}
onClose={() => setIsLevelModalOpen(false)}
/>
<ContainerListModal
isOpen={isContainerListModalOpen}
onClose={() => setIsContainerListModalOpen(false)}
/>
<CommandDictionaryModal
isOpen={isCommandDictModalOpen}
onClose={() => setIsCommandDictModalOpen(false)}
/>

<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
</div>
<main className={styles.main}>
<Terminal />
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org →
</a>
</footer>
</div>
);
}
52 changes: 52 additions & 0 deletions src/components/browser/NetworkBrowser.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.browserContainer {
padding: 2rem;
background: #f8f9fa;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.networkList {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
margin-top: 1.5rem;
}

.networkCard {
background: white;
padding: 1.5rem;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
transition: transform 0.2s ease;
}

.networkCard:hover {
transform: translateY(-2px);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.networkName {
font-size: 1.25rem;
font-weight: 600;
color: #2d3748;
margin-bottom: 1rem;
}

.networkDetails {
color: #4a5568;
font-size: 0.875rem;
}

.networkDetail {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
}

.detailLabel {
font-weight: 500;
}

.detailValue {
color: #718096;
}
48 changes: 48 additions & 0 deletions src/components/common/Header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
background-color: #ffffff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.logo {
font-size: 1.5rem;
font-weight: bold;
}

.logo a {
color: #228be6;
text-decoration: none;
transition: color 0.2s;
}

.logo a:hover {
color: #1c7ed6;
}

.nav {
display: flex;
gap: 2rem;
align-items: center;
}

.navLink {
color: #495057;
text-decoration: none;
font-weight: 500;
padding: 0.5rem 1rem;
border-radius: 4px;
transition: all 0.2s;
}

.navLink:hover {
color: #228be6;
background-color: #e7f5ff;
}

.active {
color: #228be6;
background-color: #e7f5ff;
}
56 changes: 56 additions & 0 deletions src/components/common/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use client';

import React from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import styles from './Header.module.css';

const Header: React.FC = () => {
const pathname = usePathname();

const isActive = (path: string) => pathname === path;

return (
<header className={styles.header}>
<div className={styles.logo}>
<Link href="/">
DOCKERSIM
</Link>
</div>
<nav className={styles.nav}>
<Link
href="/"
className={`${styles.navLink} ${isActive('/') ? styles.active : ''}`}
>
학습
</Link>
<Link
href="/workspace"
className={`${styles.navLink} ${isActive('/workspace') ? styles.active : ''}`}
>
작업
</Link>
<Link
href="/board"
className={`${styles.navLink} ${isActive('/board') ? styles.active : ''}`}
>
게시판
</Link>
<Link
href="/questions"
className={`${styles.navLink} ${isActive('/questions') ? styles.active : ''}`}
>
자주 묻는 질문
</Link>
<Link
href="/settings"
className={`${styles.navLink} ${isActive('/settings') ? styles.active : ''}`}
>
설정
</Link>
</nav>
</header>
);
};

export default Header;
Loading