- {emotions.map((emotion) => (
-
handleClick(emotion.id)}
- className="cursor-pointer p-4 text-sm transition-colors duration-200 ease-in-out hover:bg-primaryBlue-main"
- >
- {emotion.name}
-
- ))}
+
+
+
+ {emotions.map((emotion) => (
+ handleClick(emotion.id)}
+ >
+ {emotion.name.toUpperCase()}
+
+ ))}
+
+
How do you feel?
diff --git a/app/(main)/(home)/components/HappinessSurvey.tsx b/app/(main)/(home)/components/HappinessSurvey.tsx
index 21ae722..1038d06 100644
--- a/app/(main)/(home)/components/HappinessSurvey.tsx
+++ b/app/(main)/(home)/components/HappinessSurvey.tsx
@@ -1,13 +1,14 @@
'use client';
import * as React from 'react';
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@components/ui/Card/Card';
-import { Annoyed, Frown, Laugh, Smile } from 'lucide-react';
-import SurveyHappinessButton from '@components/Buttons/SurveyHappinessButton';
+import { User } from '@/types/UserType';
+import { Card, CardContent, CardHeader } from '@components/ui/Card/Card';
+import useDashboardClient from '@hooks/useDashboardClient';
import { SubmitHappinessScoreDTO } from '@/types/SurveyType';
+import { Annoyed, Frown, Laugh, Smile } from 'lucide-react';
+import { Button } from '@components/ui/Buttons/Button';
import { toast } from '@components/ui/Toast/use-toast';
-import useDashboardClient from '@hooks/useDashboardClient';
-import { User } from '@/types/UserType';
+import SurveyHoverCard from './SurveyHoverCard';
interface HappinessSurveyProps {
fetchDashboardData: () => void;
@@ -15,11 +16,8 @@ interface HappinessSurveyProps {
}
const HappinessSurvey: React.FC
= ({ fetchDashboardData, user }) => {
- const [rotateButton, setRotateButton] = React.useState(null);
const { submitHappinessScore } = useDashboardClient();
- const iconClasses = (score: number) => `h-12 w-12 ${rotateButton === score ? 'rotate-360' : ''}`;
-
const handleHappinessSubmit = async (score: number) => {
const happinessScore: SubmitHappinessScoreDTO = {
score,
@@ -44,51 +42,35 @@ const HappinessSurvey: React.FC = ({ fetchDashboardData, u
};
const handleClick = (score: number) => {
- setRotateButton(score);
- setTimeout(() => setRotateButton(null), 1000);
handleHappinessSubmit(score);
};
return (
-
-
- Survey
- How happy are you with your working day?
-
- We want to know how satisfied you are with your workday today. Your feedback is important to us and helps us
- understand your daily work experience.
-
+
+
+
+
-
-
-
}
- />
-
}
- />
-
}
- />
-
}
- />
+
+
+
+
handleClick(2)}>
+
+
+
handleClick(8)}>
+
+
+
handleClick(14)}>
+
+
+
handleClick(20)}>
+
+
+
+
How happy are you with your working day?
diff --git a/app/(main)/(home)/components/InactivityAlert.tsx b/app/(main)/(home)/components/InactivityAlert.tsx
deleted file mode 100644
index deff3a4..0000000
--- a/app/(main)/(home)/components/InactivityAlert.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-'use client';
-
-import * as React from 'react';
-
-import { DashboardDTO } from '@/types/DashboardType';
-import Widget from '@components/Cards/Widget';
-import { Activity, Annoyed, Bike, CircleSlash2, Component, Megaphone, Siren } from 'lucide-react';
-import AlertWidget from './AlertWidget';
-import Widget2 from './Widget';
-import SprintWidget from './SprintWidget';
-
-interface DashboardOverviewProps {
- dashboardData?: DashboardDTO;
-}
-
-const InactivityAlert: React.FC
= ({ dashboardData }) => (
-
-
} days={12} />
-
-
- } content="Coding" description="Most tracked worktype" />
-
-
}
- content={
}
- description="Average Happiness"
- />
-
} content="Bored, Lonely" description="Most tracked emotions" />
-
} content="4" description="Days left in the sprint" />
-
} content="Coding" description="Most tracked worktype" />
-
-
} days={12} />
-
,
- }}
- content={{
- mainContent: 'No Happiness tracking since 52 days.',
- subContent: dashboardData?.averageScore,
- }}
- borderColor="border-primaryBlue-main"
- fontColor="text-primaryBlue-main"
- />
-
-);
-
-export default InactivityAlert;
diff --git a/app/(main)/(home)/components/SprintWidget.tsx b/app/(main)/(home)/components/SprintWidget.tsx
index 6a187cf..21c64c8 100644
--- a/app/(main)/(home)/components/SprintWidget.tsx
+++ b/app/(main)/(home)/components/SprintWidget.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
import { Card, CardContent, CardHeader } from '@components/ui/Card/Card';
+import { motion, useAnimation } from 'framer-motion';
interface SprintWidgetProps {
icon: React.ReactNode;
@@ -7,21 +8,40 @@ interface SprintWidgetProps {
description: string;
}
-const SprintWidget: React.FC = ({ icon, content, description }) => (
-
-
-
-
- {icon}
-
-
-
-
-
{content}
-
{description}
-
-
-
-);
+const SprintWidget: React.FC = ({ icon, content, description }) => {
+ const controls = useAnimation();
+
+ const handleHoverStart = () => {
+ controls.start({
+ x: [-30, 30],
+ });
+ };
+
+ const handleHoverEnd = () => {
+ controls.stop();
+ controls.set({ x: 0 });
+ };
+
+ return (
+
+
+
+
+
+
+ {icon}
+
+
+
+
+
+
{content}
+
{description}
+
+
+
+
+ );
+};
export default SprintWidget;
diff --git a/app/(main)/(home)/components/SurveyHoverCard.tsx b/app/(main)/(home)/components/SurveyHoverCard.tsx
new file mode 100644
index 0000000..798f357
--- /dev/null
+++ b/app/(main)/(home)/components/SurveyHoverCard.tsx
@@ -0,0 +1,33 @@
+import * as React from 'react';
+import { HoverCard, HoverCardTrigger, HoverCardContent } from '@components/ui/HoverCard/HoverCard';
+import { FilePlus } from 'lucide-react';
+
+interface SurveyHoverCardProps {
+ title: string;
+ description: string;
+}
+
+const SurveyHoverCard: React.FC = ({ title, description }) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{title}
+
{description}
+
+
+
+
+
+);
+
+export default SurveyHoverCard;
diff --git a/app/(main)/(home)/components/Widget.tsx b/app/(main)/(home)/components/Widget.tsx
index 027706e..0ece139 100644
--- a/app/(main)/(home)/components/Widget.tsx
+++ b/app/(main)/(home)/components/Widget.tsx
@@ -7,7 +7,7 @@ interface WidgetProps {
description: string;
}
-const Widget2: React.FC = ({ icon, content, description }) => (
+const Widget: React.FC = ({ icon, content, description }) => (
@@ -17,11 +17,11 @@ const Widget2: React.FC = ({ icon, content, description }) => (
-
{content}
+
{content}
{description}
);
-export default Widget2;
+export default Widget;
diff --git a/app/(main)/(home)/components/WidgetRow.tsx b/app/(main)/(home)/components/WidgetRow.tsx
deleted file mode 100644
index 67c5a24..0000000
--- a/app/(main)/(home)/components/WidgetRow.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-'use client';
-
-import * as React from 'react';
-
-import { DashboardDTO } from '@/types/DashboardType';
-import Widget from '@components/Cards/Widget';
-import { AudioWaveform, Bike, CircleSlash } from 'lucide-react';
-import Progress from '@components/ui/Progress/Progress';
-import AverageHappinessButton from '@components/Buttons/AverageHappinessButton';
-
-interface DashboardOverviewProps {
- dashboardData?: DashboardDTO;
-}
-
-const WidgetRow: React.FC = ({ dashboardData }) => (
-
-
,
- }}
- content={{
- mainContent:
,
- }}
- />
-
,
- }}
- content={{
- mainContent:
,
- subContent: '4 days left',
- }}
- />
-
,
- }}
- content={{
- mainContent:
Bored, Lonely, Sick
,
- }}
- />
-
- {dashboardData.mostVotedWorkKind.workKindName}
-
-
- ) : (
- '-'
- ),
- }}
- />
-
-);
-
-export default WidgetRow;
diff --git a/app/(main)/(home)/components/WorkKindSurvey.tsx b/app/(main)/(home)/components/WorkKindSurvey.tsx
deleted file mode 100644
index 62c7e02..0000000
--- a/app/(main)/(home)/components/WorkKindSurvey.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-'use client';
-
-import * as React from 'react';
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@components/ui/Card/Card';
-import { toast } from '@components/ui/Toast/use-toast';
-import { WorkKind } from '@/types/WorkKindType';
-import { Annoyed, Frown, Laugh, Smile } from 'lucide-react';
-import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@components/ui/Table/BasicTable';
-import useDashboardClient from '@hooks/useDashboardClient';
-import { SubmitWorkKindScoreDTO } from '@/types/SurveyType';
-import { User } from '@/types/UserType';
-import SurveyHappinessButton from '@components/Buttons/SurveyHappinessButton';
-
-interface WorkKindSurveyProps {
- workKinds: Array;
- user: User;
- fetchDashboardData: () => void;
-}
-
-const WorkKindSurvey: React.FC = ({ fetchDashboardData, workKinds, user }) => {
- const { submitWorkKindScore } = useDashboardClient();
-
- const handleClick = async (score: number, workKindId: number) => {
- const workKindScore: SubmitWorkKindScoreDTO = {
- score,
- userId: user.id,
- workKindId,
- };
-
- try {
- await submitWorkKindScore(workKindScore);
- toast({
- title: 'Success!',
- description: `Happiness score submitted`,
- });
- fetchDashboardData();
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- } catch (error: any) {
- toast({
- title: 'Error!',
- description: `Failed to submit score: ${error.message}`,
- variant: 'destructive',
- });
- }
- };
-
- return (
-
-
- Survey
- How happy are you with specific worktypes?
-
- We want to understand your satisfaction with the different types of work you do. Your feedback helps us
- improve and tailor tasks to better fit your preferences.
-
-
-
-
-
-
-
- Work type
- Happiness
-
-
-
- {workKinds.map((workKind) => (
-
- {workKind.name}
-
-
-
handleClick(score, workKind.id)}
- className="bg-tertiaryBG-light"
- icon={ }
- />
- handleClick(score, workKind.id)}
- className="bg-primaryRed-light text-primaryRed-main"
- icon={ }
- />
- handleClick(score, workKind.id)}
- className="bg-primaryBlue-light text-primaryBlue-main"
- icon={ }
- />
- handleClick(score, workKind.id)}
- className="bg-primaryGreen-light text-primaryGreen-main"
- icon={ }
- />
-
-
-
- ))}
-
-
-
-
- );
-};
-
-export default WorkKindSurvey;
diff --git a/app/(main)/(home)/components/WorktypeSurvey.tsx b/app/(main)/(home)/components/WorktypeSurvey.tsx
new file mode 100644
index 0000000..941d55f
--- /dev/null
+++ b/app/(main)/(home)/components/WorktypeSurvey.tsx
@@ -0,0 +1,89 @@
+'use client';
+
+import * as React from 'react';
+import { Card, CardContent, CardHeader } from '@components/ui/Card/Card';
+import { WorkKind } from '@/types/WorkKindType';
+import { Annoyed, Frown, Laugh, Smile } from 'lucide-react';
+import useDashboardClient from '@hooks/useDashboardClient';
+import { User } from '@/types/UserType';
+import { SubmitWorkKindScoreDTO } from '@/types/SurveyType';
+import { Button } from '@components/ui/Buttons/Button';
+import { toast } from '@components/ui/Toast/use-toast';
+import SurveyHoverCard from './SurveyHoverCard';
+
+interface WorktypeSurveyProps {
+ workKinds: Array;
+ user: User;
+ fetchDashboardData: () => void;
+}
+
+const WorktypeSurvey: React.FC = ({ fetchDashboardData, workKinds, user }) => {
+ const { submitWorkKindScore } = useDashboardClient();
+
+ const handleClick = async (score: number, workKindId: number) => {
+ const workKindScore: SubmitWorkKindScoreDTO = {
+ score,
+ userId: user.id,
+ workKindId,
+ };
+
+ try {
+ await submitWorkKindScore(workKindScore);
+ toast({
+ title: 'Success!',
+ description: `Happiness score submitted`,
+ });
+ fetchDashboardData();
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ } catch (error: any) {
+ toast({
+ title: 'Error!',
+ description: `Failed to submit score: ${error.message}`,
+ variant: 'destructive',
+ });
+ }
+ };
+
+ return (
+
+
+
+
+
+
+ {workKinds.map((workKind) => (
+
+
{workKind.name}
+
+
handleClick(2, workKind.id)}>
+
+
+
handleClick(8, workKind.id)}>
+
+
+
handleClick(14, workKind.id)}
+ >
+
+
+
handleClick(20, workKind.id)}
+ >
+
+
+
+
+ ))}
+ How happy are you with specific worktypes?
+
+
+ );
+};
+
+export default WorktypeSurvey;
diff --git a/app/(main)/(home)/components/index.ts b/app/(main)/(home)/components/index.ts
new file mode 100644
index 0000000..55ae29a
--- /dev/null
+++ b/app/(main)/(home)/components/index.ts
@@ -0,0 +1,6 @@
+export { default as HappinessSurvey } from './HappinessSurvey';
+export { default as WorktypeSurvey } from './WorktypeSurvey';
+export { default as EmotionSurvey } from './EmotionSurvey';
+export { default as Widget } from './Widget';
+export { default as AlertWidget } from './AlertWidget';
+export { default as SprintWidget } from './SprintWidget';
diff --git a/app/(main)/(home)/page.tsx b/app/(main)/(home)/page.tsx
index d740328..94c62e3 100644
--- a/app/(main)/(home)/page.tsx
+++ b/app/(main)/(home)/page.tsx
@@ -5,22 +5,15 @@ import { useRouter } from 'next/navigation';
import Loading from '@components/Loading/Loading';
import Error from '@components/Error/Error';
import { useAuth } from '@providers/AuthProvider';
-import { ShipWheel } from 'lucide-react';
-import HappinessSurvey from '@/(main)/(home)/components/HappinessSurvey';
-import Widget from '@components/Cards/Widget';
+import { Activity, Bike, Component, CircleSlash2, Annoyed } from 'lucide-react';
import useDashboardClient from '@hooks/useDashboardClient';
import { toast } from '@components/ui/Toast/use-toast';
import { WorkKind } from '@/types/WorkKindType';
import useWorkKindClient from '@hooks/useWorkKindClient';
-import WorkKindSurvey from '@/(main)/(home)/components/WorkKindSurvey';
import { DashboardDTO } from '@/types/DashboardType';
import useEmotionClient from '@hooks/useEmotionClient';
import { Emotion } from '@/types/EmotionType';
-import EmotionSurvey from '@/(main)/(home)/components/EmotionSurvey';
-import WidgetRow from '@/(main)/(home)/components/WidgetRow';
-import InactivityAlert from '@/(main)/(home)/components/InactivityAlert';
-import FeedbackSurvey from '@/(main)/(home)/components/FeedbackSurvey';
-import AverageHappinessButton from '@components/Buttons/AverageHappinessButton';
+import { HappinessSurvey, WorktypeSurvey, EmotionSurvey, Widget, AlertWidget, SprintWidget } from './components';
const Home: React.FC = () => {
const { user, isLoading, error } = useAuth();
@@ -28,7 +21,7 @@ const Home: React.FC = () => {
const { getDashboardData } = useDashboardClient();
const { getWorkKinds } = useWorkKindClient();
const { getEmotions } = useEmotionClient();
- const [dashboardData, setDashboardData] = React.useState();
+ const [setDashboardData] = React.useState();
const [workKinds, setWorkKinds] = React.useState([]);
const [emotions, setEmotions] = React.useState([]);
const [isLoadingWorkKinds, setIsLoadingWorkKinds] = React.useState();
@@ -100,42 +93,18 @@ const Home: React.FC = () => {
{user && user.hasTeam ? (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
,
- }}
- content={{
- mainContent: 53,
- subContent: 'Story Points',
- }}
- />
-
,
- }}
- content={{
- mainContent:
,
- }}
- />
-
-
-
+
+
+
+
+
} content="4" description="Days left in the sprint" />
+
} content="Bored, Lonely" description="Most tracked emotions" />
+
} content="Coding" description="Most tracked worktype" />
+
}
+ content={
}
+ description="Average Happiness"
+ />
) : (
diff --git a/app/(onboarding)/onboarding/components/SelectableCard.tsx b/app/(onboarding)/onboarding/components/SelectableCard.tsx
index f2a903e..b28d5ad 100644
--- a/app/(onboarding)/onboarding/components/SelectableCard.tsx
+++ b/app/(onboarding)/onboarding/components/SelectableCard.tsx
@@ -12,7 +12,7 @@ interface SelectableCardProps {
const SelectableCard: React.FC
= ({ onClick, title, description, icon }) => (
diff --git a/components/Buttons/SurveyHappinessButton.tsx b/components/Buttons/SurveyHappinessButton.tsx
deleted file mode 100644
index 5ea9d52..0000000
--- a/components/Buttons/SurveyHappinessButton.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { Button } from '@components/ui/Buttons/Button';
-
-interface SurveyButtonProps {
- score: number;
- onClick: (score: number) => void;
- className: string;
- icon: React.ReactNode;
- size: 'icon' | 'default' | 'mood' | 'sm' | 'lg' | 'navigation' | null | undefined;
-}
-
-const SurveyHappinessButton: React.FC = ({ score, onClick, className, icon, size }) => (
- onClick(score)} variant="mood" size={size} className={className}>
- {icon}
-
-);
-
-export default SurveyHappinessButton;
diff --git a/components/Cards/Widget.tsx b/components/Cards/Widget.tsx
deleted file mode 100644
index 9437773..0000000
--- a/components/Cards/Widget.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as React from 'react';
-import { Card, CardHeader, CardTitle, CardContent } from '@components/ui/Card/Card';
-
-interface CardProps {
- header: {
- title: string;
- icon?: React.ReactNode;
- };
- content: {
- mainContent: React.ReactNode;
- subContent?: React.ReactNode;
- };
- borderColor?: string;
- fontColor?: string;
-}
-
-const Widget: React.FC = ({ header, content, borderColor, fontColor }) => (
-
-
- {header.title}
- {header.icon && {header.icon}
}
-
-
- {content.mainContent}
- {content.subContent && {content.subContent}
}
-
-
-);
-
-export default Widget;
diff --git a/components/ui/Buttons/Button.tsx b/components/ui/Buttons/Button.tsx
index 00c70f3..395b19b 100644
--- a/components/ui/Buttons/Button.tsx
+++ b/components/ui/Buttons/Button.tsx
@@ -20,15 +20,16 @@ const buttonVariants = cva(
link: 'text-slate-900 underline-offset-4 hover:underline dark:text-slate-50',
selected: 'bg-tertiaryBG-light dark:bg-secondaryBG-dark',
icon: 'dark:hover:bg-secondaryBG-dark hover:bg-tertiaryBG-light',
- mood: 'rounded-2xl hover:bg-secondaryBG-light focus-visible:bg-secondaryBG-light',
+ mood: 'rounded-3xl bg-tertiaryBG-light hover:bg-slate-50 text-black hover:text-black p-4',
},
size: {
default: 'h-10 px-4 py-2',
sm: ' rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-8 w-8',
+ survey: 'h-12 w-12',
navigation: 'h-10 w-10',
- mood: 'h-20 w-20',
+ mood: 'h-28 w-28',
},
},
defaultVariants: {
diff --git a/package-lock.json b/package-lock.json
index 1a03963..4fede56 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -30,6 +30,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
+ "framer-motion": "^11.3.17",
"input-otp": "^1.2.4",
"lucide-react": "^0.395.0",
"next": "14.2.3",
@@ -125,9 +126,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz",
- "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
+ "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -1515,9 +1516,9 @@
"integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
},
"node_modules/@rushstack/eslint-patch": {
- "version": "1.10.3",
- "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz",
- "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==",
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz",
+ "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==",
"dev": true
},
"node_modules/@swc/counter": {
@@ -1913,12 +1914,15 @@
}
},
"node_modules/ansi-escapes": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz",
- "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz",
+ "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==",
"dev": true,
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
"engines": {
- "node": ">=14.16"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -2384,15 +2388,15 @@
}
},
"node_modules/cli-cursor": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
- "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
"dev": true,
"dependencies": {
- "restore-cursor": "^4.0.0"
+ "restore-cursor": "^5.0.0"
},
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -2745,9 +2749,9 @@
}
},
"node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
@@ -2926,6 +2930,18 @@
"node": ">=10.13.0"
}
},
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.23.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
@@ -4049,6 +4065,30 @@
"node": ">= 6"
}
},
+ "node_modules/framer-motion": {
+ "version": "11.3.19",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.19.tgz",
+ "integrity": "sha512-+luuQdx4AsamyMcvzW7jUAJYIKvQs1KE7oHvKkW3eNzmo0S+3PSDWjBuQkuIP9WyneGnKGMLUSuHs8OP7jKpQg==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0",
+ "react-dom": "^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -4379,9 +4419,9 @@
}
},
"node_modules/husky": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.1.tgz",
- "integrity": "sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==",
+ "version": "9.1.3",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.3.tgz",
+ "integrity": "sha512-ET3TQmQgdIu0pt+jKkpo5oGyg/4MQZpG6xcam5J5JyNJV+CBT23OBpCF15bKHKycRyMH9k6ONy8g2HdGIsSkMQ==",
"dev": true,
"bin": {
"husky": "bin.js"
@@ -5301,14 +5341,14 @@
"dev": true
},
"node_modules/log-update": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz",
- "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
"dev": true,
"dependencies": {
- "ansi-escapes": "^6.2.0",
- "cli-cursor": "^4.0.0",
- "slice-ansi": "^7.0.0",
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
"strip-ansi": "^7.1.0",
"wrap-ansi": "^9.0.0"
},
@@ -5510,6 +5550,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
@@ -6239,9 +6291,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.39",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
- "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
+ "version": "8.4.40",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz",
+ "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==",
"funding": [
{
"type": "opencollective",
@@ -6870,51 +6922,36 @@
}
},
"node_modules/restore-cursor": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
- "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
"dev": true,
"dependencies": {
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2"
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
},
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/restore-cursor/node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/restore-cursor/node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
"dev": true,
"dependencies": {
- "mimic-fn": "^2.1.0"
+ "mimic-function": "^5.0.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/restore-cursor/node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "dev": true
- },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -7579,9 +7616,9 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.6",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz",
- "integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==",
+ "version": "3.4.7",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz",
+ "integrity": "sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
diff --git a/package.json b/package.json
index 0ec1769..de43765 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
+ "framer-motion": "^11.3.17",
"input-otp": "^1.2.4",
"lucide-react": "^0.395.0",
"next": "14.2.3",
diff --git a/tailwind.config.ts b/tailwind.config.ts
index e34421e..901001f 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -40,6 +40,10 @@ const config: Config = {
main: 'rgba(78, 138, 227)',
light: 'rgba(78, 138, 227, 0.2)',
},
+ primaryYellow: {
+ main: 'rgba(255, 179, 0)',
+ light: 'rgba(255, 179, 0, 0.2)',
+ },
// background colors
primaryBG: {