first commit
This commit is contained in:
52
components/ArticleCard.tsx
Normal file
52
components/ArticleCard.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import Image from 'next/image';
|
||||
import { VscEye, VscHeart, VscComment } from 'react-icons/vsc';
|
||||
|
||||
import { Article } from '@/types';
|
||||
|
||||
import styles from '@/styles/ArticleCard.module.css';
|
||||
|
||||
interface ArticleCardProps {
|
||||
article: Article;
|
||||
}
|
||||
|
||||
const ArticleCard = ({ article }: ArticleCardProps) => {
|
||||
return (
|
||||
<a
|
||||
href={article.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={styles.container}
|
||||
>
|
||||
<div className={styles.imageWrapper}>
|
||||
<Image
|
||||
src={article.cover_image}
|
||||
alt={article.title}
|
||||
fill
|
||||
sizes="(max-width: 768px) 100vw, 300px"
|
||||
className={styles.image}
|
||||
/>
|
||||
<div className={styles.viewsBadge}>
|
||||
<VscEye /> {article.page_views_count}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<h3 className={styles.title}>{article.title}</h3>
|
||||
<p className={styles.description}>{article.description}</p>
|
||||
|
||||
<div className={styles.footer}>
|
||||
<div className={styles.stats}>
|
||||
<div className={styles.stat}>
|
||||
<VscHeart className={styles.icon} />{' '}
|
||||
{article.public_reactions_count}
|
||||
</div>
|
||||
<div className={styles.stat}>
|
||||
<VscComment className={styles.icon} /> {article.comments_count}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
export default ArticleCard;
|
||||
49
components/Bottombar.tsx
Normal file
49
components/Bottombar.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
VscBell,
|
||||
VscCheck,
|
||||
VscError,
|
||||
VscWarning,
|
||||
VscSourceControl,
|
||||
} from 'react-icons/vsc';
|
||||
import { SiNextdotjs } from 'react-icons/si';
|
||||
|
||||
import styles from '@/styles/Bottombar.module.css';
|
||||
|
||||
const Bottombar = () => {
|
||||
return (
|
||||
<footer className={styles.bottomBar}>
|
||||
<div className={styles.container}>
|
||||
<a
|
||||
href="https://github.com/itsnitinr/vscode-portfolio"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
className={styles.section}
|
||||
>
|
||||
<VscSourceControl className={styles.icon} />
|
||||
<p>main</p>
|
||||
</a>
|
||||
<div className={styles.section}>
|
||||
<VscError className={styles.icon} />
|
||||
<p className={styles.errorText}>0</p>
|
||||
<VscWarning className={styles.icon} />
|
||||
<p>0</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.container}>
|
||||
<div className={styles.section}>
|
||||
<SiNextdotjs className={styles.icon} />
|
||||
<p>Powered by Next.js</p>
|
||||
</div>
|
||||
<div className={styles.section}>
|
||||
<VscCheck className={styles.icon} />
|
||||
<p>Prettier</p>
|
||||
</div>
|
||||
<div className={styles.section}>
|
||||
<VscBell />
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Bottombar;
|
||||
51
components/ContactCode.tsx
Normal file
51
components/ContactCode.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import styles from '@/styles/ContactCode.module.css';
|
||||
|
||||
const contactItems = [
|
||||
{
|
||||
social: 'website',
|
||||
link: 'Portfolio',
|
||||
href: 'https://ahmed.galadima.talenttic.com',
|
||||
},
|
||||
{
|
||||
social: 'email',
|
||||
link: 'ahmed.galadima@hotmail.com',
|
||||
href: 'mailto:ahmed.galadima@hotmail.com',
|
||||
},
|
||||
{
|
||||
social: 'github',
|
||||
link: 'galads',
|
||||
href: 'https://github.com/glimz',
|
||||
},
|
||||
{
|
||||
social: 'linkedin',
|
||||
link: 'Linkedin URL',
|
||||
href: 'https://www.linkedin.com/in/ahmed-galadima',
|
||||
},
|
||||
{
|
||||
social: 'twitter',
|
||||
link: 'galads',
|
||||
href: 'https://x.com/Mr_galads',
|
||||
},
|
||||
];
|
||||
|
||||
const ContactCode = () => {
|
||||
return (
|
||||
<div className={styles.code}>
|
||||
<p className={styles.line}>
|
||||
<span className={styles.className}>.socials</span> {
|
||||
</p>
|
||||
{contactItems.map((item, index) => (
|
||||
<p className={styles.line} key={index}>
|
||||
{item.social}:{' '}
|
||||
<a href={item.href} target="_blank" rel="noopener">
|
||||
{item.link}
|
||||
</a>
|
||||
;
|
||||
</p>
|
||||
))}
|
||||
<p className={styles.line}>}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContactCode;
|
||||
80
components/Explorer.tsx
Normal file
80
components/Explorer.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { useState } from 'react';
|
||||
import { VscChevronRight } from 'react-icons/vsc';
|
||||
|
||||
import styles from '@/styles/Explorer.module.css';
|
||||
|
||||
const explorerItems = [
|
||||
{
|
||||
name: 'home.tsx',
|
||||
path: '/',
|
||||
icon: '/logos/react_icon.svg',
|
||||
},
|
||||
{
|
||||
name: 'about.html',
|
||||
path: '/about',
|
||||
icon: '/logos/html_icon.svg',
|
||||
},
|
||||
{
|
||||
name: 'contact.css',
|
||||
path: '/contact',
|
||||
icon: '/logos/css_icon.svg',
|
||||
},
|
||||
{
|
||||
name: 'projects.js',
|
||||
path: '/projects',
|
||||
icon: '/logos/js_icon.svg',
|
||||
},
|
||||
/* {
|
||||
name: 'articles.json',
|
||||
path: '/articles',
|
||||
icon: '/logos/json_icon.svg',
|
||||
}, */
|
||||
{
|
||||
name: 'github.md',
|
||||
path: '/github',
|
||||
icon: '/logos/markdown_icon.svg',
|
||||
},
|
||||
];
|
||||
|
||||
const Explorer = () => {
|
||||
const [portfolioOpen, setPortfolioOpen] = useState(true);
|
||||
|
||||
return (
|
||||
<div className={styles.explorer}>
|
||||
<p className={styles.title}>Explorer</p>
|
||||
<div>
|
||||
<input
|
||||
type="checkbox"
|
||||
className={styles.checkbox}
|
||||
id="portfolio-checkbox"
|
||||
checked={portfolioOpen}
|
||||
onChange={() => setPortfolioOpen(!portfolioOpen)}
|
||||
/>
|
||||
<label htmlFor="portfolio-checkbox" className={styles.heading}>
|
||||
<VscChevronRight
|
||||
className={styles.chevron}
|
||||
style={portfolioOpen ? { transform: 'rotate(90deg)' } : {}}
|
||||
/>
|
||||
Portfolio
|
||||
</label>
|
||||
<div
|
||||
className={styles.files}
|
||||
style={portfolioOpen ? { display: 'block' } : { display: 'none' }}
|
||||
>
|
||||
{explorerItems.map((item) => (
|
||||
<Link href={item.path} key={item.name}>
|
||||
<div className={styles.file}>
|
||||
<Image src={item.icon} alt={item.name} height={18} width={18} />{' '}
|
||||
<p>{item.name}</p>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Explorer;
|
||||
35
components/Head.tsx
Normal file
35
components/Head.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import Head from 'next/head';
|
||||
|
||||
interface CustomHeadProps {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const CustomHead = ({ title }: CustomHeadProps) => {
|
||||
return (
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Ahmed Galadima, Senior QA Engineer, Automation Consultant, Software Development, Test Automation, CI/CD, DevOps"
|
||||
/>
|
||||
<meta
|
||||
name="keywords"
|
||||
content="Ahmed Galadima, Senior QA Engineer, Automation Consultant, Software Development, Test Automation, CI/CD, DevOps"
|
||||
/>
|
||||
<meta property="og:title" content="Ahmed Galadima's Portfolio" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="A Senior QA Engineer, Automation Consultant. Software Development, Test Automation, CI/CD, DevOps"
|
||||
/>
|
||||
<meta property="og:image" content="https://imgur.com/4zi5KkQ.png" />
|
||||
<meta property="og:url" content="https://vscode-portfolio.vercel.app" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
</Head>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomHead;
|
||||
|
||||
CustomHead.defaultProps = {
|
||||
title: 'Ahmed Galadima | Portfolio',
|
||||
};
|
||||
25
components/Illustration.tsx
Normal file
25
components/Illustration.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { SVGProps } from 'react';
|
||||
|
||||
const Illustration = (props: SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
width={486}
|
||||
height={534}
|
||||
viewBox="0 0 486 534"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<circle cx={167} cy={60} r={60} fill="#D7F484" />
|
||||
<circle cx={37.5} cy={215.5} r={37.5} fill="currentColor" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M486 144.469c-38.145-31.86-87.255-51.033-140.842-51.033-121.415 0-219.842 98.427-219.842 219.842 0 14.167 1.34 28.02 3.9 41.441 47.414-86.154 91.678-142.17 146.717-170.767 56.069-29.132 121.816-29.08 210.067-6.68v-32.803zm0 48.288v289.33c-38.145 31.86-87.255 51.033-140.842 51.033-100.321 0-184.947-67.197-211.325-159.037l1.502.805c49.937-93.22 94.046-149.844 147.514-177.625 52.014-27.025 114.411-27.498 203.151-4.506z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Illustration;
|
||||
44
components/Layout.tsx
Normal file
44
components/Layout.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import Titlebar from '@/components/Titlebar';
|
||||
import Sidebar from '@/components/Sidebar';
|
||||
import Explorer from '@/components/Explorer';
|
||||
import Bottombar from '@/components/Bottombar';
|
||||
import Tabsbar from '@/components/Tabsbar';
|
||||
|
||||
import styles from '@/styles/Layout.module.css';
|
||||
|
||||
interface LayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const Layout = ({ children }: LayoutProps) => {
|
||||
// set scroll to top of main content on url pathname change
|
||||
const router = useRouter();
|
||||
useEffect(() => {
|
||||
const main = document.getElementById('main-editor');
|
||||
if (main) {
|
||||
main.scrollTop = 0;
|
||||
}
|
||||
}, [router.pathname]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Titlebar />
|
||||
<div className={styles.main}>
|
||||
<Sidebar />
|
||||
<Explorer />
|
||||
<div style={{ width: '100%' }}>
|
||||
<Tabsbar />
|
||||
<main id="main-editor" className={styles.content}>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<Bottombar />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Layout;
|
||||
51
components/ProjectCard.tsx
Normal file
51
components/ProjectCard.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import Image from 'next/image';
|
||||
|
||||
import { Project } from '@/types';
|
||||
|
||||
import styles from '@/styles/ProjectCard.module.css';
|
||||
|
||||
interface ProjectCardProps {
|
||||
project: Project;
|
||||
}
|
||||
|
||||
const ProjectCard = ({ project }: ProjectCardProps) => {
|
||||
return (
|
||||
<a
|
||||
href={project.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={styles.card}
|
||||
>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.logoWrapper}>
|
||||
<Image
|
||||
src={project.logo}
|
||||
alt={`${project.title} logo`}
|
||||
width={24}
|
||||
height={24}
|
||||
className={styles.logo}
|
||||
/>
|
||||
</div>
|
||||
<p className={styles.type}>{project.type}</p>
|
||||
<h3 className={styles.title}>{project.title}</h3>
|
||||
<p className={styles.description}>{project.description}</p>
|
||||
|
||||
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<p className={styles.date}>{project.date}</p>
|
||||
<p className={styles.status} data-status={project.status.toLowerCase()}>
|
||||
{project.status}
|
||||
</p>
|
||||
{/* <p className={styles.skills}>{project.skills}</p> */}
|
||||
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
// Add hover effect to the card
|
||||
// Add a gradient overlay on hover
|
||||
|
||||
|
||||
export default ProjectCard;
|
||||
71
components/RepoCard.tsx
Normal file
71
components/RepoCard.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import {
|
||||
VscEye,
|
||||
VscRepoForked,
|
||||
VscStarEmpty,
|
||||
VscGithubAlt,
|
||||
VscLinkExternal,
|
||||
VscTypeHierarchy,
|
||||
} from 'react-icons/vsc';
|
||||
|
||||
import { Repo } from '@/types';
|
||||
|
||||
import styles from '@/styles/RepoCard.module.css';
|
||||
|
||||
interface RepoCardProps {
|
||||
repo: Repo;
|
||||
}
|
||||
|
||||
const RepoCard = ({ repo }: RepoCardProps) => {
|
||||
return (
|
||||
<div className={styles.card}>
|
||||
<div className={styles.cardHeader}>
|
||||
<h3 className={styles.title}>{repo.name}</h3>
|
||||
{repo.language && (
|
||||
<div className={styles.language}>
|
||||
<VscTypeHierarchy className={styles.languageIcon} />
|
||||
<span>{repo.language}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p>{repo.description || 'No description provided'}</p>
|
||||
<div className={styles.stats}>
|
||||
<div>
|
||||
<div>
|
||||
<VscStarEmpty className={styles.icon} />
|
||||
{repo.stargazers_count}
|
||||
</div>
|
||||
<div>
|
||||
<VscRepoForked className={styles.icon} />
|
||||
{repo.forks}
|
||||
</div>
|
||||
<div>
|
||||
<VscEye className={styles.icon} />
|
||||
{repo.watchers}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href={repo.html_url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="View Repository"
|
||||
>
|
||||
<VscGithubAlt className={styles.icon} />
|
||||
</a>
|
||||
{repo.homepage && (
|
||||
<a
|
||||
href={repo.homepage}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title="Visit Live Site"
|
||||
>
|
||||
<VscLinkExternal className={styles.icon} />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RepoCard;
|
||||
74
components/Sidebar.tsx
Normal file
74
components/Sidebar.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import {
|
||||
VscAccount,
|
||||
VscSettings,
|
||||
VscMail,
|
||||
VscGithubAlt,
|
||||
VscCode,
|
||||
VscFiles,
|
||||
VscEdit,
|
||||
} from 'react-icons/vsc';
|
||||
|
||||
import styles from '@/styles/Sidebar.module.css';
|
||||
|
||||
const sidebarTopItems = [
|
||||
{ Icon: VscFiles, path: '/' },
|
||||
{ Icon: VscGithubAlt, path: '/github' },
|
||||
{ Icon: VscCode, path: '/projects' },
|
||||
{ Icon: VscEdit, path: '/articles' },
|
||||
{ Icon: VscMail, path: '/contact' },
|
||||
];
|
||||
|
||||
const sidebarBottomItems = [
|
||||
{ Icon: VscAccount, path: '/about' },
|
||||
{ Icon: VscSettings, path: '/settings' },
|
||||
];
|
||||
|
||||
const Sidebar = () => {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<aside className={styles.sidebar}>
|
||||
<div className={styles.sidebarTop}>
|
||||
{sidebarTopItems.map(({ Icon, path }) => (
|
||||
<Link href={path} key={path}>
|
||||
<div
|
||||
className={`${styles.iconContainer} ${
|
||||
router.pathname === path && styles.active
|
||||
}`}
|
||||
>
|
||||
<Icon
|
||||
size={16}
|
||||
fill={
|
||||
router.pathname === path
|
||||
? 'rgb(225, 228, 232)'
|
||||
: 'rgb(106, 115, 125)'
|
||||
}
|
||||
className={styles.icon}
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.sidebarBottom}>
|
||||
{sidebarBottomItems.map(({ Icon, path }) => (
|
||||
<div className={styles.iconContainer} key={path}>
|
||||
<Link href={path}>
|
||||
<Icon
|
||||
fill={
|
||||
router.pathname === path
|
||||
? 'rgb(225, 228, 232)'
|
||||
: 'rgb(106, 115, 125)'
|
||||
}
|
||||
className={styles.icon}
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
28
components/Tab.tsx
Normal file
28
components/Tab.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
import styles from '@/styles/Tab.module.css';
|
||||
|
||||
interface TabProps {
|
||||
icon: string;
|
||||
filename: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
const Tab = ({ icon, filename, path }: TabProps) => {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Link href={path}>
|
||||
<div
|
||||
className={`${styles.tab} ${router.pathname === path && styles.active}`}
|
||||
>
|
||||
<Image src={icon} alt={filename} height={18} width={18} />
|
||||
<p>{filename}</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tab;
|
||||
26
components/Tabsbar.tsx
Normal file
26
components/Tabsbar.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import Tab from '@/components/Tab';
|
||||
|
||||
import styles from '@/styles/Tabsbar.module.css';
|
||||
|
||||
const Tabsbar = () => {
|
||||
return (
|
||||
<div className={styles.tabs}>
|
||||
<Tab icon="/logos/react_icon.svg" filename="home.tsx" path="/" />
|
||||
<Tab icon="/logos/html_icon.svg" filename="about.html" path="/about" />
|
||||
<Tab icon="/logos/css_icon.svg" filename="contact.css" path="/contact" />
|
||||
<Tab icon="/logos/js_icon.svg" filename="projects.js" path="/projects" />
|
||||
{/* <Tab
|
||||
icon="/logos/json_icon.svg"
|
||||
filename="articles.json"
|
||||
path="/articles"
|
||||
/> */}
|
||||
<Tab
|
||||
icon="/logos/markdown_icon.svg"
|
||||
filename="github.md"
|
||||
path="/github"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tabsbar;
|
||||
40
components/ThemeInfo.tsx
Normal file
40
components/ThemeInfo.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import Image from 'next/image';
|
||||
|
||||
import styles from '@/styles/ThemeInfo.module.css';
|
||||
|
||||
interface ThemeInfoProps {
|
||||
icon: string;
|
||||
name: string;
|
||||
publisher: string;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const ThemeInfo = ({ icon, name, publisher, theme }: ThemeInfoProps) => {
|
||||
const setTheme = (theme: string) => {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
localStorage.setItem('theme', theme);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.imageWrapper}>
|
||||
<Image
|
||||
src={icon}
|
||||
alt={name}
|
||||
height={80}
|
||||
width={80}
|
||||
className={styles.themeImage}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.info}>
|
||||
<div>
|
||||
<h3>{name}</h3>
|
||||
<h5>{publisher}</h5>
|
||||
</div>
|
||||
<button onClick={() => setTheme(theme)}>Set Color Theme</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeInfo;
|
||||
34
components/Titlebar.tsx
Normal file
34
components/Titlebar.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import Image from 'next/image';
|
||||
|
||||
import styles from '@/styles/Titlebar.module.css';
|
||||
|
||||
const Titlebar = () => {
|
||||
return (
|
||||
<section className={styles.titlebar}>
|
||||
<Image
|
||||
src="/logos/vscode_icon.svg"
|
||||
alt="VSCode Icon"
|
||||
height={15}
|
||||
width={15}
|
||||
className={styles.icon}
|
||||
/>
|
||||
<div className={styles.items}>
|
||||
<p>File</p>
|
||||
<p>Edit</p>
|
||||
<p>View</p>
|
||||
<p>Go</p>
|
||||
<p>Run</p>
|
||||
<p>Terminal</p>
|
||||
<p>Help</p>
|
||||
</div>
|
||||
<p className={styles.title}>Ahmed Galadima - Visual Studio Code</p>
|
||||
<div className={styles.windowButtons}>
|
||||
<span className={styles.minimize}></span>
|
||||
<span className={styles.maximize}></span>
|
||||
<span className={styles.close}></span>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Titlebar;
|
||||
Reference in New Issue
Block a user