Skip to content

Commit

Permalink
add create qna api
Browse files Browse the repository at this point in the history
  • Loading branch information
hyehyeongjo committed Jun 26, 2021
1 parent 333070c commit 3e1d328
Show file tree
Hide file tree
Showing 26 changed files with 7,130 additions and 896 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
NEXT_PUBLIC_SENTRY_TOKEN="https://[email protected]/5422171"
NEXT_PUBLIC_GOOGLE_CLIENT_ID="184303225237-v43ete082uljlk0a3hknnp5u91hkj7n5.apps.googleusercontent.com"
NEXT_PUBLIC_GITHUB_CLIENT_ID="bea156fb6e412de32c9d"
NEXT_PUBLIC_SERVER_URL="http://3.37.67.246"
NEXT_PUBLIC_SERVER_URL="http://3.36.53.125"
9 changes: 9 additions & 0 deletions asset/images/svg/EditorBold.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions asset/images/svg/LockIcon.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';

export default function LockIcon({ onClick }) {
export default function LockIcon({ onClick, lock }) {
return (
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg" onClick={onClick}>
<path fillRule="evenodd" clipRule="evenodd" d="M19.0278 2H12.5442L2 12.5419V27.4558L12.5442 38H18.9706V37H12.9584L3 27.0416V12.9562L12.9583 3H19.0278V2ZM20.9722 3H27.0417L37 12.9562V27.0416L27.0416 37H20.915V38H27.4558L38 27.4558V12.5419L27.4558 2H20.9722V3ZM22.2973 10.5H17.7027L14.5 14.1449V16H15.5V14.5219L18.1552 11.5H21.8448L24.5 14.5219V18H12V24.482L16.6863 29H23.3137L28 24.482V18H25.5V14.1449L22.2973 10.5ZM24.5 19H13V24.0571L17.0898 28H22.9102L27 24.0571V19H25.5H24.5ZM20.5 22V25H19.5V22H20.5Z" fill="#DCDCDC" />
<path fillRule="evenodd" clipRule="evenodd" d="M19.0278 2H12.5442L2 12.5419V27.4558L12.5442 38H18.9706V37H12.9584L3 27.0416V12.9562L12.9583 3H19.0278V2ZM20.9722 3H27.0417L37 12.9562V27.0416L27.0416 37H20.915V38H27.4558L38 27.4558V12.5419L27.4558 2H20.9722V3ZM22.2973 10.5H17.7027L14.5 14.1449V16H15.5V14.5219L18.1552 11.5H21.8448L24.5 14.5219V18H12V24.482L16.6863 29H23.3137L28 24.482V18H25.5V14.1449L22.2973 10.5ZM24.5 19H13V24.0571L17.0898 28H22.9102L27 24.0571V19H25.5H24.5ZM20.5 22V25H19.5V22H20.5Z" fill={lock ? '#AA00FF' : '#DCDCDC'} />
</svg>
);
}
8 changes: 8 additions & 0 deletions next.config.original.1618114020833.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ const nextConfig = {

const prod = process.env.NODE_ENV === 'production';

config.module.rules.push({ // 웹팩설정에 로더 추가함
test: /\.svg$/,
issuer: {
test: /\.(js|ts)x?$/,
},
use: ['@svgr/webpack'],
});

config.plugins.push(new webpack.IgnorePlugin(/(?:\/tests|__mocks)/));
// moment locale size is too big
config.plugins.push(
Expand Down
5,935 changes: 5,067 additions & 868 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"dependencies": {
"@babel/runtime": "^7.14.0",
"@next/bundle-analyzer": "^10.0.6",
"@svgr/webpack": "^5.5.0",
"@toast-ui/editor-plugin-code-syntax-highlight": "^3.0.0-alpha.0",
"@toast-ui/react-editor": "^2.5.3",
"@zeit/next-source-maps": "0.0.3",
Expand All @@ -38,8 +39,8 @@
"react-google-login": "^5.2.2",
"react-toastify": "^7.0.4",
"sass": "^1.32.6",
"serverless": "^2.35.0",
"tailwindcss": "^2.0.3"
"serverless": "^2.48.0",
"tailwindcss": "^2.2.2"
},
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.13.0",
Expand Down
4 changes: 4 additions & 0 deletions public/images/svg/EditorBlockQuote.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorBold.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorCode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions public/images/svg/EditorHeading.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions public/images/svg/EditorHr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorImage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorItalic.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorLink.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorOrderedList.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorRedo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorSnippet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorUnOrderedList.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/svg/EditorUndo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 91 additions & 1 deletion src/components/Editor/TextEditor.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import dynamic from 'next/dynamic';
import React, {
forwardRef, useCallback, useRef, useState,
forwardRef, useCallback, useEffect, useRef, useState,
} from 'react';

const isServer = typeof window === 'undefined';
const Editor = dynamic(() => import('./WrappedEditor'), { ssr: false });
const EditorWithForwardedRef = forwardRef((props, ref) => (
<Editor {...props} forwardedRef={ref} />
Expand All @@ -13,6 +14,70 @@ export default function TextEditor(props) {
initialValue, previewStyle, height, initialEditType, useCommandShortcut, content, setContent,
} = props;

const imagePath = '/images/svg/';

const toolbarItems = [
{
command: 'Bold',
backgroundImg: `${imagePath}EditorBold.svg`,
},
{
command: 'Italic',
backgroundImg: `${imagePath}EditorItalic.svg`,
},
{
command: 'AddLink',
backgroundImg: `${imagePath}EditorLink.svg`,
},
{
command: 'Blockquote',
backgroundImg: `${imagePath}EditorBlockQuote.svg`,
},
{
command: 'CodeBlock',
backgroundImg: `${imagePath}EditorCode.svg`,
},
{
command: 'AddImage',
backgroundImg: `${imagePath}EditorImage.svg`,
},
{
command: 'Code',
backgroundImg: `${imagePath}EditorSnippet.svg`,
},
{
command: 'OL',
backgroundImg: `${imagePath}EditorOrderedList.svg`,
},
{
command: 'UL',
backgroundImg: `${imagePath}EditorUnOrderedList.svg`,
},
{
command: 'Heading',
backgroundImg: `${imagePath}EditorHeading.svg`,
},
{
command: 'HR',
backgroundImg: `${imagePath}EditorHr.svg`,
}
];

const createButton = () => {
if (!isServer) {
const el = document.createElement('button');

el.addEventListener("click", () => {
const editor = editorRef.current.getInstance();
console.log("editor", editor.commandManager._mdCommand._keys);
})

el.innerHTML = '';

return el;
}
};

const editorRef = useRef();
const handleChange = useCallback(() => {
if (!editorRef.current) {
Expand All @@ -25,6 +90,30 @@ export default function TextEditor(props) {
setContent(valueType === 'markdown' ? instance.getMarkdown() : instance.getHtml());
}, [props, editorRef, content, setContent]);

useEffect(() => {
if (editorRef && editorRef.current) {
const toolbar = editorRef.current.getInstance().getUI().getToolbar();

toolbar.removeAllItems();

toolbarItems.forEach(tool => {
const command = tool.command.charAt(0).toUpperCase() + tool.command.slice(1);

toolbar.addItem({
type: 'button',
options: {
className: tool.command,
command: command,
tooltip: command,
el: createButton(),
text: '',
style: `background-image: url(${tool.backgroundImg});`,
},
});
})
}
}, [editorRef.current]);

return (
<div className="editor">
<EditorWithForwardedRef
Expand All @@ -36,6 +125,7 @@ export default function TextEditor(props) {
useCommandShortcut={useCommandShortcut || true}
ref={editorRef}
onChange={handleChange}
// toolbarItems={toolbarItemsOps}
/>
</div>
);
Expand Down
44 changes: 35 additions & 9 deletions src/components/QuestionItem.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { BookmarkIcon, ThumbsUpIcon } from '@/svg';
import dayjs from 'dayjs';
import { handleAsync } from '@/utils/mobx';
import { Qna } from '@/utils/api';
import Tag from './Tag';
import styles from './QuestionItem.module.scss';

Expand All @@ -18,20 +20,44 @@ const ActionButton = ({
const QuestionItem = (props) => {
const {
question: {
comments, tags, title, qnaType, createdAt, liked, bookmarked, user,
comments, tags, title, qnaType, createdAt, liked, bookmarked, user, id, likes,
},
} = props;

const [curLiked, setCurLiked] = useState(liked);
const [curBookmarked, setCurBookmarked] = useState(bookmarked);
const [curBookmark, setCurBookmark] = useState(bookmarked);
const [curLikes, setCurLikes] = useState(likes);

const onBookmark = useCallback(async () => {
const [res, err] = await handleAsync(Qna[curBookmark ? 'unbookmark' : 'bookmark']({ qnaId: id }));
if (res) {
setCurBookmark(!curBookmark);
} else {
console.log(err);
}
}, [bookmarked, curBookmark, setCurBookmark]);

const onLike = useCallback(async () => {
const [res, err] = await handleAsync(Qna[curLiked ? 'unlike' : 'like']({ qnaId: id }));
if (res) {
curLiked ? setCurLikes((prev) => prev - 1) : setCurLikes((prev) => prev + 1);
setCurLiked(!curLiked);
} else {
console.log(err);
}
}, [liked, curLiked, setCurLiked, likes, curLikes, setCurLikes]);

useEffect(() => {
setCurBookmarked(bookmarked);
}, [curBookmarked]);
setCurBookmark(bookmarked);
}, [bookmarked]);

useEffect(() => {
setCurLiked(liked);
}, [curLiked]);
}, [liked]);

useEffect(() => {
setCurLikes(likes);
}, [likes]);

return (
<div className={styles.questionItem}>
Expand Down Expand Up @@ -61,12 +87,12 @@ const QuestionItem = (props) => {
</div>
</div>
<div className={styles.questionItem__actions}>
<ActionButton className={curLiked ? 'active' : undefined} onClick={() => setCurLiked(!curLiked)}>
<ActionButton className={curLiked ? 'active' : undefined} onClick={onLike}>
<ThumbsUpIcon />
<span className={styles.actionButton__thumbsUpCount}>0</span>
<span className={styles.actionButton__thumbsUpCount}>{curLikes}</span>
</ActionButton>

<ActionButton className={curLiked ? 'active' : undefined} onClick={() => setCurBookmarked(!curBookmarked)}>
<ActionButton className={curBookmark ? 'active' : undefined} onClick={onBookmark}>
<BookmarkIcon />
</ActionButton>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useStore } from '../modules';
import '../utils/styles/Toast.scss';
import '../utils/styles/global.scss';
import 'codemirror/lib/codemirror.css';
import '@toast-ui/react-editor/node_modules/@toast-ui/editor/dist/toastui-editor.css';
import '../utils/styles/toastui-editor.css';

const App = ({ Component, appProps, pageProps }) => {
const { pathname } = useRouter();
Expand Down
Loading

0 comments on commit 3e1d328

Please sign in to comment.