Skip to content

Commit

Permalink
0.4.0 배포 (#306)
Browse files Browse the repository at this point in the history
  • Loading branch information
doputer authored Dec 12, 2022
2 parents 22c193b + bc38318 commit c9749e7
Show file tree
Hide file tree
Showing 65 changed files with 1,238 additions and 430 deletions.
1 change: 0 additions & 1 deletion .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ jobs:
`| ${score(summaryTotal.accessibility)} Accessibility | ${summaryTotal.accessibility} |`,
`| ${score(summaryTotal['best-practices'])} Best Practices | ${summaryTotal['best-practices']} |`,
`| ${score(summaryTotal.seo)} SEO | ${summaryTotal.seo} |`,
`| ${score(summaryTotal.pwa)} PWA | ${summaryTotal.pwa} |`,
].join('\n');
core.setOutput('comment', comment)
Expand Down
13 changes: 11 additions & 2 deletions backend/pm2.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@
"apps": [
{
"name": "knoticle-backend",
"script": "npm",
"args": "run start"
"script": "./dist/index.js",
"node_args": "-r ./tsconfig-paths.js",
"instance": 1,
"exec_mode": "cluster",
"wait_ready": true,
"listen_timeout": 50000,
"kill_timeout": 5000,
"merge_logs": true,
"env": {
"NODE_ENV": "prod"
}
}
]
}
4 changes: 2 additions & 2 deletions backend/src/apis/bookmarks/bookmarks.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ const createBookmark = async (req: Request, res: Response) => {
const deleteBookmark = async (req: Request, res: Response) => {
const bookmarkId = Number(req.params.bookmarkId);

await bookmarksService.deleteBookmark(bookmarkId);
const bookamrk = await bookmarksService.deleteBookmark(bookmarkId);

return res.status(200).send();
return res.status(200).send(bookamrk);
};

export default {
Expand Down
15 changes: 13 additions & 2 deletions backend/src/apis/bookmarks/bookmarks.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { prisma } from '@config/orm.config';
import { Message, NotFound } from '@errors';
import { Message, NotFound, ResourceConflict } from '@errors';

const createBookmark = async (user_id: number, book_id: number) => {
const bookmark = await prisma.bookmark.findFirst({
where: {
user_id,
book_id,
},
});

if (bookmark) throw new ResourceConflict(Message.BOOKMARK_ALREADY_EXISTS);

const { id } = await prisma.bookmark.create({
data: {
user_id,
Expand All @@ -14,11 +23,13 @@ const createBookmark = async (user_id: number, book_id: number) => {

const deleteBookmark = async (id: number) => {
try {
await prisma.bookmark.delete({
const bookmark = await prisma.bookmark.delete({
where: {
id,
},
});

return bookmark;
} catch (err) {
throw new NotFound(Message.BOOKMARK_NOTFOUND);
}
Expand Down
1 change: 1 addition & 0 deletions backend/src/errors/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default {
TOKEN_MALFORMED: '로그인이 필요합니다.',
BOOK_NOTFOUND: '일치하는 책이 없습니다.',
BOOK_INVALID_TITLE: '책 제목이 비어있습니다.',
BOOKMARK_ALREADY_EXISTS: '이미 북마크된 책입니다',
BOOKMARK_NOTFOUND: '북마크된 책이 아닙니다.',
ARTICLE_NOTFOUND: '일치하는 글이 없습니다.',
ARTICLE_INVALID_TITLE: '글 제목이 비어있습니다.',
Expand Down
8 changes: 7 additions & 1 deletion backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ const startServer = async () => {

await loader(app);

app.listen(+process.env.PORT, process.env.HOST, () => {
const server = app.listen(+process.env.PORT, process.env.HOST, () => {
if (process.send) process.send('ready');

console.log(`Server listening on port: ${process.env.PORT}`);
});

process.on('SIGINT', () => {
server.close(() => process.exit(0));
});
};

startServer();
6 changes: 6 additions & 0 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
}
}
],
"jsx-a11y/label-has-associated-control": [
"error",
{
"labelAttributes": ["htmlFor"]
}
],
"prettier/prettier": ["error", { "endOfLine": "auto" }],
"react/react-in-jsx-scope": "off",
"react/jsx-filename-extension": ["error", { "extensions": [".ts", ".tsx"] }],
Expand Down
11 changes: 11 additions & 0 deletions frontend/.lighthouserc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ module.exports = {
startServerCommand: 'npm run start',
url: ['http://localhost:3000'],
numberOfRuns: 3,
settings: {
onlyCategories: ['performance', 'accessibility', 'best-practices', 'seo'],
},
},
assert: {
assertions: {
'categories:performance': ['warn', { minScore: 0.9, aggregationMethod: 'median-run' }],
'categories:accessibility': ['warn', { minScore: 1, aggregationMethod: 'pessimistic' }],
'categories:best-practices': ['warn', { minScore: 1, aggregationMethod: 'pessimistic' }],
'categories:seo': ['warn', { minScore: 1, aggregationMethod: 'pessimistic' }],
},
},
upload: {
target: 'filesystem',
Expand Down
10 changes: 10 additions & 0 deletions frontend/atoms/curBookmarkedBookList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { atom } from 'recoil';

import { IBookScraps } from '@interfaces';

const curBookmarkedBookListState = atom<IBookScraps[]>({
key: 'curBookmarkedBookListState',
default: [],
});

export default curBookmarkedBookListState;
9 changes: 3 additions & 6 deletions frontend/components/common/Book/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,9 @@ interface BookProps {
}

export default function Book({ book }: BookProps) {
const { id, title, user, scraps, _count, bookmarks } = book;
const { handleBookmarkClick, curBookmarkCnt, curBookmarkId } = useBookmark(
bookmarks.length ? bookmarks[0].id : null,
_count.bookmarks,
id
);
const { id, title, user, scraps } = book;
const { handleBookmarkClick, curBookmarkCnt, curBookmarkId } = useBookmark(book);

return (
// 수정모드일때만 아래 onclick이 실행되도록 수정해야함 -> 민형님 작업 후
<BookWrapper>
Expand Down
10 changes: 7 additions & 3 deletions frontend/components/common/Content/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ export const ContentTitle = styled.h1`
margin-bottom: 16px;
font-size: 24px;
font-weight: 700;
display: flex;
align-items: center;
height: 35px;
`;

export const ContentBody = styled.div`
padding-top: 10px;
> * {
line-height: 2;
font-weight: 400;
Expand Down Expand Up @@ -68,6 +69,10 @@ export const ContentBody = styled.div`
}
}
em {
font-style: italic;
}
blockquote {
margin: 24px 0;
padding: 24px 16px;
Expand All @@ -86,7 +91,6 @@ export const ContentBody = styled.div`
border-radius: 4px;
font-family: 'consolas';
font-size: 16px;
font-weight: 700;
line-height: 1.4;
code {
Expand Down
7 changes: 3 additions & 4 deletions frontend/components/common/DragDrop/ListItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,17 +84,16 @@ export const ListItem = memo(function Scrap({
const handleMinusBtnClick = () => {
// 원본글이 아니면 스크랩에서만 삭제
// 원본글이면 실제로 삭제
if (window.confirm('글을 책에서 삭제하시겠습니까?')) {
if (isOriginal) {
if (isOriginal) {
if (window.confirm('이 글은 원본 글입니다. 정말로 삭제하시겠습니까?')) {
setEditInfo({
...editInfo,
deletedArticle: [...editInfo.deletedArticle, id],
deletedScraps: [...editInfo.deletedScraps, scrapId],
});
setScraps(scraps.filter((v) => v.article.id !== id));
return;
}

} else if (window.confirm('글을 책에서 삭제하시겠습니까?')) {
setEditInfo({
...editInfo,
deletedScraps: [...editInfo.deletedScraps, scrapId],
Expand Down
3 changes: 2 additions & 1 deletion frontend/components/common/DragDrop/ListItem/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export const MinusButton = styled.div`
display: flex;
justify-content: center;
align-items: center;
width: 30px;
width: 25px;
height: 25px;
border-radius: 50%;
background-color: var(--red-color);
`;
Expand Down
6 changes: 4 additions & 2 deletions frontend/components/common/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import FooterContent from './styled';
import { FooterContent, FooterLink } from './styled';

function Footer() {
return (
<footer>
<FooterContent>
<div>Copyright © 2022 by Knoticle Team</div>
<div>Github</div>
<div>
<FooterLink href="https://github.com/boostcampwm-2022/web01-knoticle">Github</FooterLink>
</div>
</FooterContent>
</footer>
);
Expand Down
14 changes: 13 additions & 1 deletion frontend/components/common/Footer/styled.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import Link from 'next/link';

import styled from 'styled-components';

import { FlexCenter } from '@styles/layout';

const FooterContent = styled(FlexCenter)`
export const FooterContent = styled(FlexCenter)`
flex-direction: column;
padding: 50px;
gap: 8px;
color: var(--grey-01-color);
font-size: 14px;
`;

export const FooterLink = styled(Link)`
color: var(--primary-color);
font-size: 14px;
:hover {
color: var(--primary-color);
text-decoration-line: underline;
}
`;

export default FooterContent;
24 changes: 14 additions & 10 deletions frontend/components/common/GNB/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import dynamic from 'next/dynamic';
import Link from 'next/link';

import { useState } from 'react';
Expand All @@ -8,13 +9,14 @@ import ArticleIcon from '@assets/ico_article.svg';
import PersonIcon from '@assets/ico_person.svg';
import SearchIcon from '@assets/ico_search.svg';
import signInStatusState from '@atoms/signInStatus';
import SignInModal from '@components/auth/SignInModal';
import SignUpModal from '@components/auth/SignUpModal';
import Modal from '@components/common/Modal';

import { GNBbar, Icon, IconsContainer, Logo, LogoWrapper } from './styled';

export default function GNB() {
const Modal = dynamic(() => import('@components/common/Modal'));
const SignInModal = dynamic(() => import('@components/auth/SignInModal'));
const SignUpModal = dynamic(() => import('@components/auth/SignUpModal'));

const [isModalShown, setModalShown] = useState(false);
const [currentModalState, setCurrentModalState] = useState<'SignIn' | 'SignUp'>('SignIn');
const signInStatus = useRecoilValue(signInStatusState);
Expand All @@ -33,13 +35,15 @@ export default function GNB() {
<Logo href="/">knoticle</Logo>
</LogoWrapper>
<IconsContainer>
<Link href="/editor">
<Icon
src={ArticleIcon}
alt="Article Icon"
isvisible={(signInStatus.id !== 0).toString()}
/>
</Link>
{signInStatus.id !== 0 && (
<Link href="/editor">
<Icon
src={ArticleIcon}
alt="Article Icon"
isvisible={(signInStatus.id !== 0).toString()}
/>
</Link>
)}

{signInStatus.id !== 0 ? (
<Link href={`/study/${signInStatus.nickname}`}>
Expand Down
45 changes: 27 additions & 18 deletions frontend/components/edit/Editor/core/theme.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
import { tags } from '@lezer/highlight';
import { tags as t } from '@lezer/highlight';

export default function theme() {
const highlightStyle = HighlightStyle.define([
{ tag: tags.heading1, fontSize: '24px', fontWeight: '700' },
{ tag: tags.heading2, fontSize: '20px', fontWeight: '700' },
{ tag: tags.heading3, fontSize: '18px', fontWeight: '700' },
{ tag: tags.link, textDecoration: 'underline' },
{ tag: tags.strikethrough, textDecoration: 'line-through' },
{ tag: tags.invalid, color: '#cb2431' },
{ tag: [tags.string, tags.meta, tags.regexp], color: '#222222', fontWeight: 700 },
{ tag: [tags.heading, tags.strong], color: '#222222', fontWeight: '700' },
{ tag: [tags.emphasis], color: '#24292e', fontStyle: 'italic' },
{ tag: [tags.comment, tags.bracket], color: '#6a737d' },
{ tag: [tags.className, tags.propertyName], color: '#6f42c1' },
{ tag: [tags.variableName, tags.attributeName, tags.number, tags.operator], color: '#005cc5' },
{ tag: [tags.keyword, tags.typeName, tags.typeOperator, tags.typeName], color: '#d73a49' },
{ tag: [tags.name, tags.quote], color: '#22863a' },
{ tag: [tags.deleted], color: '#b31d28', backgroundColor: 'ffeef0' },
{ tag: [tags.atom, tags.bool, tags.special(tags.variableName)], color: '#e36209' },
{ tag: [tags.url, tags.escape, tags.regexp, tags.link], color: '#222222' },
{ tag: t.heading1, fontSize: '24px', fontWeight: '700' },
{ tag: t.heading2, fontSize: '20px', fontWeight: '700' },
{ tag: t.heading3, fontSize: '18px', fontWeight: '700' },
{ tag: t.link, textDecoration: 'underline' },
{ tag: t.strikethrough, textDecoration: 'line-through' },
{ tag: t.invalid, color: '#cb2431' },
{ tag: t.name, color: '#22863a' },
{ tag: t.emphasis, color: '#24292e', fontStyle: 'italic' },
{ tag: t.deleted, color: '#b31d28', backgroundColor: '#ffeef0' },
{ tag: [t.heading, t.strong, t.meta], color: '#222222', fontWeight: '700' },
{ tag: [t.url, t.escape, t.regexp, t.link, t.quote], color: '#222222' },
{ tag: t.comment, color: '#6a737d', fontFamily: 'consolas' },
{
tag: [t.attributeName, t.className, t.propertyName, t.function(t.definition(t.variableName))],
color: '#6f42c1',
fontFamily: 'consolas',
},
{ tag: [t.operator, t.variableName, t.bracket], color: '#222222', fontFamily: 'consolas' },
{ tag: [t.string], color: '#032f62', fontFamily: 'consolas' },
{ tag: [t.number], color: '#005cc5', fontFamily: 'consolas' },
{
tag: [t.keyword, t.typeName, t.typeOperator, t.typeName, t.atom, t.moduleKeyword],
color: '#d73a49',
fontFamily: 'consolas',
},
{ tag: [t.bool, t.special(t.variableName)], color: '#005cc5', fontFamily: 'consolas' },
]);

return [syntaxHighlighting(highlightStyle)];
Expand Down
Loading

0 comments on commit c9749e7

Please sign in to comment.