diff --git a/frontend/public/codezap.png b/frontend/public/codezap.png
new file mode 100644
index 000000000..0eae5f67d
Binary files /dev/null and b/frontend/public/codezap.png differ
diff --git a/frontend/public/index.html b/frontend/public/index.html
index 268d1c971..ff20b8126 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -1,5 +1,5 @@
-
+
+
+
+
+
- codezap
+ 코드잽
diff --git a/frontend/src/assets/images/checkCircle.svg b/frontend/src/assets/images/checkCircle.svg
new file mode 100644
index 000000000..95f120964
--- /dev/null
+++ b/frontend/src/assets/images/checkCircle.svg
@@ -0,0 +1,10 @@
+
diff --git a/frontend/src/assets/images/index.ts b/frontend/src/assets/images/index.ts
index 4e56dbc01..53009ee3d 100644
--- a/frontend/src/assets/images/index.ts
+++ b/frontend/src/assets/images/index.ts
@@ -15,8 +15,10 @@ export { default as HamburgerIcon } from './Hamburger';
export { default as PersonIcon } from './person.svg';
export { default as ClockIcon } from './clock.svg';
export { default as BooksIcon } from './books.svg';
+export { default as CheckCircleIcon } from './checkCircle.svg';
// Logo
export { default as CodeZapLogo } from './codezapLogo.svg';
export { default as TigerLogo } from './tiger.svg';
export { default as ZapzapLogo } from './zapzap.svg';
+export { default as ZapzapCuriousLogo } from './zapzapCurious.svg';
diff --git a/frontend/src/assets/images/zapzapCurious.svg b/frontend/src/assets/images/zapzapCurious.svg
new file mode 100644
index 000000000..53c53d2df
--- /dev/null
+++ b/frontend/src/assets/images/zapzapCurious.svg
@@ -0,0 +1,9 @@
+
diff --git a/frontend/src/pages/LandingPage/LandingPage.style.ts b/frontend/src/pages/LandingPage/LandingPage.style.ts
new file mode 100644
index 000000000..98245eeae
--- /dev/null
+++ b/frontend/src/pages/LandingPage/LandingPage.style.ts
@@ -0,0 +1,103 @@
+import styled from '@emotion/styled';
+
+export const Container = styled.div`
+ max-width: 1200px;
+ margin: auto;
+ padding: 1.25rem;
+`;
+
+export const ContentSection = styled.div`
+ display: flex;
+ gap: 3rem;
+ align-items: center;
+ justify-content: space-between;
+
+ width: 100%;
+ margin-top: 4rem;
+
+ @media (max-width: 768px) {
+ flex-direction: column-reverse;
+ text-align: center;
+ }
+`;
+
+export const TextContent = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 2rem;
+ justify-content: space-between;
+
+ @media (max-width: 768px) {
+ align-items: center;
+ justify-content: center;
+ }
+`;
+
+export const ImageWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
+
+export const CardSection = styled.div`
+ display: flex;
+ justify-content: space-between;
+ padding: 3rem 0;
+
+ @media (max-width: 768px) {
+ flex-direction: column;
+ }
+`;
+
+export const Card = styled.div`
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+ gap: 0.5rem;
+
+ margin: 0 10px;
+ padding: 20px;
+
+ text-align: center;
+
+ background-color: white;
+ border-radius: 8px;
+ box-shadow: 1px 2px 8px 1px #00000030;
+ &:hover {
+ bottom: 0.5rem;
+ transform: scale(1.025);
+ }
+
+ @media (max-width: 768px) {
+ align-items: center;
+ margin: 10px 0;
+ }
+`;
+
+export const TemplateSection = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ width: 100%;
+ margin-top: 3rem;
+ padding: 4rem 0;
+
+ @media (max-width: 768px) {
+ flex-direction: column;
+ }
+`;
+
+export const CodeSection = styled.div`
+ margin-right: 2rem;
+
+ @media (max-width: 768px) {
+ width: 100%;
+ }
+`;
+
+export const SyntaxHighlighterWrapper = styled.div<{ isOpen: boolean }>`
+ overflow: hidden;
+ max-height: ${({ isOpen }) => (isOpen ? '1000rem' : '0')};
+ animation: ${({ isOpen }) => (!isOpen ? 'collapse' : 'expand')} 0.7s ease-in-out forwards;
+`;
diff --git a/frontend/src/pages/LandingPage/LandingPage.tsx b/frontend/src/pages/LandingPage/LandingPage.tsx
index 192d25d76..4ac5dcf5a 100644
--- a/frontend/src/pages/LandingPage/LandingPage.tsx
+++ b/frontend/src/pages/LandingPage/LandingPage.tsx
@@ -1,78 +1,106 @@
-import styled from '@emotion/styled';
import { type LanguageName, loadLanguage } from '@uiw/codemirror-extensions-langs';
import { quietlight } from '@uiw/codemirror-theme-quietlight';
import CodeMirror, { EditorView } from '@uiw/react-codemirror';
+import { Link } from 'react-router-dom';
-import { ChevronIcon, CodeZapLogo } from '@/assets/images';
+import { CheckCircleIcon, ChevronIcon, ZapzapLogo } from '@/assets/images';
import { Button, Flex, Heading, Text } from '@/components';
import { CustomCodeMirrorTheme } from '@/components/TemplateCard/TemplateCard.style';
+import { ToastContext } from '@/contexts';
+import { useCustomContext } from '@/hooks/utils';
import { theme } from '@/style/theme';
+import { SourceCodes } from '@/types';
import { getLanguageByFilename } from '@/utils';
-import * as S from '../TemplatePage/TemplatePage.style';
+import * as S from './LandingPage.style';
const LandingPage = () => (
-
-
-
- 코드잽
-
-
-
- 자주 쓰는 코드를 나만의 템플릿으로 저장해보세요.
- 코드잽에서 나의 코드를 빠르게 찾고, 효율적으로 관리할 수 있습니다.
-
-
-
-
- 💾 간편한 저장
-
- 자주 쓰는 나의 코드를 ZAP하게 저장하세요.
-
-
-
-
- 🔍 빠른 검색
-
- 필요한 나의 코드를 ZAP하게 찾아 사용하세요.
-
-
+
+
+
+ 이런 경험 한 번쯤 있으시죠?
+ {'"아, 그때 그 코드 어디에 썼더라..."'}
+
+
+ 더이상 코드를 찾느데 헤매지 마세요!
+ 코드잽에 자주 쓰는 코드를 템플릿으로 저장하고 빠르게 찾아요.
+
+
+
+
+
+
-
- 📊 체계적인 관리
-
- 직관적인 분류 시스템으로 ZAP하게 정리하세요.
+
+
+
+
+ ZAP하게 저장
+
+ 자주 쓰는 나의 코드를 간편하게 저장하세요
+
+
+
+
+ ZAP하게 관리
+
+
+ 직관적인 분류 시스템으로 체계적으로 관리하세요
-
-
+
+
+
+
+ ZAP하게 검색
+
+ 필요한 나의 코드를 빠르게 찾아 사용하세요
+
+
-
+
-
-
+
+
- ⚡️ 템플릿이란?
+ 템플릿이란?
-
- 템플릿은 반복적으로 작성하게 되는 코드 블럭 모음
-
+
+ 코드잽에서 템플릿이란 반복적으로 작성하게 되는 소스 코드의 모음을 뜻해요.
+
+
+ 하나의 템플릿에 여러개의 소스코드를 넣을 수 있어요!
+
-
+
- 🙌 코드잽은 이런 분들에게 딱이에요
+ 소스코드란?
-
- • 자주 쓰는 코드 템플릿을 간편하게 저장하고 싶은 분
-
-
- • 프로젝트 파일을 뒤적거리는 대신 필요한 코드를 빠르게 찾고 싶은 분
-
-
- • 체계적으로 코드를 정리하고 싶지만 방법을 모르셨던 분
-
+
+ 코드잽에서 소스코드란 파일명 + 소스코드 내용으로 이루어진 코드 단위를 뜻해요.
+
+
+ 파일명.[확장자]를 입력하면 하이라이트가 되고 복사 버튼으로 편하게 복사할 수 있어요!
+
-
-
+
+
+
+
+ 코드잽은 이런 분들에게 딱이에요 !
+ 자주 쓰는 코드 템플릿을 간편하게 저장하고 싶은 분
+ 프로젝트 파일을 뒤적거리는 대신 필요한 코드를 빠르게 찾고 싶은 분
+ 체계적으로 코드를 정리하고 싶지만 방법을 모르셨던 분
+
+
+
+
+
+
+
+
+
+
+
);
export default LandingPage;
@@ -82,12 +110,18 @@ const ExamCode = () => {
id: 102,
filename: 'App.tsx',
content:
- "import React from 'react';\nimport MyComponent from './MyComponent';\n\nconst App: React.FC = () => {\n return (\n \n \n
\n );\n};\n\nexport default App;",
+ "import React from 'react';\nimport MyComponent from './MyComponent';\n\nconst Template = () => {\n return (\n \n \n
\n );\n};\n\nexport default Template;",
ordinal: 2,
};
+ const { infoAlert } = useCustomContext(ToastContext);
+ const copyCode = (sourceCode: SourceCodes) => () => {
+ navigator.clipboard.writeText(sourceCode.content);
+ infoAlert('코드가 복사되었습니다!');
+ };
+
return (
-
+
{
{sourceCode.filename}
-
+
);
};
-
-const Card = styled.div`
- cursor: pointer;
-
- display: flex;
- flex-direction: column;
- gap: 2rem;
-
- padding: 2rem;
-
- background-color: ${theme.color.light.primary_500};
- border-radius: 24px;
-
- transition: 0.1s ease;
- &:hover {
- bottom: 0.5rem;
- transform: scale(1.025);
- box-shadow: 1px 2px 8px 1px #00000030;
- }
-`;
diff --git a/frontend/src/pages/MyTemplatesPage/MyTemplatePage.tsx b/frontend/src/pages/MyTemplatesPage/MyTemplatePage.tsx
index 41f62286b..287612170 100644
--- a/frontend/src/pages/MyTemplatesPage/MyTemplatePage.tsx
+++ b/frontend/src/pages/MyTemplatesPage/MyTemplatePage.tsx
@@ -2,7 +2,7 @@ import { useState, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { DEFAULT_SORTING_OPTION, SORTING_OPTIONS } from '@/api';
-import { ArrowUpIcon, PlusIcon, SearchIcon } from '@/assets/images';
+import { ArrowUpIcon, PlusIcon, SearchIcon, ZapzapCuriousLogo } from '@/assets/images';
import {
CategoryFilterMenu,
Flex,
@@ -108,7 +108,12 @@ const MyTemplatePage = () => {
if (templates.length === 0) {
if (debouncedKeyword !== '') {
- return 검색 결과가 없습니다.;
+ return (
+
+
+ 검색 결과가 없습니다.
+
+ );
} else {
return ;
}
diff --git a/frontend/src/pages/TemplatePage/TemplatePage.tsx b/frontend/src/pages/TemplatePage/TemplatePage.tsx
index f0c907d6e..244065efa 100644
--- a/frontend/src/pages/TemplatePage/TemplatePage.tsx
+++ b/frontend/src/pages/TemplatePage/TemplatePage.tsx
@@ -8,6 +8,7 @@ import { ChevronIcon, ClockIcon, PencilIcon, PersonIcon, TrashcanIcon } from '@/
import { Button, Flex, Heading, Modal, SelectList, TagButton, Text } from '@/components';
import { CustomCodeMirrorTheme } from '@/components/TemplateCard/TemplateCard.style';
import { ToastContext } from '@/contexts';
+import { useAuth } from '@/hooks/authentication';
import { useTemplate } from '@/hooks/template';
import { useCustomContext, useToggle } from '@/hooks/utils';
import { TemplateEditPage } from '@/pages';
@@ -18,6 +19,9 @@ import * as S from './TemplatePage.style';
const TemplatePage = () => {
const { id } = useParams<{ id: string }>();
const theme = useTheme();
+ const {
+ memberInfo: { name },
+ } = useAuth();
const { infoAlert } = useCustomContext(ToastContext);
const [isOpen, toggleModal] = useToggle();
@@ -65,20 +69,22 @@ const TemplatePage = () => {
{template.category?.name}
-
- {
- handleEditButtonClick();
- }}
- >
-
-
-
-
-
-
+ {template.member.name === name && (
+
+ {
+ handleEditButtonClick();
+ }}
+ >
+
+
+
+
+
+
+ )}