feat(ui): improve ui for test, drills and htm screens
This commit is contained in:
@ -36,7 +36,7 @@ const STYLES = `
|
||||
.home-screen {
|
||||
min-height: 100vh;
|
||||
background: #fffbf4;
|
||||
font-family: 'Satoshi', sans-serif;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
@ -248,6 +248,30 @@ const STYLES = `
|
||||
.h-tip-icon { flex-shrink:0;margin-top:1px; }
|
||||
.h-tip-text { font-size:0.85rem;font-weight:700;color:#374151;line-height:1.4; }
|
||||
|
||||
|
||||
/* ── Load more ── */
|
||||
.h-load-more-btn {
|
||||
width: 100%; margin-top: 0.25rem;
|
||||
padding: 0.75rem;
|
||||
background: white; border: 2.5px solid #f3f4f6;
|
||||
border-radius: 100px; cursor: pointer;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-size: 0.82rem; font-weight: 800; color: #9ca3af;
|
||||
display: flex; align-items: center; justify-content: center; gap: 0.4rem;
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,0.04);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.h-load-more-btn:hover { border-color: #c4b5fd; color: #a855f7; background: #fdf4ff; transform: translateY(-1px); box-shadow: 0 6px 14px rgba(0,0,0,0.06); }
|
||||
.h-load-more-btn:active { transform: translateY(1px); }
|
||||
|
||||
.h-sheet-count {
|
||||
text-align: center;
|
||||
font-family: 'Nunito Sans', sans-serif;
|
||||
font-size: 0.72rem; font-weight: 600; color: #d1d5db;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
.h-sheet-count span { font-weight: 800; color: #9ca3af; }
|
||||
|
||||
@keyframes hPopIn {
|
||||
from{opacity:0;transform:scale(0.92) translateY(10px);}
|
||||
to{opacity:1;transform:scale(1) translateY(0);}
|
||||
@ -305,6 +329,8 @@ const TIPS = [
|
||||
];
|
||||
|
||||
// ─── Main component ───────────────────────────────────────────────────────────
|
||||
const PAGE_SIZE = 2;
|
||||
|
||||
export const Home = () => {
|
||||
const user = useAuthStore((state) => state.user);
|
||||
const navigate = useNavigate();
|
||||
@ -319,6 +345,7 @@ export const Home = () => {
|
||||
>("all");
|
||||
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [visibleCount, setVisibleCount] = useState(PAGE_SIZE);
|
||||
|
||||
useEffect(() => {
|
||||
const sort = (sheets: PracticeSheet[]) => {
|
||||
@ -352,13 +379,22 @@ export const Home = () => {
|
||||
|
||||
const handleStart = (id: string) => navigate(`/student/practice/${id}`);
|
||||
|
||||
const tabSheets =
|
||||
const allTabSheets =
|
||||
activeTab === "all"
|
||||
? practiceSheets
|
||||
: activeTab === "NOT_STARTED"
|
||||
? notStartedSheets
|
||||
: completedSheets;
|
||||
|
||||
const tabSheets = allTabSheets.slice(0, visibleCount);
|
||||
const hasMore = visibleCount < allTabSheets.length;
|
||||
const remaining = allTabSheets.length - visibleCount;
|
||||
|
||||
const handleTabChange = (tab: "all" | "NOT_STARTED" | "COMPLETED") => {
|
||||
setActiveTab(tab);
|
||||
setVisibleCount(PAGE_SIZE);
|
||||
};
|
||||
|
||||
const greeting =
|
||||
new Date().getHours() < 12
|
||||
? "Good morning"
|
||||
@ -414,9 +450,9 @@ export const Home = () => {
|
||||
{user?.name?.slice(0, 1)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="space-y-1">
|
||||
<div>
|
||||
<p className="home-user-name">
|
||||
{greeting}, {user?.name?.split(" ")[0] || "Student"}
|
||||
{greeting}, {user?.name?.split(" ")[0] || "Student"} 👋
|
||||
</p>
|
||||
<p className="home-user-role">
|
||||
{user?.role === "STUDENT"
|
||||
@ -513,7 +549,7 @@ export const Home = () => {
|
||||
<button
|
||||
key={tab}
|
||||
className={`h-tab-btn${activeTab === tab ? " active" : ""}`}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
onClick={() => handleTabChange(tab)}
|
||||
>
|
||||
{tab === "all"
|
||||
? "All"
|
||||
@ -524,12 +560,30 @@ export const Home = () => {
|
||||
))}
|
||||
</div>
|
||||
|
||||
{tabSheets.length > 0 ? (
|
||||
<div className="h-sheet-grid">
|
||||
{tabSheets.map((sheet) => (
|
||||
<SheetCard key={sheet.id} sheet={sheet} onStart={handleStart} />
|
||||
))}
|
||||
</div>
|
||||
{allTabSheets.length > 0 ? (
|
||||
<>
|
||||
<div className="h-sheet-grid">
|
||||
{tabSheets.map((sheet) => (
|
||||
<SheetCard
|
||||
key={sheet.id}
|
||||
sheet={sheet}
|
||||
onStart={handleStart}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{hasMore ? (
|
||||
<button
|
||||
className="h-load-more-btn"
|
||||
onClick={() => setVisibleCount((c) => c + PAGE_SIZE)}
|
||||
>
|
||||
↓ Show {Math.min(remaining, PAGE_SIZE)} more
|
||||
</button>
|
||||
) : allTabSheets.length > PAGE_SIZE ? (
|
||||
<p className="h-sheet-count">
|
||||
Showing all <span>{allTabSheets.length}</span> sheets
|
||||
</p>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<div className="h-empty">
|
||||
<span className="h-empty-emoji">🔍</span>
|
||||
|
||||
Reference in New Issue
Block a user