Skip to content

Commit 30ac65a

Browse files
authored
Merge pull request #23 from mark-mdev/cap-deploy
feat(dashboard, vocab-assessment, story): enhance scrolling behavior …
2 parents efac6b2 + 263b8f7 commit 30ac65a

File tree

7 files changed

+108
-34
lines changed

7 files changed

+108
-34
lines changed

README.md

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Lingput - AI-Powered Comprehensible Input for Language Learning
22

3-
[**Live Demo**](https://your-demo-link.com) · [**Video Demo**](#video-demo)
3+
**Demo:**
4+
https://lingput.dev/
5+
https://app.lingput.dev/
6+
API:
7+
https://docs.lingput.dev/
48

59
<img src="docs/logo_min.jpeg" alt="Lingput logo" width="320" />
610

@@ -31,7 +35,6 @@ This project was built to production-grade standards, demonstrating expertise in
3135
- [Use Cases](#use-cases)
3236
- [Features](#features)
3337
- [Tech Stack](#tech-stack)
34-
- [API Overview](#api-overview)
3538
- [Quickstart](#quickstart)
3639
- [Production Deploy](#production-deploy)
3740
- [Roadmap](#roadmap)
@@ -109,24 +112,6 @@ This project was built to production-grade standards, demonstrating expertise in
109112

110113
---
111114

112-
## API Overview
113-
114-
Backend base: `/api`
115-
Full API docs with request/response examples: [`apps/backend/API.md`](apps/backend/API.md)
116-
117-
**Main route groups:**
118-
119-
- `POST /auth/register` · `POST /auth/login` · `POST /auth/logout` · `POST /auth/refresh` · `GET /auth/me`
120-
- `POST /story/generate` · `GET /story`
121-
- `GET /vocab/words` · `POST /vocab/words` · `PATCH /vocab/words/:id` · `DELETE /vocab/words/:id`
122-
- `GET /unknown-words/words` · `POST /unknown-words/mark-as-learned/:wordId`
123-
- `GET /vocab-assessment/start` · `POST /vocab-assessment/answer`
124-
- `GET /jobs/status/:jobId`
125-
126-
Auth uses HTTP-only cookies. Rate limiting + Helmet enabled.
127-
128-
---
129-
130115
## Quickstart
131116

132117
```bash

apps/frontend/package-lock.json

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/frontend/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"react-dom": "^19.0.0",
1515
"react-loading-skeleton": "^3.5.0",
1616
"react-toastify": "^11.0.5",
17+
"simplebar": "6.3.2",
18+
"simplebar-react": "3.3.2",
1719
"swr": "^2.3.3"
1820
},
1921
"devDependencies": {

apps/frontend/src/components/Dashboard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export default function Dashboard({
6969
}, [error]);
7070

7171
return (
72-
<div className="flex flex-col bg-transparent h-screen">
72+
<div className="flex flex-col bg-transparent h-screen overflow-y-scroll">
7373
<AssessmentRequiredOverlay wordsCount={typeof wordsCount === "number" ? wordsCount : -1} />
7474
{showOnboarding && !hasIntroShown && <OnboardingOverlay onComplete={completeIntro} />}
7575
{showOnboarding && hasIntroShown && coachmarkIndex !== null && (
@@ -86,7 +86,7 @@ export default function Dashboard({
8686
onChangeToNewStoryViewMode={handleChangeToNewStoryViewMode}
8787
onChangeToAllStoriesViewMode={handleChangeToAllStoriesViewMode}
8888
/>
89-
<div className="flex flex-row gap-6 flex-1 min-h-0">
89+
<div className="flex flex-row gap-6 flex-1 min-h-0 overflow-y-scroll">
9090
{/* LEFT PANEL */}
9191
<LeftPanel
9292
isLoading={isLoading}

apps/frontend/src/components/VocabAssessment.tsx

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"use client";
2+
import SimpleBar from "simplebar-react";
3+
import "simplebar-react/dist/simplebar.min.css";
14
import Word from "@/features/vocabAssessment/components/Word";
25
import ContinueButton from "@/features/vocabAssessment/components/ContinueButton";
36
import StartButton from "@/features/vocabAssessment/components/StartButton";
@@ -27,9 +30,12 @@ export default function VocabAssessment({
2730
handleWordAnswer,
2831
}: VocabAssessmentProps) {
2932
return (
30-
<div className="fixed inset-0 z-40 flex items-center justify-center">
31-
<div className="px-6 py-20 bg-white/80 backdrop-blur-sm border border-slate-100 flex flex-col items-center rounded-2xl w-full md:w-2/3 lg:w-1/2 shadow-sm mx-auto">
32-
<h1 className="text-xl font-semibold text-slate-900">Vocabulary Assessment</h1>
33+
<div className="fixed inset-0 z-40 flex items-center justify-center overflow-y-auto p-4">
34+
<SimpleBar
35+
autoHide={false}
36+
className="px-6 py-10 md:py-20 bg-white/80 backdrop-blur-sm border border-slate-100 flex flex-col items-center rounded-2xl w-full md:w-2/3 lg:w-1/2 shadow-sm mx-auto my-4 max-h-[90vh]"
37+
>
38+
<h1 className="text-xl font-semibold text-slate-900 text-center">Vocabulary Assessment</h1>
3339
{(status === "loading" || isLoading) && (
3440
<div className="py-6">
3541
<p className="text-slate-600">Loading...</p>
@@ -84,7 +90,24 @@ export default function VocabAssessment({
8490
</form>
8591
</div>
8692
)}
87-
</div>
93+
</SimpleBar>
94+
<style jsx>{`
95+
:global(.simplebar-track.simplebar-vertical) {
96+
width: 10px;
97+
background: #f1f5f9; /* slate-100 */
98+
border-radius: 9999px;
99+
}
100+
:global(.simplebar-scrollbar) {
101+
border-radius: 9999px;
102+
}
103+
:global(.simplebar-scrollbar:before) {
104+
background: #93c5fd; /* blue-300 */
105+
opacity: 1; /* ensure always visible */
106+
}
107+
:global(.simplebar-scrollbar:hover:before) {
108+
background: #60a5fa; /* blue-400 */
109+
}
110+
`}</style>
88111
</div>
89112
);
90113
}

apps/frontend/src/features/dashboard/components/RightPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function RightPanel({
77
}) {
88
return (
99
<div
10-
className={`w-full lg:w-3/4 bg-white/80 backdrop-blur-sm rounded-2xl flex flex-col gap-5 py-8 px-6 h-full overflow-hidden shadow-sm border border-slate-100 ${styles}`}
10+
className={`w-full lg:w-3/4 bg-white/80 backdrop-blur-sm rounded-2xl flex flex-col gap-5 py-8 px-6 h-full overflow-scroll shadow-sm border border-slate-100 ${styles}`}
1111
>
1212
{children}
1313
</div>

apps/frontend/src/features/story/components/Story.tsx

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"use client";
2+
import SimpleBar from "simplebar-react";
3+
import "simplebar-react/dist/simplebar.min.css";
14
import { useState } from "react";
25
import { Story } from "@/features/story/types";
36
import UnknownWordComponent from "@/features/unknownWord/components/UnknownWord";
@@ -37,17 +40,16 @@ export default function StoryComponent({
3740
<h2 className="font-semibold text-2xl tracking-tight text-slate-900">
3841
Story #
3942
{story ? story?.id : <Skeleton circle={true} width={20} height={20} inline={true} />}{" "}
40-
details
4143
</h2>
4244
<hr className="my-4 border-slate-200" />
4345
</div>
4446
{/* BOTTOM PART */}
45-
<div className="flex flex-col gap-6 flex-1 overflow-hidden">
47+
<SimpleBar autoHide={false} className="flex flex-col gap-6 flex-1 min-h-0">
4648
{/* TOP PANEL (STORY) */}
47-
<div className="px-4 flex flex-col gap-4 w-full">
49+
<div className="px-0 lg:px-4 flex flex-col gap-4 w-full">
4850
<h3 className="font-semibold text-slate-900">Story text</h3>
4951
<div className="p-4 bg-white rounded-xl border border-slate-200 shadow-sm">
50-
<p className="leading-relaxed text-slate-800">
52+
<p className="leading-relaxed text-slate-800 text-sm lg:text-base">
5153
{story ? story.storyText : <Skeleton count={3} />}
5254
</p>
5355
</div>
@@ -71,7 +73,7 @@ export default function StoryComponent({
7173
</button>
7274
{showTranslation && (
7375
<div className="p-4 bg-white rounded-xl border border-slate-200 shadow-sm">
74-
<p className="text-slate-800">
76+
<p className="text-slate-800 text-sm lg:text-base">
7577
{story && showTranslation ? story.translationText : <Skeleton count={2} />}
7678
</p>
7779
</div>
@@ -80,7 +82,7 @@ export default function StoryComponent({
8082
{/* <div className="bg-black w-[1px]"></div> */}
8183
<hr className="border-slate-200" />
8284
{/* BOTTOM PANEL (VOCABULARY) */}
83-
<div className="flex flex-col gap-3 px-4 w-full overflow-y-auto">
85+
<div className="flex flex-col gap-3 px-4 w-full">
8486
<div className="flex flex-row gap-2 items-center">
8587
<h3 className="font-semibold text-xl text-slate-900">Vocabulary</h3>
8688
{wordTranslationsBlurred && (
@@ -156,7 +158,24 @@ export default function StoryComponent({
156158
</div>
157159
)}
158160
</div>
159-
</div>
161+
</SimpleBar>
162+
<style jsx>{`
163+
:global(.simplebar-track.simplebar-vertical) {
164+
width: 10px;
165+
background: #f1f5f9; /* slate-100 */
166+
border-radius: 9999px;
167+
}
168+
:global(.simplebar-scrollbar) {
169+
border-radius: 9999px;
170+
}
171+
:global(.simplebar-scrollbar:before) {
172+
background: #93c5fd; /* blue-300 */
173+
opacity: 1; /* always visible */
174+
}
175+
:global(.simplebar-scrollbar:hover:before) {
176+
background: #60a5fa; /* blue-400 */
177+
}
178+
`}</style>
160179
</>
161180
);
162181
}

0 commit comments

Comments
 (0)