Skip to content

Commit

Permalink
add fetchGitHubFileContent, add hide code block, error handling CopyB…
Browse files Browse the repository at this point in the history
…utton
  • Loading branch information
MarkMelior committed Jul 10, 2024
1 parent 3744c43 commit 9152721
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 86 deletions.
Binary file modified app/favicon.ico
Binary file not shown.
6 changes: 4 additions & 2 deletions app/projects/app-router-auth/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { FormLogin, FormRegister, getUser } from '@/features';
import { fetchGitHubFileContent } from '@/shared/lib';
import { CodeBlock } from '@/shared/ui';
import { Header } from '@/widgets';
import { code1 } from './test';

export default async function AppRouterAuthPage() {
const user = await getUser();
const codePath1 = 'src/features/auth/services/login.ts';
const code1 = await fetchGitHubFileContent({ path: codePath1 });

return (
<>
Expand All @@ -16,7 +18,7 @@ export default async function AppRouterAuthPage() {

<div id='content-wrapper' className=''>
<p>Prisma ORM</p>
<CodeBlock text={code1} fileName='features/auth/services/login.ts' />
<CodeBlock text={code1} fileName={codePath1.slice(4)} />
</div>

{user && <p>Hi, {user.name}!</p>}
Expand Down
50 changes: 0 additions & 50 deletions app/projects/app-router-auth/test.ts

This file was deleted.

28 changes: 4 additions & 24 deletions src/features/burger/burger.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { SidebarNavigation } from '@/shared/ui';
import { DownloadCvButton, SidebarNavigation } from '@/shared/ui';
import { Button } from '@nextui-org/react';
import { RxHamburgerMenu } from 'react-icons/rx';
import { Drawer } from 'vaul';
Expand All @@ -20,37 +20,17 @@ export const Burger = () => {
<Drawer.Portal>
<Drawer.Overlay className='fixed inset-0 bg-black/40 z-40' />
<Drawer.Content className='bg-default-100 flex flex-col rounded-t-[10px] h-[90%] mt-24 fixed bottom-0 left-0 right-0 z-40 outline-none'>
<div className='w-full bg-default-100 h-32 flex justify-center items-center'>
<div className='w-full bg-default-100 h-12 flex justify-center items-center'>
<div className='w-12 h-1.5 rounded-full bg-default-300' />
</div>
<div className='overflow-auto'>
<div className='max-w-md mx-auto'>
<div className='max-w-md mx-auto px-4'>
<DownloadCvButton className='mb-8' />
<SidebarNavigation />
</div>
</div>
</Drawer.Content>
</Drawer.Portal>
</Drawer.Root>
// <Drawer.Root direction='right'>
// <Drawer.Trigger asChild>
// <Button
// className='text-default-500 hover:text-default-600 lg:hidden'
// isIconOnly
// variant='light'
// >
// <RxHamburgerMenu size={20} />
// </Button>
// </Drawer.Trigger>
// <Drawer.Portal>
// <Drawer.Overlay className='fixed inset-0 bg-black/40 z-40' />
// <Drawer.Content className='bg-default-100 h-full w-[80%] fixed bottom-0 right-0 z-40 outline-none overflow-y-auto'>
// <div className='p-4 bg-default-100 flex-1 h-full'>
// <div className='h-[300vh] max-w-md mx-auto'>
// <SidebarNavigation />
// </div>
// </div>
// </Drawer.Content>
// </Drawer.Portal>
// </Drawer.Root>
);
};
48 changes: 48 additions & 0 deletions src/shared/lib/fetch-github-file/fetch-github-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { cache } from 'react';

interface GitHubFileContent {
owner?: string;
repo?: string;
path: string;
}

export const fetchGitHubFileContent = cache(
async ({
owner = 'MarkMelior',
repo = 'simple-app',
path,
}: GitHubFileContent): Promise<string> => {
const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}`;

try {
const response = await fetch(url);

if (!response.ok) {
throw new Error(
`Error fetching from GitHub: ${response.status} - ${response.statusText}`,
);
}

const data = await response.json();

if (!data || !data.content) {
throw new Error('Invalid data format from GitHub API');
}

const content = atob(data.content);

// Remove last empty line
const contentSplit = content.split('\n');
if (contentSplit[contentSplit.length - 1] === '') {
contentSplit.pop();
}

return contentSplit.join('\n');
} catch (error) {
console.error('Error receiving a file from GitHub:', error);
return error?.toString() || 'An unknown error has occurred';

throw error; // Forward the error further for processing at the call level
}
},
);
3 changes: 2 additions & 1 deletion src/shared/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { fetchGitHubFileContent } from './fetch-github-file/fetch-github-file';
import { cn } from './tailwind-merge/tailwind-merge';

export { cn };
export { cn, fetchGitHubFileContent };
21 changes: 21 additions & 0 deletions src/shared/ui/code-block/code-block.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.showWrapper {
position: relative;
}

.gradient {
@apply absolute pointer-events-none w-full -top-32 h-32 bg-gradient-to-t from-default-100;
}

.showButton {
@apply bg-default-100 text-default-600 py-2 px-3 w-full text-left data-[pressed=true]:scale-100;

&:hover {
@apply bg-default-200;
}
}

.showButton:hover .gradient {
background: red !important;
background-color: red !important;
@apply from-default-200;
}
25 changes: 23 additions & 2 deletions src/shared/ui/code-block/code-block.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { Theme } from '@/shared/types/theme';
import { Skeleton } from '@nextui-org/react';
import { Button, Skeleton } from '@nextui-org/react';
import { useTheme } from 'next-themes';
import { FC, useEffect, useMemo, useState } from 'react';
import { BiLogoJavascript, BiLogoTypescript } from 'react-icons/bi';
Expand All @@ -12,18 +12,25 @@ import {
atomOneLight,
} from 'react-syntax-highlighter/dist/cjs/styles/hljs';
import { CopyButton } from '../copy-button/copy-button';
import cls from './code-block.module.scss';

interface CodeBlockProps {
text: string;
fileName?: string;
language?: 'TypeScript' | 'JavaScript';
linesLength?: number;
}

export const CodeBlock: FC<CodeBlockProps> = ({
text,
fileName,
language = 'TypeScript',
linesLength = 15,
}) => {
const [isExpanded, setIsExpanded] = useState(false);
const lines = text.split('\n');
const isLong = lines.length > linesLength;

const [mounted, setMounted] = useState(false);
const { theme } = useTheme();

Expand Down Expand Up @@ -55,14 +62,28 @@ export const CodeBlock: FC<CodeBlockProps> = ({
{fileName ? fileName : language}
<CopyButton text={text} />
</div>

<SyntaxHighlighter
language={language}
showLineNumbers
style={theme === Theme.DARK ? atomOneDark : atomOneLight}
className='!bg-default-100 border-t-1 border-default-200'
>
{text}
{isExpanded || !isLong ? text : lines.slice(0, linesLength).join('\n')}
</SyntaxHighlighter>

{isLong && (
<div className={cls.showWrapper}>
{!isExpanded && <div className={cls.gradient} />}
<Button
radius='none'
onClick={() => setIsExpanded(!isExpanded)}
className={cls.showButton}
>
{isExpanded ? 'Hide' : 'Show more'}
</Button>
</div>
)}
</div>
);
};
18 changes: 13 additions & 5 deletions src/shared/ui/copy-button/copy-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,21 @@ export const CopyButton: FC<CopyButtonProps> = ({ text }) => {
const [copied, setCopied] = useState(false);

const handleCopy = () => {
navigator.clipboard.writeText(text);
showMessage({
content: 'Copied to clipboard!',
type: 'success',
});
try {
navigator.clipboard.writeText(text);
showMessage({
content: 'Copied to clipboard!',
type: 'success',
});
} catch (err) {
showMessage({
content: 'Failed to copy!',
type: 'error',
});
}

setCopied(true);

setTimeout(() => {
setCopied(false);
}, 2500);
Expand Down
8 changes: 6 additions & 2 deletions src/shared/ui/download-cv-button/download-cv-button.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { cn } from '@/shared/lib';
import { Button } from '@nextui-org/react';
import Link from 'next/link';
import { FaDownload } from 'react-icons/fa6';

export const DownloadCvButton = () => {
export const DownloadCvButton = ({ className }: { className?: string }) => {
return (
<Button
as={Link}
Expand All @@ -11,7 +12,10 @@ export const DownloadCvButton = () => {
download='Frontend разработчик - Завгородний Марк'
fullWidth
startContent={<FaDownload />}
className='bg-white dark:bg-default-200 text-default-600 border border-default-200 dark:border-0 hover:text-default-700'
className={cn(
'bg-white dark:bg-default-200 text-default-600 border border-default-200 dark:border-0 hover:text-default-700 text-md py-6 md:py-4',
className,
)}
radius='sm'
>
Download CV
Expand Down

0 comments on commit 9152721

Please sign in to comment.