-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from youngwan2/feature/views
feature/실시간 인기 명언 조회 기능 추가
- Loading branch information
Showing
13 changed files
with
194 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
'use client' | ||
import ReplaceMessageCard from "@/components/UI/common/ReplaceMessageCard" | ||
import PopularQuoteList from "@/components/UI/quote/PopularQuoteList" | ||
import { useSwrFetch } from "@/utils/swr" | ||
import toast from "react-hot-toast" | ||
import { HiRefresh } from "react-icons/hi" | ||
|
||
export interface QuoteType { | ||
quote_id: number | ||
quote: string | ||
author: string | ||
job: string | ||
category: string | ||
views: number | ||
} | ||
export default function PopularQuotesPage() { | ||
|
||
const url = '/api/quotes/populars' | ||
const { data, mutate } = useSwrFetch(url,1000 * 60, false) | ||
const { quotes } = data || { quotes: null } | ||
|
||
async function reload() { | ||
toast.promise(mutate(), { | ||
loading:'새로운 데이터를 불러오는 중입니다.', | ||
success:'최신 데이터로 갱신되었습니다.', | ||
error:'서버 문제로 데이터 조회에 실패하였습니다.' | ||
}) | ||
} | ||
|
||
if (!quotes) return <ReplaceMessageCard childern='데이터를 조회중 입니다..' /> | ||
return ( | ||
<article> | ||
<h2 className="flex flex-col justify-center items-center text-[1.5em] p-[10px] text-center text-white max-w-[250px] mx-auto bg-gradient-to-b from-[transparent] to-[#00000033] shadow-[0_9px_2px_0_rgba(0,0,0,0.5)] rounded-[5px] my-[2em] perspective-500 "> | ||
실시간 인기명언 <span> Top 100</span> | ||
</h2> | ||
<button className="absolute flex items-center left-[50%] translate-x-[-50%] text-white hover:cursor-pointer z-[20] hover:text-[gold] " onClick={reload}><HiRefresh className='mx-[3px]' />새로고침 </button> | ||
<PopularQuoteList quotes={quotes} /> | ||
</article> | ||
|
||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { HTTP_CODE } from "@/app/http-code" | ||
import { openDB } from "@/utils/connect"; | ||
import { NextResponse } from "next/server" | ||
|
||
export async function GET() { | ||
|
||
try { | ||
const db = await openDB(); | ||
|
||
const selectQuery = ` | ||
SELECT * | ||
FROM quotes A | ||
INNER JOIN views B ON A.quote_id = B.quote_id | ||
ORDER BY B.views DESC, A.quote_id ASC | ||
` | ||
|
||
const results = await db.query(selectQuery) | ||
const items = results.rows | ||
|
||
return NextResponse.json({...HTTP_CODE.OK,quotes:items}) | ||
|
||
} catch (error) { | ||
console.error('/api/quotes/populars', error) | ||
return NextResponse.json(HTTP_CODE.INTERNAL_SERVER_ERROR) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { QuoteType } from "@/app/(quotes)/quotes/populars/page"; | ||
import TtsButton from "../common/TtsButton"; | ||
import QuoteViews from "./QuoteViews"; | ||
import useTTS from "@/custom/useTTS"; | ||
import { HiSpeakerphone } from "react-icons/hi"; | ||
import QuoteProgress from "./QuoteProgress"; | ||
import QuoteDetailMoveButton from "./QuoteDetailMoveButton"; | ||
import { viewCounter } from "@/services/data/patch"; | ||
import { MouseEvent } from "react"; | ||
import toast from "react-hot-toast"; | ||
import { useRouter } from "next/navigation"; | ||
import gsap from "gsap/all"; | ||
|
||
interface PropsType { | ||
quoteInfo: QuoteType | ||
} | ||
export default function PopularQuoteCard({ quoteInfo }: PropsType) { | ||
|
||
const { isPlaying, progress, readText, setText } = useTTS() | ||
|
||
const {push} = useRouter() | ||
|
||
const onClickSetText = (quote: string | null) => { | ||
if (!quote) return | ||
setText(quote) | ||
} | ||
|
||
// 상세 페이지 이동 | ||
const onClickPushAnimation = (e: MouseEvent<HTMLButtonElement>) => { | ||
viewCounter(quoteInfo.quote_id) | ||
|
||
const tl = gsap.timeline() | ||
tl.to(e.currentTarget.parentElement, { | ||
scale: 0.8, | ||
duration: 1, | ||
onStart() { | ||
toast('✈ 잠시후, 디테일 명언 카드 페이지로 이동합니다.', { | ||
className: 'font-sans' | ||
}) | ||
}, | ||
}) | ||
tl.to(e.currentTarget.parentElement, { | ||
scale: 0.5, | ||
rotateY: 10, | ||
filter: 'blur(1px)', | ||
borderTopLeftRadius: '5%', | ||
borderBottomLeftRadius: '5%', | ||
boxShadow: '-100px 0 100px 0 tomato' | ||
|
||
}) | ||
tl.to(e.currentTarget.parentElement, { | ||
x: window.innerWidth, | ||
opacity: 0, | ||
}) | ||
tl.to(e.currentTarget.parentElement, { | ||
onComplete() { | ||
push(`/quotes/authors/${quoteInfo.author}/${quoteInfo.quote_id}`) | ||
tl.kill() | ||
}, | ||
}) | ||
} | ||
|
||
return ( | ||
<li key={quoteInfo.quote_id} | ||
className={`visible shadow-[inset_0_0_0_3px_white] rounded-[10px] w-[95%] my-[1em] max-w-[500px] bg-transparent px-[15px] py-[35px] mx-auto relative hover:bg-[#d5d5d533]`}> | ||
<blockquote className="text-white mt-[1em] "> | ||
<p>{readText || quoteInfo.quote}</p> | ||
<span className="block font-bold mt-[1em] text-right"> | ||
- {quoteInfo.author} - | ||
</span> | ||
</blockquote> | ||
<TtsButton quote={quoteInfo.quote} onClickSetText={onClickSetText} className='absolute right-[3.3em] top-[0.429em] decoration-wavy decoration-[tomato] underline text-[1.1em] hover:shadow-[inset_0_0_0_1px_tomato] p-[4px] py-[5px] text-white ' /> | ||
<QuoteDetailMoveButton onClickDetailMove={onClickPushAnimation} /> | ||
<QuoteProgress progress={progress} /> | ||
<QuoteViews viewCount={quoteInfo.views} /> | ||
|
||
<p>{isPlaying | ||
? <span className='text-[1.05em] animate-pulse absolute bottom-2 left-2 text-white rounded-[10px] p-[2px] px-[7px] flex items-center'><HiSpeakerphone color='gold' className='mr-[5px]' /> {progress}/100</span> | ||
: <span className='text-[1.05em] animate-none absolute bottom-2 left-2 text-white rounded-[10px] p-[2px] px-[7px]'></span>}</p> | ||
|
||
</li> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
'use client' | ||
import { QuoteType } from "@/app/(quotes)/quotes/populars/page" | ||
import ReplaceMessageCard from "../common/ReplaceMessageCard" | ||
import PopularQuoteCard from "./PopularQuoteCard" | ||
|
||
interface PropsType { | ||
quotes: QuoteType[] | ||
} | ||
export default function PopularQuoteList({ quotes }: PropsType) { | ||
|
||
|
||
if (!quotes || quotes?.length < 1) return <ReplaceMessageCard childern='데이터를 조회중입니다..' /> | ||
return ( | ||
<ul className=" mt-[1em] pt-[2em] flex flex-col flex-wrap w-full perspective-500 transform-style-3d"> | ||
{quotes.map(quoteInfo => | ||
<PopularQuoteCard quoteInfo={quoteInfo} key={quoteInfo.quote_id}/> | ||
)} | ||
</ul> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
|
||
|
||
|
||
interface PropsType { | ||
[key: string]: string | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters