Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
8e9ee56
📦 package: update tailwindcss [KOBG-10]
minzee09 Aug 6, 2025
2c8951e
💄 UI: add fonts [KOBG-10]
minzee09 Aug 6, 2025
d94fc63
💄 UI: add colors to global css file [KOBG-10]
minzee09 Aug 6, 2025
5f6d00d
💬 comment: modify design system wording [KOBG-10]
minzee09 Aug 6, 2025
e808fdd
💄 UI: add fonts to globals [KOBG-10]
minzee09 Aug 14, 2025
f689ddd
📝 docs: modify PR template [KOBG-5]
minzee09 Aug 14, 2025
cabb1af
💄 UI: add google icon svg [KOBG-11]
minzee09 Aug 14, 2025
5c78cb1
✨ feat: add googleLoginBtn component [KOBG-11]
minzee09 Aug 14, 2025
5d97dc2
💄 UI: add onboarding [KOBG-11]
minzee09 Aug 14, 2025
4cf8cd2
💄 UI: add login [KOBG-11]
minzee09 Aug 14, 2025
e7cddb0
💄 UI: add chevron-left svg [KOBG-11]
minzee09 Aug 14, 2025
40883f3
✨ feat: add topAppBar component
minzee09 Aug 14, 2025
57a1c15
💄 UI: add designed logo [KOBG-11]
minzee09 Aug 15, 2025
6f9ddb1
📦 package: add framer-motion [KOBG-11]
minzee09 Aug 15, 2025
ee7af2f
🔥 remove: logo layout [KOBG-11]
minzee09 Aug 15, 2025
0563b76
✨ feat: add Logo component [KOBG-11]
minzee09 Aug 15, 2025
85da693
✨ feat: add splash screen [KOBG-11]
minzee09 Aug 15, 2025
a67f658
✨ feat: add login screen [KOBG-11]
minzee09 Aug 15, 2025
89f749c
✨ feat: add onClick props to btn [KOBG-11]
minzee09 Aug 15, 2025
b67d4fe
✨ feat: add route constants [KOBG-11]
minzee09 Aug 15, 2025
6c72528
♻️ refactor: add route constants [KOBG-11]
minzee09 Aug 15, 2025
efeedce
✨ feat: add google login util
minzee09 Aug 15, 2025
7bf4667
🎨 style: update format in login screen [KOBG-11]
minzee09 Aug 15, 2025
953534b
✨ feat: add google login handler [KOBG-11]
minzee09 Aug 15, 2025
e106e84
✨ feat: add go back button to TopAppBar component [KOBG-11]
minzee09 Aug 16, 2025
4f6d4ad
✨ feat: add sign step routes [KOBG-11]
minzee09 Aug 16, 2025
96d1894
💄 UI: add fade in motion component [KOBG-11]
minzee09 Aug 16, 2025
64cb8bc
💄 UI: delete padding [KOBG-11]
minzee09 Aug 16, 2025
165958d
✨ feat: add title text component [KOBG-11]
minzee09 Aug 16, 2025
7170314
✨ feat: add progress bar component [KOBG-11]
minzee09 Aug 16, 2025
e8e6650
💄 UI: modify height [KOBG-11]
minzee09 Aug 16, 2025
c3cdb21
✨ feat: modify route [KOBG-11]
minzee09 Aug 16, 2025
0796348
✨ feat: add signin screen [KOBG-11]
minzee09 Aug 16, 2025
f646cf5
📦 package: add zustand [KOBG-11]
minzee09 Aug 16, 2025
3110579
💄 UI: add chevron icons [KOBG-11]
minzee09 Aug 16, 2025
81451be
✨ feat: add language selection dropdown component [KOBG-11]
minzee09 Aug 16, 2025
03e4e35
✨ feat: add language global state [KOBG-11]
minzee09 Aug 16, 2025
eb759a4
💄 UI: add disabled style to dropdown [KOBG-11]
minzee09 Aug 16, 2025
635ed61
🎨 style: modify component folder name [KOBG-11]
minzee09 Aug 16, 2025
6a8b6bb
💄 UI: add margin [KOBG-11]
minzee09 Aug 16, 2025
e3a3ec0
✨ feat: add persist middleware to save in local storage [KOBG-11]
minzee09 Aug 16, 2025
6f518b7
✨ feat: add onChange prop to dropdown component [KOBG-11]
minzee09 Aug 16, 2025
e40544d
📦 package: add iso-639-1 [KOBG-11]
minzee09 Aug 18, 2025
06725ee
💄 UI: add icons [KOBG-11]
minzee09 Aug 18, 2025
a3d5662
✨ feat: add bottom sheet component [KOBG-11]
minzee09 Aug 18, 2025
a53cd94
🎨 style: modify file path [KOBG-11]
minzee09 Aug 18, 2025
19ce927
💄 UI: add all languages dropdown [KOBG-11]
minzee09 Aug 18, 2025
5f0146b
✨ feat: add language codes constants [KOBG-11]
minzee09 Aug 18, 2025
b87d4fb
💄 UI: add button component [KOBG-11]
minzee09 Aug 18, 2025
6ab9a7a
✨ feat: add step1 of signin screen [KOBG-11]
minzee09 Aug 18, 2025
2daad5c
✨ feat: modify next page route [KOBG-11]
minzee09 Aug 18, 2025
47660b2
💄 UI: add icons [KOBG-11]
minzee09 Aug 18, 2025
ed3d041
💄 UI: add scrollbar-hide in globals.css [KOBG-11]
minzee09 Aug 18, 2025
194c68e
✨ feat: add ordinal util [KOBG-11]
minzee09 Aug 18, 2025
bea3ae1
💄 UI: add text field components [KOBG-11]
minzee09 Aug 18, 2025
02586d9
✨ feat: modify props for TitleText component [KOBG-11]
minzee09 Aug 18, 2025
30d4579
✨ feat: add stores [KOBG-11]
minzee09 Aug 18, 2025
020ca2b
✨ feat: add school, voice constants [KOBG-11]
minzee09 Aug 18, 2025
25d6787
💄 UI: add school select dropdown component [KOBG-11]
minzee09 Aug 18, 2025
e06c1c3
💄 UI: add select type button component [KOBG-11]
minzee09 Aug 18, 2025
edaa5fd
💄 UI: add character voice toggle btn component [KOBG-11]
minzee09 Aug 18, 2025
7385288
💄 UI: modify color [KOBG-11]
minzee09 Aug 18, 2025
88221de
💄 UI: add character text component [KOBG-11]
minzee09 Aug 18, 2025
15d76a9
✨ feat: update route constants [KOBG-11]
minzee09 Aug 18, 2025
548af15
✨ feat: add signin screens [KOBG-11]
minzee09 Aug 18, 2025
165531b
✨ feat: add voice selection screens [KOBG-11]
minzee09 Aug 18, 2025
2d3f201
💄 UI: add navigation bar component [KOBG-11]
minzee09 Aug 18, 2025
0c29eb7
✨ feat: add main screens
minzee09 Aug 18, 2025
f0b2917
🐛 bug: fix text color(black) not showing up in android [KOBG-11]
minzee09 Aug 18, 2025
8cfed75
💄 UI: add icons [KOBG-11]
minzee09 Aug 19, 2025
44b9135
✨ feat: add my-learning route constants [KOBG-11]
minzee09 Aug 19, 2025
8b59fb9
✨ feat: add step1 rating constants [KOBG-11]
minzee09 Aug 19, 2025
10ac0d5
💄 UI: update to add center text [KOBG-11]
minzee09 Aug 19, 2025
e0bac81
💄 UI: update button color props [KOBG-11]
minzee09 Aug 19, 2025
805274a
🐛 bug: modify router route [KOBG-11]
minzee09 Aug 19, 2025
a5b138e
✨ feat: add toast message component [KOBG-11]
minzee09 Aug 19, 2025
55420a7
✨ feat: add locales for my-learning tab [KOBG-11]
minzee09 Aug 19, 2025
fd40569
💄 UI: add textfield component [KOBG-11]
minzee09 Aug 19, 2025
3a8e616
✨ feat: add voice & keyboard btn component [KOBG-11]
minzee09 Aug 19, 2025
2fce623
💄 UI: add character text component [KOBG-11]
minzee09 Aug 19, 2025
edfcc2f
✨ feat: add level finder from param hook [KOBG-11]
minzee09 Aug 19, 2025
1bc79d9
💄 UI: add my-learning screen [KOBG-11]
minzee09 Aug 19, 2025
4ddaddf
✨ feat: add my-learning components [KOBG-11]
minzee09 Aug 19, 2025
7cd145f
✨ feat: add my-learning intro screen [KOBG-11]
minzee09 Aug 19, 2025
ddc894f
✨ feat: add custom text highlighter util [KOBG-11]
minzee09 Aug 19, 2025
d614c8c
✨ feat: add my-learning step1 screen [KOBG-11]
minzee09 Aug 19, 2025
76eb390
✨ feat: add my-learning intro2 screen [KOBG-11]
minzee09 Aug 19, 2025
b5ed397
💄 UI: add icons [KOBG-11]
minzee09 Aug 19, 2025
3f66177
💄 UI: modify to align middle [KOBG-11]
minzee09 Aug 19, 2025
6ffbc2e
✨ feat: add step3 of my-learning screen [KOBG-11]
minzee09 Aug 19, 2025
d297075
✨ feat: add ending of my-learning screen [KOBG-11]
minzee09 Aug 19, 2025
f0e46a6
✨ feat: add level roadmap layout [KOBG-11]
minzee09 Aug 19, 2025
cccbdb9
💄 UI: add active icons [KOBG-11]
minzee09 Aug 19, 2025
2eef827
✨ feat: add text json files [KOBG-11]
minzee09 Aug 19, 2025
c24ba3b
✨ feat: update routes constants [KOBG-11]
minzee09 Aug 19, 2025
4ac1e41
✨ feat: 사용자 현재 레벨에 자동 스크롤 기능 추가 [KOBG-11]
minzee09 Aug 20, 2025
58cdf3c
✨ feat: 음성 녹음 기능 추가 [KOBG-11]
minzee09 Aug 20, 2025
596ed5e
💄 UI: add icons [KOBG-11]
minzee09 Aug 20, 2025
08a2ef7
📦 package: add deepgram [KOBG-11]
minzee09 Aug 20, 2025
9414e16
✨ feat: add POST api for STT [KOBG-11]
minzee09 Aug 20, 2025
d811b4c
💄 UI: add swipe btn component [KOBG-11]
minzee09 Aug 20, 2025
537f9f2
🐛 bug: 마이크 모드로 전환 안되고 바로 음성 녹음되는 오류 해결 [KOBG-11]
minzee09 Aug 20, 2025
beb4e63
💄 UI: modify margin style [KOBG-11]
minzee09 Aug 20, 2025
eebcd79
✨ feat: 레벤슈타인 거리 알고리즘 유틸 함수 추가 [KOBG-11]
minzee09 Aug 20, 2025
fb4fa2d
✨ feat: add conversation screen [KOBG-11]
minzee09 Aug 20, 2025
c455543
💄 UI: add mypage styling [KOBG-11]
minzee09 Aug 20, 2025
f839ce0
✨ feat: STT 호출 커스텀 훅 추가 [KOBG-11]
minzee09 Aug 20, 2025
ae8c870
✨ feat: update rating logic [KOBG-11]
minzee09 Aug 20, 2025
d0599e5
💄 UI: modify main layout styles [KOBG-11]
minzee09 Aug 20, 2025
34dbe2e
✨ feat: add voice recognition to step1 [KOBG-11]
minzee09 Aug 20, 2025
0bfe5c1
✨ feat: add chatting stage [KOGB-11]
minzee09 Aug 20, 2025
cb388f6
✏️ typo: remove lint errors [KOBG-11]
minzee09 Aug 20, 2025
36c8054
💬 comment: 타입 에러 예외 주석 추가 [KOBG-11]
minzee09 Aug 20, 2025
909139e
Merge pull request #2 from 2025-KoBridge/feature/KOBG-11/UI-component
minzee09 Aug 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
## JIRA 이슈 키
<!--[JIRA-이슈번호]-->
## 🔑 JIRA 이슈 키
<!-- [KOBB-123] 한국어 레슨 별 조회 API -->

---

## JIRA 이슈 키
## ✒ 진행한 작업
- [x] 진행한 작업
- [x] 진행한 작업
- [x] 진행한 작업

---

## 💡 생겼던 문제 및 해결법
1️⃣ 요약
문제:
해결:
- 문제:
- 해결:

---

## 📢 아쉬운 부분 및 개선점
- ...

## 스크린샷
---

## 📚 개발에 참고한 자료 및 포인트
- 참고한 부분 요약 및 포인트
- link

## 아쉬운 부분 및 개선점
---

## 📸 스크린샷
- ...

## 개발에 참고한 자료 및 포인트
<!--참고한 부분 요약 및 포인트(link)-->
---
63 changes: 63 additions & 0 deletions app/api/deepgram/transcribe/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { createClient } from '@deepgram/sdk';
import { NextRequest, NextResponse } from 'next/server';

export const POST = async (req: NextRequest) => {
try {
const deepgram = createClient(process.env.DEEPGRAM_API_KEY!);

// JSON으로 Base64 보내는 경우
const contentType = req.headers.get('content-type') || '';
let audioBuffer: Buffer | null = null;

if (contentType.includes('application/json')) {
const { audioBase64 } = await req.json();
if (!audioBase64) {
return NextResponse.json(
{ error: 'No audioBase64 provided' },
{ status: 400 },
);
}
audioBuffer = Buffer.from(audioBase64, 'base64');
}
// FormData로 보내는 경우
else if (contentType.includes('multipart/form-data')) {
const formData = await req.formData();
const audioFile = formData.get('file') as File;
if (!audioFile) {
return NextResponse.json(
{ error: 'No audio file provided' },
{ status: 400 },
);
}
const arrayBuffer = await audioFile.arrayBuffer();
audioBuffer = Buffer.from(arrayBuffer);
} else {
return NextResponse.json(
{ error: 'Unsupported Content-Type' },
{ status: 400 },
);
}

// Deepgram STT
const { result } = await deepgram.listen.prerecorded.transcribeFile(
audioBuffer,
{
model: 'nova-2',
language: 'ko',
smart_format: true,
},
);

// 안전하게 transcript 추출
const transcript =
result?.results?.channels?.[0]?.alternatives?.[0]?.transcript || '';

return NextResponse.json({ transcript });
} catch (err) {
console.error('STT Error:', err);
return NextResponse.json(
{ error: err instanceof Error ? err.message : 'Unknown error' },
{ status: 500 },
);
}
};
Binary file modified app/favicon.ico
Binary file not shown.
178 changes: 171 additions & 7 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
@import "tailwindcss";

:root {
--font-gothic-a1: 'Gothic A1', sans-serif;
--font-mplus-2: 'M PLUS 2', sans-serif;
--font-noto-sc: 'Noto Sans SC',sans-serif;
--font-sans: var(--font-gothic-a1), var(--font-mplus-2), var(--font-noto-sc), system-ui, sans-serif;

--background: #ffffff;
--foreground: #171717;
}

@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
}

@media (prefers-color-scheme: dark) {
Expand All @@ -19,8 +21,170 @@
}
}

@theme inline {
/* 폰트 */
--font-sans: var(--font-sans);
--font-gothic: var(--font-gothic-a1);
--font-mplus: var(--font-mplus-2);
--font-noto: var(--font-noto-sc);

/* 컬러 */
--color-background: var(--background);
--color-foreground: var(--foreground);

--color-primary: #F7DD4A;
--color-primary-900: #FEF9DD;
--color-primary-800: #FBEFAC;
--color-primary-dimensional: #F6B831;

--color-secondary: #BFE2F3;
--color-secondary-400: #248EC1;
--color-secondary-300: #1C6E96;

--color-bg-solid: #E6F4FA;

--color-error: #F74A4A;
--color-error-dimensional: #D51111;

--color-black: #1B1B1B;
--color-black-70: rgba(27, 27, 27, 0.7);

--color-gray-300: #4F4F4F;
--color-gray-500: #828282;
--color-gray-700: #B5B5B5;
--color-gray-900: #E8E8E8;
--color-gray-950: #F2F2F2;

--color-white: #FEFEFE;
--color-white-70: rgba(254, 254, 254, 0.7);

/* H1 Bold */
--text-h1-bold: 24px;
--text-h1-bold--line-height: 160%;
--text-h1-bold--font-weight: 700;
--text-h1-bold--font-family: var(--font-gothic-a1);

/* H1 Regular */
--text-h1-regular: 24px;
--text-h1-regular--line-height: 160%;
--text-h1-regular--font-weight: 400;
--text-h1-regular--font-family: var(--font-gothic-a1);

/* H2 Bold */
--text-h2-bold: 20px;
--text-h2-bold--line-height: 160%;
--text-h2-bold--font-weight: 700;
--text-h2-bold--font-family: var(--font-gothic-a1);

/* H2 Regular */
--text-h2-regular: 20px;
--text-h2-regular--line-height: 160%;
--text-h2-regular--font-weight: 400;
--text-h2-regular--font-family: var(--font-gothic-a1);

/* H3 Bold */
--text-h3-bold: 18px;
--text-h3-bold--line-height: 160%;
--text-h3-bold--font-weight: 700;
--text-h3-bold--font-family: var(--font-gothic-a1);

/* H3 Regular */
--text-h3-regular: 18px;
--text-h3-regular--line-height: 160%;
--text-h3-regular--font-weight: 400;
--text-h3-regular--font-family: var(--font-gothic-a1);

/* Body1 Bold */
--text-bd1-bold: 16px;
--text-bd1-bold--line-height: 160%;
--text-bd1-bold--font-weight: 700;
--text-bd1-bold--font-family: var(--font-gothic-a1);

/* Body1 Regular */
--text-bd1-regular: 16px;
--text-bd1-regular--line-height: 160%;
--text-bd1-regular--font-weight: 400;
--text-bd1-regular--font-family: var(--font-gothic-a1);

/* Body2 Bold */
--text-bd2-bold: 14px;
--text-bd2-bold--line-height: 160%;
--text-bd2-bold--font-weight: 700;
--text-bd2-bold--font-family: var(--font-gothic-a1);

/* Body2 Regular */
--text-bd2-regular: 14px;
--text-bd2-regular--line-height: 160%;
--text-bd2-regular--font-weight: 400;
--text-bd2-regular--font-family: var(--font-gothic-a1);

/* Caption1 Bold */
--text-cp1-bold: 12px;
--text-cp1-bold--line-height: 160%;
--text-cp1-bold--font-weight: 700;
--text-cp1-bold--font-family: var(--font-gothic-a1);

/* Caption1 Regular */
--text-cp1-regular: 12px;
--text-cp1-regular--line-height: 160%;
--text-cp1-regular--font-weight: 400;
--text-cp1-regular--font-family: var(--font-gothic-a1);

/* Caption2 Bold */
--text-cp2-bold: 10px;
--text-cp2-bold--line-height: 160%;
--text-cp2-bold--font-weight: 700;
--text-cp2-bold--font-family: var(--font-gothic-a1);

/* Caption2 Regular */
--text-cp2-regular: 10px;
--text-cp2-regular--line-height: 160%;
--text-cp2-regular--font-weight: 400;
--text-cp2-regular--font-family: var(--font-gothic-a1);

/* Translate Caption1 Regular */
--text-trans-cp1-regular: 14px;
--text-cp1-regular--line-height: 160%;
--text-cp1-regular--font-weight: 400;
--text-cp1-regular--font-family: var(--font-mplus-2);

/* Translate Caption1 Regular */
--text-trans-cp1-regular: 14px;
--text-trans-cp1-regular--line-height: 160%;
--text-trans-cp1-regular--font-weight: 400;
--text-trans-cp1-regular--font-family: var(--font-mplus-2);

/* Translate Caption2 Regular */
--text-trans-cp2-regular: 12px;
--text-trans-cp2-regular--line-height: 120%;
--text-trans-cp2-regular--font-weight: 400;
--text-trans-cp2-regular--font-family: var(--font-mplus-2);

/* Translate Caption3 Regular */
--text-trans-cp3-regular: 10px;
--text-trans-cp3-regular--line-height: 120%;
--text-trans-cp3-regular--font-weight: 400;
--text-trans-cp3-regular--font-family: var(--font-mplus-2);
}

@layer utilities {
/* 그라디언트 */
.bg-gradient {
background-image: linear-gradient(to bottom, #FEFEFE, #E6F4FA);
}
.bg-gradient-reverse {
background-image: linear-gradient(to bottom, #E6F4FA, #FEFEFE);
}
/* 스크롤바 숨기기 */
.scrollbar-hide {
&::-webkit-scrollbar {
display: none;
}
scrollbar-width: none;
}
}

body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}
33 changes: 19 additions & 14 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import type { Metadata } from 'next';
import { Geist, Geist_Mono } from 'next/font/google';
import { Gothic_A1, M_PLUS_2, Noto_Sans_SC } from 'next/font/google';
import './globals.css';
import { ReactNode } from 'react';

const geistSans = Geist({
variable: '--font-geist-sans',
const gothic = Gothic_A1({
weight: ['400', '700'],
subsets: ['latin'],
variable: '--font-gothic-a1',
});

const geistMono = Geist_Mono({
variable: '--font-geist-mono',
const mplus = M_PLUS_2({
weight: ['400'],
subsets: ['latin', 'vietnamese', 'latin-ext'],
variable: '--font-mplus-2',
});

const noto = Noto_Sans_SC({
weight: ['400'],
subsets: ['latin'],
variable: '--font-noto-sc',
});

// TODO: 메타데이터 전체 수정
Expand All @@ -24,16 +32,13 @@ export const metadata: Metadata = {
},
};

export default function RootLayout({
children,
}: Readonly<{
children: ReactNode;
}>) {
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<html
lang="en"
className={`${gothic.variable} ${mplus.variable} ${noto.variable}`}
>
<body className="antialiased font-sans bg-background text-foreground">
{children}
</body>
</html>
Expand Down
Loading