Skip to content

Commit 952caa4

Browse files
authored
Merge pull request #127 from Logannford/dashboard/all-questions-bento-box-component
Dashboard/all questions bento box component
2 parents 4322b73 + a8dff72 commit 952caa4

File tree

9 files changed

+136
-35
lines changed

9 files changed

+136
-35
lines changed

src/app/(default_layout)/dashboard/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default async function Dashboard() {
1818
</div>
1919
</div>
2020
<Separator className="bg-black-50" />
21-
<div className=" h-full">
21+
<div className="h-full mt-1">
2222
<DashboardBentoGrid />
2323
</div>
2424
</div>

src/app/(default_layout)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function Layout({
2929

3030
{/* Scrollable content */}
3131
<AppSidebar />
32-
<main className="w-full pr-6 py-6 lg:pt-8 lg:pb-3">
32+
<main className="w-full pr-6 py-6 lg:pt-6 lg:pb-3">
3333
<div className="lg:pl-4 h-full">
3434
{/* <SidebarTrigger className="size-4 h-full flex items-center my-auto -top-2.5 relative" /> */}
3535
{children}

src/app/globals.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ body {
2727
.text-balance {
2828
text-wrap: balance;
2929
}
30+
31+
.pause-animation {
32+
animation-play-state: paused;
33+
}
3034
}
3135

3236
/* Basic editor styles */

src/components/dashboard/dashboard-bento-grid.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import TodaysLeaderboardBentoBox from '@/components/leaderboard/bento-box';
1212
import { getUserFromSession } from '@/actions/user/get-user';
1313
import UserRank from '../leaderboard/user-rank';
1414
import { Button } from '../ui/button';
15+
import AllQuestionsDashboardBentoBox from '../questions/dashboard/all-questions-bento-box';
1516

1617
export default async function DashboardBentoGrid() {
1718
const todaysQuestion = await getTodaysQuestion();
@@ -62,9 +63,7 @@ export default async function DashboardBentoGrid() {
6263
className: 'md:col-span-1 text-white',
6364
},
6465
{
65-
title: 'All Questions',
66-
description: 'View all questions and improve your knowledge',
67-
header: <Skeleton />,
66+
header: <AllQuestionsDashboardBentoBox />,
6867
className: 'md:col-span-1 text-white',
6968
href: '/previous-questions',
7069
},

src/components/global/chip.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default function Chip(opts: { text: string; color: string }) {
2+
const { text, color } = opts;
3+
4+
return (
5+
<span
6+
className={`px-2 py-1 text-xs font-semibold text-white rounded-md bg-${color}`}
7+
>
8+
{text}
9+
</span>
10+
);
11+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use client';
2+
import React, { useState } from 'react';
3+
import Chip from '../../global/chip';
4+
import DashboardQuestionCard from './dashboard-question-card';
5+
import { Arrow } from '@radix-ui/react-tooltip';
6+
import { ArrowRight } from 'lucide-react';
7+
8+
export default function AllQuestionsDashboardBentoBox() {
9+
const questions = [
10+
'What does the spread operator do?',
11+
"What's the difference between '==' and '==='?",
12+
'What will be the outcome of the following JavaScript snippet?',
13+
'What are the differences objects and arrays?',
14+
'What is the difference between .map and .forEach?',
15+
'Explain component lifecycle',
16+
];
17+
18+
// Triple the questions to ensure smooth infinite scroll
19+
const [allQuestions] = useState([...questions, ...questions, ...questions]);
20+
21+
return (
22+
<section className="h-full flex flex-col gap-y-5 group">
23+
<div className="space-y-3">
24+
<Chip color="accent" text="Questions" />
25+
<h6 className="text-lg lg:text-xl flex items-center">
26+
View all Questions
27+
<ArrowRight className="w-4 h-4 inline-block ml-1 group-hover:ml-2 duration-300" />
28+
</h6>
29+
</div>
30+
31+
<div className="relative overflow-hidden mt-3 h-64">
32+
<div
33+
className="animate-scroll hover:pause-animation"
34+
style={
35+
{ '--question-count': questions.length } as React.CSSProperties
36+
}
37+
>
38+
{allQuestions.map((question, index) => (
39+
<DashboardQuestionCard
40+
key={`${question}-${index}`}
41+
question={question}
42+
/>
43+
))}
44+
</div>
45+
</div>
46+
</section>
47+
);
48+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { CheckIcon } from '@radix-ui/react-icons';
2+
import { X } from 'lucide-react';
3+
4+
export default function DashboardQuestionCard({
5+
question,
6+
}: {
7+
question: string;
8+
}) {
9+
const randomQuestion = Math.random() > 0.5;
10+
11+
return (
12+
<div className="bg-black-100 border border-black-50 rounded-md p-4 mb-4">
13+
<div className="flex items-center">
14+
<div className="flex items-center justify-center size-4 border rounded-sm border-black-50 mr-3">
15+
{/** randomly add a tick icon */}
16+
{randomQuestion ? (
17+
<CheckIcon className="w-4 h-4 text-green-500" />
18+
) : (
19+
<X className="w-4 h-4 text-red-500" />
20+
)}
21+
</div>
22+
<span className="text-sm font-ubuntu">{question}</span>
23+
</div>
24+
</div>
25+
);
26+
}

src/components/ui/bento-grid.tsx

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const BentoGrid = ({
99
children?: React.ReactNode;
1010
}) => {
1111
return (
12-
<div className={cn('grid grid-cols-1 md:grid-cols-3 gap-6 ', className)}>
12+
<div className={cn('grid grid-cols-1 md:grid-cols-3 gap-6', className)}>
1313
{children}
1414
</div>
1515
);
@@ -30,39 +30,43 @@ export const BentoGridItem = ({
3030
icon?: React.ReactNode;
3131
href?: string;
3232
}) => {
33-
const content = (
34-
<>
35-
{header}
36-
<div className="group-hover/bento:translate-x-2 transition duration-200">
37-
{icon}
38-
<div className="font-bold text-white mb-1 mt-2 font-satoshi text-lg">
39-
{title}
40-
</div>
41-
<div className="font-normal text-sm text-white">{description}</div>
42-
</div>
43-
</>
33+
const renderContent = () => {
34+
const hasContent = title || description || icon;
35+
36+
return (
37+
<>
38+
{header}
39+
{hasContent && (
40+
<div className="group-hover/bento:translate-x-2 transition duration-200">
41+
{icon}
42+
{title && (
43+
<div className="font-bold text-white mb-1 mt-2 font-satoshi text-lg">
44+
{title}
45+
</div>
46+
)}
47+
{description && (
48+
<div className="font-normal text-sm text-white">
49+
{description}
50+
</div>
51+
)}
52+
</div>
53+
)}
54+
</>
55+
);
56+
};
57+
58+
const baseClasses = cn(
59+
'row-span-1 rounded-xl group/bento hover:shadow-xl transition duration-200 shadow-input dark:shadow-none p-4 dark:bg-black dark:border-white/[0.2] bg-black-75 border border-transparent justify-between flex flex-col',
60+
// Only add space-y-4 if there's content to space
61+
header || title || description || icon ? 'space-y-4' : '',
62+
className
4463
);
4564

46-
// If `href` is provided, wrap the content in a Link or anchor tag
4765
return href ? (
48-
<Link
49-
href={href}
50-
className={cn(
51-
'row-span-1 rounded-xl group/bento hover:shadow-xl transition duration-200 shadow-input dark:shadow-none p-4 dark:bg-black dark:border-white/[0.2] bg-black-75 border border-transparent justify-between flex flex-col space-y-4',
52-
className
53-
)}
54-
prefetch
55-
>
56-
{content}
66+
<Link href={href} className={baseClasses} prefetch>
67+
{renderContent()}
5768
</Link>
5869
) : (
59-
<div
60-
className={cn(
61-
'row-span-1 rounded-xl group/bento hover:shadow-xl transition duration-200 shadow-input dark:shadow-none p-4 dark:bg-black dark:border-white/[0.2] bg-black-75 border border-transparent justify-between flex flex-col space-y-4',
62-
className
63-
)}
64-
>
65-
{content}
66-
</div>
70+
<div className={baseClasses}>{renderContent()}</div>
6771
);
6872
};

tailwind.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,19 @@ const config: Config = {
116116
height: '0',
117117
},
118118
},
119+
scroll: {
120+
'0%': {
121+
transform: 'translateY(0)',
122+
},
123+
'100%': {
124+
transform: 'translateY(calc(-72px * var(--question-count)))',
125+
},
126+
},
119127
},
120128
animation: {
121129
'accordion-down': 'accordion-down 0.2s ease-out',
122130
'accordion-up': 'accordion-up 0.2s ease-out',
131+
scroll: 'scroll 30s linear infinite',
123132
},
124133
},
125134
},

0 commit comments

Comments
 (0)