diff --git a/frontend/package.json b/frontend/package.json
index 72b917d9..6bf1925e 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -9,19 +9,20 @@
"lint": "next lint"
},
"dependencies": {
+ "next": "15.2.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
- "next": "15.2.4"
+ "react-icons": "^5.6.0"
},
"devDependencies": {
- "typescript": "^5",
+ "@eslint/eslintrc": "^3",
+ "@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
- "@tailwindcss/postcss": "^4",
- "tailwindcss": "^4",
"eslint": "^9",
"eslint-config-next": "15.2.4",
- "@eslint/eslintrc": "^3"
+ "tailwindcss": "^4",
+ "typescript": "^5"
}
}
diff --git a/frontend/public/Premium Gift Card.png b/frontend/public/Premium Gift Card.png
new file mode 100644
index 00000000..bff9585d
Binary files /dev/null and b/frontend/public/Premium Gift Card.png differ
diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css
index a2dc41ec..5d5d9196 100644
--- a/frontend/src/app/globals.css
+++ b/frontend/src/app/globals.css
@@ -8,8 +8,9 @@
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
+ --font-sans: var(--font-inter);
+ --font-inter: var(--font-inter);
+ --font-poppins: var(--font-poppins);
}
@media (prefers-color-scheme: dark) {
@@ -22,5 +23,13 @@
body {
background: var(--background);
color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+ font-family: var(--font-inter);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: var(--font-poppins);
+ font-weight: 700;
+ letter-spacing: -0.02em;
}
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index f7fa87eb..ac5a9134 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -1,15 +1,17 @@
import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
+import { Inter, Poppins } from "next/font/google";
import "./globals.css";
-const geistSans = Geist({
- variable: "--font-geist-sans",
+const inter = Inter({
+ variable: "--font-inter",
subsets: ["latin"],
+ weight: ["400", "500", "600", "700"],
});
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
+const poppins = Poppins({
+ variable: "--font-poppins",
subsets: ["latin"],
+ weight: ["500", "600", "700", "800"],
});
export const metadata: Metadata = {
@@ -25,7 +27,7 @@ export default function RootLayout({
return (
{children}
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index e68abe6b..4f342e5a 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -1,103 +1,25 @@
-import Image from "next/image";
+'use client';
+
+import { Navigation, HeroSection, WhyChooseSection } from '@/features';
export default function Home() {
return (
-
-
-
-
- -
- Get started by editing{" "}
-
- src/app/page.tsx
-
- .
-
- -
- Save and see your changes instantly.
-
-
+
+ {/* Navigation */}
+
+
+ {/* Hero Section */}
+
-
-
-
+ {/* Why Choose Section */}
+
);
}
diff --git a/frontend/src/features/benefits/components/BenefitCard.tsx b/frontend/src/features/benefits/components/BenefitCard.tsx
new file mode 100644
index 00000000..6cef9792
--- /dev/null
+++ b/frontend/src/features/benefits/components/BenefitCard.tsx
@@ -0,0 +1,94 @@
+import React from 'react';
+import { BenefitCardProps } from '../types/benefits.types';
+import { COLORS, SPACING } from '../constants/theme.constants';
+
+export const BenefitCard: React.FC = ({
+ icon,
+ title,
+ description,
+ gradient,
+ iconBg,
+ iconSize,
+ titleSize = 14,
+ descSize = 12,
+ flex,
+ layout = 'vertical',
+ titleColor = COLORS.cardText,
+ descriptionColor = COLORS.cardSubtext,
+ iconBorder,
+}) => {
+ if (layout === 'horizontal') {
+ return (
+
+
+ {icon}
+
+
+
+ {title}
+
+
+ {description}
+
+
+
+ );
+ }
+
+ return (
+
+
+ {icon}
+
+
+ {title}
+
+
+ {description}
+
+
+ );
+};
diff --git a/frontend/src/features/benefits/components/WhyChooseSection.tsx b/frontend/src/features/benefits/components/WhyChooseSection.tsx
new file mode 100644
index 00000000..dd80a4ce
--- /dev/null
+++ b/frontend/src/features/benefits/components/WhyChooseSection.tsx
@@ -0,0 +1,87 @@
+import React from 'react';
+import { Benefits } from '../data/benefits.data';
+import { COLORS, SPACING } from '../constants/theme.constants';
+import { WhyChooseSectionProps, Benefit } from '../types/benefits.types';
+import { BenefitCard } from './BenefitCard';
+
+export const WhyChooseSection: React.FC = ({
+ heading = 'Why Choose Moola?',
+ subtitle = 'Experience the most sophisticated rewards platform designed for the modern lifestyle',
+}) => {
+ const leftColumn = Benefits.filter((b) => b.column === 'left');
+ const rightColumn = Benefits.filter((b) => b.column === 'right');
+
+ const renderColumn = (column: Benefit[]) =>
+ column.map((benefit) => (
+
+ ));
+
+ return (
+
+ {/* Header */}
+
+
+ {heading}
+
+
+ {subtitle}
+
+
+
+ {/* Two-column grid */}
+
+ {/* LEFT COLUMN */}
+
+ {renderColumn(leftColumn)}
+
+
+ {/* RIGHT COLUMN */}
+
+ {renderColumn(rightColumn)}
+
+
+
+ );
+};
+
+export default WhyChooseSection;
\ No newline at end of file
diff --git a/frontend/src/features/benefits/components/index.ts b/frontend/src/features/benefits/components/index.ts
new file mode 100644
index 00000000..ecb50800
--- /dev/null
+++ b/frontend/src/features/benefits/components/index.ts
@@ -0,0 +1,2 @@
+export { WhyChooseSection } from './WhyChooseSection';
+export { BenefitCard } from './BenefitCard';
diff --git a/frontend/src/features/benefits/constants/index.ts b/frontend/src/features/benefits/constants/index.ts
new file mode 100644
index 00000000..5eea45b6
--- /dev/null
+++ b/frontend/src/features/benefits/constants/index.ts
@@ -0,0 +1 @@
+export { COLORS, SPACING, ICON_SIZES } from './theme.constants';
diff --git a/frontend/src/features/benefits/constants/theme.constants.ts b/frontend/src/features/benefits/constants/theme.constants.ts
new file mode 100644
index 00000000..dbaa28b9
--- /dev/null
+++ b/frontend/src/features/benefits/constants/theme.constants.ts
@@ -0,0 +1,28 @@
+export const COLORS = {
+ background: '#eee8f9',
+ heading: '#13092c',
+ subtitle: '#6b5d80',
+ cardText: '#160d30',
+ cardSubtext: '#4a3c62',
+ primary: '#7c3aed',
+ accent: '#c4368a',
+ darkGradient1: '#6730de',
+ darkGradient2: '#3d16a8',
+} as const;
+
+export const SPACING = {
+ containerPadding: '48px 32px',
+ sectionMargin: 36,
+ gridGap: 14,
+ cardPadding: '26px 22px',
+ cardCompactPadding: '20px 20px',
+ iconMargin: 13,
+ titleMargin: 7,
+} as const;
+
+export const ICON_SIZES = {
+ large: { width: 46, height: 46, radius: 12 },
+ medium: { width: 36, height: 36, radius: 9 },
+ mediumRound: { width: 36, height: 36, radius: 10 },
+ xl: { width: 52, height: 52, radius: 14 },
+} as const;
diff --git a/frontend/src/features/benefits/data/benefit-icons.tsx b/frontend/src/features/benefits/data/benefit-icons.tsx
new file mode 100644
index 00000000..a7e3b7df
--- /dev/null
+++ b/frontend/src/features/benefits/data/benefit-icons.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+
+export const CashbackIcon = (
+
+);
+
+export const BrandsIcon = (
+
+);
+
+export const InstantIcon = (
+
+);
+
+export const SecurityIcon = (
+
+);
diff --git a/frontend/src/features/benefits/data/benefits.data.ts b/frontend/src/features/benefits/data/benefits.data.ts
new file mode 100644
index 00000000..2f4e168a
--- /dev/null
+++ b/frontend/src/features/benefits/data/benefits.data.ts
@@ -0,0 +1,67 @@
+import { Benefit } from '../types/benefits.types';
+import { COLORS, ICON_SIZES } from '../constants/theme.constants';
+import { CashbackIcon, BrandsIcon, InstantIcon, SecurityIcon } from './benefit-icons';
+
+export const Benefits: Benefit[] = [
+ {
+ id: 'cashback',
+ title: 'Cash Back Rewards',
+ description:
+ 'Every time you shop, you earn. Get up to 15% cash back on your favorite brands, deposited directly to your wallet.',
+ icon: CashbackIcon,
+ gradient: 'linear-gradient(140deg, #cdb6f2 0%, #eebfdf 100%)',
+ iconBg: COLORS.primary,
+ iconSize: ICON_SIZES.large,
+ titleSize: 16,
+ descSize: 13,
+ flex: '1.1',
+ layout: 'vertical',
+ column: 'left',
+ },
+ {
+ id: 'brands',
+ title: '250+ Top Brands',
+ description:
+ "From fashion to food, tech to travel. We have the world's most loved brands. Order one now!",
+ icon: BrandsIcon,
+ gradient: 'linear-gradient(140deg, #dccff6 0%, #f0d8f3 100%)',
+ iconBg: COLORS.primary,
+ iconSize: ICON_SIZES.medium,
+ titleSize: 14,
+ descSize: 12,
+ flex: '0.9',
+ layout: 'vertical',
+ column: 'left',
+ },
+ {
+ id: 'instant',
+ title: 'Instant Delivery',
+ description:
+ 'No waiting around. Your digital gift cards are delivered to your inbox and wallet in milliseconds.',
+ icon: InstantIcon,
+ gradient: 'linear-gradient(140deg, #f0e5fb 0%, #e6d4f8 100%)',
+ iconBg: COLORS.accent,
+ iconSize: ICON_SIZES.mediumRound,
+ titleSize: 14,
+ descSize: 12,
+ layout: 'horizontal',
+ column: 'right',
+ },
+ {
+ id: 'security',
+ title: 'Bank-Grade Security',
+ description:
+ 'Your data and rewards are protected with high-level encryption and biometric authentication.',
+ icon: SecurityIcon,
+ gradient: `linear-gradient(155deg, ${COLORS.darkGradient1} 0%, ${COLORS.darkGradient2} 100%)`,
+ iconBg: 'rgba(255,255,255,0.17)',
+ iconSize: ICON_SIZES.xl,
+ titleSize: 20,
+ descSize: 13.5,
+ layout: 'vertical',
+ column: 'right',
+ titleColor: '#fff',
+ descriptionColor: 'rgba(255,255,255,0.85)',
+ iconBorder: '1px solid rgba(255,255,255,0.28)',
+ },
+];
diff --git a/frontend/src/features/benefits/data/index.ts b/frontend/src/features/benefits/data/index.ts
new file mode 100644
index 00000000..5b81abc8
--- /dev/null
+++ b/frontend/src/features/benefits/data/index.ts
@@ -0,0 +1 @@
+export { Benefits } from './benefits.data';
diff --git a/frontend/src/features/benefits/index.ts b/frontend/src/features/benefits/index.ts
new file mode 100644
index 00000000..c1fb440c
--- /dev/null
+++ b/frontend/src/features/benefits/index.ts
@@ -0,0 +1,11 @@
+// Components
+export { WhyChooseSection, BenefitCard } from './components';
+
+// Types
+export type { WhyChooseSectionProps, Benefit, BenefitCardProps } from './types/benefits.types';
+
+// Constants
+export { COLORS, SPACING, ICON_SIZES } from './constants';
+
+// Data
+export { Benefits } from './data';
diff --git a/frontend/src/features/benefits/types/benefits.types.ts b/frontend/src/features/benefits/types/benefits.types.ts
new file mode 100644
index 00000000..7af5a8a3
--- /dev/null
+++ b/frontend/src/features/benefits/types/benefits.types.ts
@@ -0,0 +1,41 @@
+import React from 'react';
+import { ICON_SIZES } from '../constants/theme.constants';
+
+export interface Benefit {
+ id: string;
+ title: string;
+ description: string;
+ icon: React.ReactNode;
+ gradient: string;
+ iconBg: string;
+ iconSize: (typeof ICON_SIZES)[keyof typeof ICON_SIZES];
+ titleSize: number;
+ descSize: number;
+ flex?: number | string;
+ layout?: 'vertical' | 'horizontal';
+ column: 'left' | 'right';
+ titleColor?: string;
+ descriptionColor?: string;
+ iconBorder?: string;
+}
+
+export interface BenefitCardProps {
+ icon: React.ReactNode;
+ title: string;
+ description: string;
+ gradient: string;
+ iconBg: string;
+ iconSize: (typeof ICON_SIZES)[keyof typeof ICON_SIZES];
+ titleSize?: number;
+ descSize?: number;
+ flex?: number | string;
+ layout?: 'vertical' | 'horizontal';
+ titleColor?: string;
+ descriptionColor?: string;
+ iconBorder?: string;
+}
+
+export interface WhyChooseSectionProps {
+ heading?: string;
+ subtitle?: string;
+}
diff --git a/frontend/src/features/common/components/Badge.tsx b/frontend/src/features/common/components/Badge.tsx
new file mode 100644
index 00000000..9975ebfe
--- /dev/null
+++ b/frontend/src/features/common/components/Badge.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import type { BadgeProps } from '../types/badge.types';
+
+export const Badge = ({ variant = 'default', icon, children, className = '' }: BadgeProps) => {
+ const baseStyles = 'inline-flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium font-poppins';
+
+ const variantStyles = {
+ default: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200',
+ primary: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200',
+ success: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
+ warning: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200',
+ };
+
+ const combinedClassName = `${baseStyles} ${variantStyles[variant]} ${className}`;
+
+ return (
+
+ {icon && {icon}}
+ {children}
+
+ );
+};
diff --git a/frontend/src/features/common/components/Button.tsx b/frontend/src/features/common/components/Button.tsx
new file mode 100644
index 00000000..409ed3dc
--- /dev/null
+++ b/frontend/src/features/common/components/Button.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import type { ButtonProps } from '../types/button.types';
+
+export const Button = ({
+ variant = 'primary',
+ size = 'md',
+ children,
+ className = '',
+ onClick,
+ href,
+ target,
+ rel,
+}: ButtonProps) => {
+ const baseStyles = 'font-semibold font-poppins rounded-full transition-all duration-200 inline-flex items-center justify-center gap-2';
+
+ const variantStyles = {
+ primary: 'bg-purple-600 text-white hover:bg-purple-700 active:bg-purple-800',
+ secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200 active:bg-gray-300 dark:bg-gray-800 dark:text-gray-100 dark:hover:bg-gray-700',
+ outline: 'border-2 border-gray-300 text-gray-900 hover:bg-gray-50 active:bg-gray-100 dark:border-gray-600 dark:text-gray-100 dark:hover:bg-gray-900',
+ };
+
+ const sizeStyles = {
+ sm: 'px-4 py-2 text-sm',
+ md: 'px-6 py-2.5 text-base',
+ lg: 'px-8 py-3 text-lg',
+ };
+
+ const combinedClassName = `${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`;
+
+ if (href) {
+ return (
+
+ {children}
+
+ );
+ }
+
+ return (
+
+ );
+};
diff --git a/frontend/src/features/common/components/Card.tsx b/frontend/src/features/common/components/Card.tsx
new file mode 100644
index 00000000..e3185b23
--- /dev/null
+++ b/frontend/src/features/common/components/Card.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+import type { CardProps } from '../types/card.types';
+
+export const Card = ({ variant = 'default', className = '', children }: CardProps) => {
+ const baseStyles = 'rounded-lg';
+
+ const variantStyles = {
+ default: 'bg-white dark:bg-gray-900 shadow-md hover:shadow-lg transition-shadow',
+ featured: 'bg-gradient-to-br from-gray-800 to-gray-900 shadow-2xl',
+ stats: 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm',
+ };
+
+ const combinedClassName = `${baseStyles} ${variantStyles[variant]} ${className}`;
+
+ return {children}
;
+};
diff --git a/frontend/src/features/common/components/Container.tsx b/frontend/src/features/common/components/Container.tsx
new file mode 100644
index 00000000..23a9e973
--- /dev/null
+++ b/frontend/src/features/common/components/Container.tsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import type { LayoutProps } from '../types/layout.types';
+
+/**
+ * Container - Standard content wrapper with responsive padding
+ * Provides max-width constraint and horizontal padding
+ */
+export const Container = ({ children, className = '' }: LayoutProps) => {
+ return {children}
;
+};
diff --git a/frontend/src/features/common/components/Grid.tsx b/frontend/src/features/common/components/Grid.tsx
new file mode 100644
index 00000000..8e899f70
--- /dev/null
+++ b/frontend/src/features/common/components/Grid.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import type { GridProps } from '../types/layout.types';
+
+/**
+ * Grid - Responsive grid for card layouts
+ * Adapts column count and gap based on screen size
+ */
+const gapStyles = {
+ sm: 'gap-4',
+ md: 'gap-6',
+ lg: 'gap-8',
+};
+
+const columnStyles = {
+ 1: 'grid-cols-1',
+ 2: 'md:grid-cols-2',
+ 3: 'md:grid-cols-2 lg:grid-cols-3',
+ 4: 'md:grid-cols-2 lg:grid-cols-4',
+};
+
+export const Grid = ({ children, columns = 3, gap = 'md' }: GridProps) => {
+ return {children}
;
+};
diff --git a/frontend/src/features/common/components/PageLayout.tsx b/frontend/src/features/common/components/PageLayout.tsx
new file mode 100644
index 00000000..968f43ef
--- /dev/null
+++ b/frontend/src/features/common/components/PageLayout.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import type { PageLayoutProps } from '../types/layout.types';
+
+/**
+ * PageLayout - Complete page wrapper with full-height layout
+ * Provides min-height viewport coverage and flex column layout
+ */
+export const PageLayout = ({ children }: PageLayoutProps) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/frontend/src/features/common/components/Section.tsx b/frontend/src/features/common/components/Section.tsx
new file mode 100644
index 00000000..59aecd03
--- /dev/null
+++ b/frontend/src/features/common/components/Section.tsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import type { LayoutProps } from '../types/layout.types';
+
+/**
+ * Section - Standard section wrapper with consistent vertical spacing
+ * Provides responsive padding for full-width sections
+ */
+export const Section = ({ children, className = '' }: LayoutProps) => {
+ return ;
+};
diff --git a/frontend/src/features/common/index.ts b/frontend/src/features/common/index.ts
new file mode 100644
index 00000000..48e5e202
--- /dev/null
+++ b/frontend/src/features/common/index.ts
@@ -0,0 +1,14 @@
+// Common Feature Components - Reusable UI Elements
+export { Button } from './components/Button';
+export { Card } from './components/Card';
+export { Badge } from './components/Badge';
+export { Container } from './components/Container';
+export { Section } from './components/Section';
+export { PageLayout } from './components/PageLayout';
+export { Grid } from './components/Grid';
+
+// Common Feature Types
+export type { ButtonProps } from './types/button.types';
+export type { CardProps } from './types/card.types';
+export type { BadgeProps } from './types/badge.types';
+export type { LayoutProps, PageLayoutProps, GridProps } from './types/layout.types';
diff --git a/frontend/src/features/common/types/badge.types.ts b/frontend/src/features/common/types/badge.types.ts
new file mode 100644
index 00000000..75431fcb
--- /dev/null
+++ b/frontend/src/features/common/types/badge.types.ts
@@ -0,0 +1,8 @@
+import React from 'react';
+
+export interface BadgeProps {
+ variant?: 'default' | 'primary' | 'success' | 'warning';
+ icon?: React.ReactNode;
+ children: React.ReactNode;
+ className?: string;
+}
diff --git a/frontend/src/features/common/types/button.types.ts b/frontend/src/features/common/types/button.types.ts
new file mode 100644
index 00000000..604e33aa
--- /dev/null
+++ b/frontend/src/features/common/types/button.types.ts
@@ -0,0 +1,12 @@
+import React from 'react';
+
+export interface ButtonProps {
+ variant?: 'primary' | 'secondary' | 'outline';
+ size?: 'sm' | 'md' | 'lg';
+ children: React.ReactNode;
+ className?: string;
+ onClick?: () => void;
+ href?: string;
+ target?: string;
+ rel?: string;
+}
diff --git a/frontend/src/features/common/types/card.types.ts b/frontend/src/features/common/types/card.types.ts
new file mode 100644
index 00000000..bd84e5a2
--- /dev/null
+++ b/frontend/src/features/common/types/card.types.ts
@@ -0,0 +1,7 @@
+import React from 'react';
+
+export interface CardProps {
+ variant?: 'default' | 'featured' | 'stats';
+ className?: string;
+ children: React.ReactNode;
+}
diff --git a/frontend/src/features/common/types/index.ts b/frontend/src/features/common/types/index.ts
new file mode 100644
index 00000000..6d742e3f
--- /dev/null
+++ b/frontend/src/features/common/types/index.ts
@@ -0,0 +1,5 @@
+// Common Feature Types
+export type { ButtonProps } from './button.types';
+export type { CardProps } from './card.types';
+export type { BadgeProps } from './badge.types';
+export type { LayoutProps, PageLayoutProps, GridProps } from './layout.types';
diff --git a/frontend/src/features/common/types/layout.types.ts b/frontend/src/features/common/types/layout.types.ts
new file mode 100644
index 00000000..69505111
--- /dev/null
+++ b/frontend/src/features/common/types/layout.types.ts
@@ -0,0 +1,16 @@
+import React from 'react';
+
+export interface LayoutProps {
+ children: React.ReactNode;
+ className?: string;
+}
+
+export interface PageLayoutProps {
+ children: React.ReactNode;
+}
+
+export interface GridProps {
+ children: React.ReactNode;
+ columns?: 1 | 2 | 3 | 4;
+ gap?: 'sm' | 'md' | 'lg';
+}
diff --git a/frontend/src/features/hero/components/HeroSection.tsx b/frontend/src/features/hero/components/HeroSection.tsx
new file mode 100644
index 00000000..195176ec
--- /dev/null
+++ b/frontend/src/features/hero/components/HeroSection.tsx
@@ -0,0 +1,79 @@
+import React from 'react';
+import Image from 'next/image';
+import { FiDollarSign } from 'react-icons/fi';
+import { Button, Badge, Card } from '@/features/common';
+import type { HeroSectionProps } from '../types/hero.types';
+
+export const HeroSection = ({
+ badge = 'The Future of Gifting is Here',
+ title = 'Gifting Made Easier',
+ description = 'Access over 250+ premium brands with instant delivery and exclusive cash back rewards. The boutique experience for digital rewards.',
+ primaryButtonText = 'Shop Gift Cards',
+ secondaryButtonText = 'View Brands',
+ stats = { label: 'EARNED TODAY', value: '$42.50' },
+}: HeroSectionProps) => {
+ return (
+
+ {/* Left Content */}
+
+ {/* Badge */}
+
+ {badge}
+
+
+ {/* Heading */}
+
+
+ {title}
+
+
+
+ {/* Description */}
+
+ {description}
+
+
+ {/* Buttons */}
+
+
+
+
+
+
+ {/* Right Content - Product Display */}
+
+ {/* Gift Card Container with Earnings Badge */}
+
+ {/* Premium Gift Card Image */}
+
+
+ {/* Earnings Badge - Positioned on bottom left */}
+
+
+
+
+
+
+
{stats.label}
+
{stats.value}
+
+
+
+
+
+
+ );
+};
diff --git a/frontend/src/features/hero/index.ts b/frontend/src/features/hero/index.ts
new file mode 100644
index 00000000..b09cc2c6
--- /dev/null
+++ b/frontend/src/features/hero/index.ts
@@ -0,0 +1,5 @@
+// Hero Feature
+export { HeroSection } from './components/HeroSection';
+
+// Hero Feature Types
+export type { HeroSectionProps } from './types/hero.types';
diff --git a/frontend/src/features/hero/types/hero.types.ts b/frontend/src/features/hero/types/hero.types.ts
new file mode 100644
index 00000000..e3bf3886
--- /dev/null
+++ b/frontend/src/features/hero/types/hero.types.ts
@@ -0,0 +1,11 @@
+export interface HeroSectionProps {
+ badge?: string;
+ title: string;
+ description: string;
+ primaryButtonText?: string;
+ secondaryButtonText?: string;
+ stats?: {
+ label: string;
+ value: string;
+ };
+}
diff --git a/frontend/src/features/hero/types/index.ts b/frontend/src/features/hero/types/index.ts
new file mode 100644
index 00000000..72408e15
--- /dev/null
+++ b/frontend/src/features/hero/types/index.ts
@@ -0,0 +1,2 @@
+// Hero Feature Types
+export type { HeroSectionProps } from './hero.types';
diff --git a/frontend/src/features/index.ts b/frontend/src/features/index.ts
new file mode 100644
index 00000000..ca14dc27
--- /dev/null
+++ b/frontend/src/features/index.ts
@@ -0,0 +1,42 @@
+/**
+ * Features:
+ * - common: Reusable UI components (Button, Card, Badge, Layout)
+ * - navigation: Navigation/header components
+ * - hero: Hero section components
+ */
+
+// Common Feature
+export {
+ Button,
+ Card,
+ Badge,
+ Container,
+ Section,
+ PageLayout,
+ Grid,
+ type ButtonProps,
+ type CardProps,
+ type BadgeProps,
+ type LayoutProps,
+ type PageLayoutProps,
+ type GridProps,
+} from './common';
+
+// Navigation Feature
+export {
+ Navigation,
+ type NavLink,
+ type NavigationProps,
+} from './navigation';
+
+// Hero Feature
+export {
+ HeroSection,
+ type HeroSectionProps,
+} from './hero';
+
+// Benefits Feature
+export {
+ WhyChooseSection,
+ type WhyChooseSectionProps,
+} from './benefits';
diff --git a/frontend/src/features/navigation/components/Navigation.tsx b/frontend/src/features/navigation/components/Navigation.tsx
new file mode 100644
index 00000000..1bf5ed7d
--- /dev/null
+++ b/frontend/src/features/navigation/components/Navigation.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import { Button } from '@/features/common';
+import type { NavLink, NavigationProps } from '../types/navigation.types';
+
+const defaultLinks: NavLink[] = [
+ { label: 'Rewards', href: '#rewards' },
+ { label: 'Features', href: '#features' },
+ { label: 'Partners', href: '#partners' },
+ { label: 'About', href: '#about' },
+];
+
+export const Navigation = ({ links = defaultLinks, logo = 'Radiant Rewards' }: NavigationProps) => {
+ return (
+
+ );
+};
diff --git a/frontend/src/features/navigation/index.ts b/frontend/src/features/navigation/index.ts
new file mode 100644
index 00000000..8f65b3c4
--- /dev/null
+++ b/frontend/src/features/navigation/index.ts
@@ -0,0 +1,5 @@
+// Navigation Feature
+export { Navigation } from './components/Navigation';
+
+// Navigation Feature Types
+export type { NavLink, NavigationProps } from './types/navigation.types';
diff --git a/frontend/src/features/navigation/types/index.ts b/frontend/src/features/navigation/types/index.ts
new file mode 100644
index 00000000..976899de
--- /dev/null
+++ b/frontend/src/features/navigation/types/index.ts
@@ -0,0 +1,2 @@
+// Navigation Feature Types
+export type { NavLink, NavigationProps } from './navigation.types';
diff --git a/frontend/src/features/navigation/types/navigation.types.ts b/frontend/src/features/navigation/types/navigation.types.ts
new file mode 100644
index 00000000..c5f0c7ad
--- /dev/null
+++ b/frontend/src/features/navigation/types/navigation.types.ts
@@ -0,0 +1,9 @@
+export interface NavLink {
+ label: string;
+ href: string;
+}
+
+export interface NavigationProps {
+ links?: NavLink[];
+ logo?: string;
+}
diff --git a/package-lock.json b/package-lock.json
index c61d591b..8f7860d7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,8 @@
"dependencies": {
"next": "15.2.4",
"react": "^19.0.0",
- "react-dom": "^19.0.0"
+ "react-dom": "^19.0.0",
+ "react-icons": "^5.6.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
@@ -143,6 +144,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz",
"integrity": "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==",
"devOptional": true,
+ "peer": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
@@ -170,6 +172,7 @@
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-7.0.5.tgz",
"integrity": "sha512-3KptlJtcYDPWohk0MfJU75MJFh2ybavbtcSd84zEPfw9s1q3hjimw3sXnH03ZxP54kiEWldvKmmnGcVffBDB1g==",
+ "peer": true,
"dependencies": {
"expo-constants": "~17.0.5",
"invariant": "^2.2.4"
@@ -355,8 +358,7 @@
"version": "0.25.0-rc-6230622a1a-20240610",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0-rc-6230622a1a-20240610.tgz",
"integrity": "sha512-GTIQdJXthps5mgkIFo7yAq03M0QQYTfN8z+GrnMC/SCKFSuyFP5tk2BMaaWUsVy4u4r+dTLdiXH8JEivVls0Bw==",
- "dev": true,
- "peer": true
+ "dev": true
},
"mobile/node_modules/json5": {
"version": "2.2.3",
@@ -374,6 +376,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -385,6 +388,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -419,6 +423,7 @@
"version": "0.76.9",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.76.9.tgz",
"integrity": "sha512-+LRwecWmTDco7OweGsrECIqJu0iyrREd6CTCgC/uLLYipiHvk+MH9nd6drFtCw/6Blz6eoKTcH9YTTJusNtrWg==",
+ "peer": true,
"dependencies": {
"@jest/create-cache-key-function": "^29.6.3",
"@react-native/assets-registry": "0.76.9",
@@ -507,6 +512,7 @@
"version": "3.16.7",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.16.7.tgz",
"integrity": "sha512-qoUUQOwE1pHlmQ9cXTJ2MX9FQ9eHllopCLiWOkDkp6CER95ZWeXhJCP4cSm6AD4jigL5jHcZf/SkWrg8ttZUsw==",
+ "peer": true,
"dependencies": {
"@babel/plugin-transform-arrow-functions": "^7.0.0-0",
"@babel/plugin-transform-class-properties": "^7.0.0-0",
@@ -530,6 +536,7 @@
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.12.0.tgz",
"integrity": "sha512-ukk5PxcF4p3yu6qMZcmeiZgowhb5AsKRnil54YFUUAXVIS7PJcMHGGC+q44fCiBg44/1AJk5njGMez1m9H0BVQ==",
+ "peer": true,
"peerDependencies": {
"react": "*",
"react-native": "*"
@@ -539,6 +546,7 @@
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.4.0.tgz",
"integrity": "sha512-c7zc7Zwjty6/pGyuuvh9gK3YBYqHPOxrhXfG1lF4gHlojQSmIx2piNbNaV+Uykj+RDTmFXK0e/hA+fucw/Qozg==",
+ "peer": true,
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -552,6 +560,7 @@
"version": "0.19.13",
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.13.tgz",
"integrity": "sha512-etv3bN8rJglrRCp/uL4p7l8QvUNUC++QwDbdZ8CB7BvZiMvsxfFIRM1j04vxNldG3uo2puRd6OSWR3ibtmc29A==",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.18.6",
"@react-native/normalize-colors": "^0.74.1",
@@ -711,6 +720,7 @@
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
"integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
+ "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.2",
@@ -1119,7 +1129,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
"integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/traverse": "^7.25.9"
@@ -1135,7 +1144,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
"integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1150,7 +1158,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
"integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1165,7 +1172,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
"integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
@@ -1182,7 +1188,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
"integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/traverse": "^7.25.9"
@@ -1277,7 +1282,6 @@
"version": "7.21.0-placeholder-for-preset-env.2",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
"integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
- "peer": true,
"engines": {
"node": ">=6.9.0"
},
@@ -1389,7 +1393,6 @@
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
"integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1562,7 +1565,6 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
"integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
"@babel/helper-plugin-utils": "^7.18.6"
@@ -1624,7 +1626,6 @@
"version": "7.26.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz",
"integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.26.5"
},
@@ -1668,7 +1669,6 @@
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
"integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
- "peer": true,
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -1740,7 +1740,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
"integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -1756,7 +1755,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
"integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1771,7 +1769,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
"integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -1787,7 +1784,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
"integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1802,7 +1798,6 @@
"version": "7.26.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz",
"integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1877,7 +1872,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
"integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1920,7 +1914,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
"integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -1935,7 +1928,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
"integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
- "peer": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -1966,7 +1958,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
"integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
- "peer": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9",
@@ -1984,7 +1975,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
"integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
- "peer": true,
"dependencies": {
"@babel/helper-module-transforms": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -2015,7 +2005,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
"integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -2074,7 +2063,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
"integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9",
"@babel/helper-replace-supers": "^7.25.9"
@@ -2164,7 +2152,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
"integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -2283,7 +2270,6 @@
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
"integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -2299,7 +2285,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
"integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -2398,7 +2383,6 @@
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz",
"integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.26.5"
},
@@ -2431,7 +2415,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
"integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.25.9"
},
@@ -2446,7 +2429,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
"integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -2477,7 +2459,6 @@
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
"integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
- "peer": true,
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.25.9",
"@babel/helper-plugin-utils": "^7.25.9"
@@ -2576,7 +2557,6 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "peer": true,
"bin": {
"semver": "bin/semver.js"
}
@@ -2601,7 +2581,6 @@
"version": "0.1.6-no-external-plugins",
"resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
"integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
- "peer": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/types": "^7.4.4",
@@ -5450,7 +5429,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.78.2.tgz",
"integrity": "sha512-y/wVRUz1ImR2hKKUXFroTdSBiL0Dd+oudzqcGKp/M8Ybrw9MQ0m2QCXxtyONtDn8qkEGceqllwTCKq5WQwJcew==",
- "peer": true,
"dependencies": {
"invariant": "^2.2.4",
"nullthrows": "^1.1.1"
@@ -5532,6 +5510,7 @@
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.5.tgz",
"integrity": "sha512-r3XonOO3b/73rSu3tisU1apcMCmiMhKTC424Hr9XO8Gy6lLVRlfCJS6r+JLGeyLMR8l2zURoWukPHfCcvIcfhQ==",
+ "peer": true,
"dependencies": {
"@react-navigation/core": "^7.8.4",
"escape-string-regexp": "^4.0.0",
@@ -5941,7 +5920,6 @@
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
"integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true,
- "peer": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@@ -5952,7 +5930,6 @@
"resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
"dev": true,
- "peer": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
@@ -6057,6 +6034,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz",
"integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==",
"devOptional": true,
+ "peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -6147,6 +6125,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz",
"integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==",
"dev": true,
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/types": "8.29.0",
@@ -6561,7 +6540,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
"integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.13.2",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2"
@@ -6571,29 +6549,25 @@
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
"integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
"integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
"integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
"integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.13.2",
"@webassemblyjs/helper-api-error": "1.13.2",
@@ -6604,15 +6578,13 @@
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
"integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
"integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@@ -6625,7 +6597,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
"integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"dev": true,
- "peer": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
@@ -6635,7 +6606,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
"integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"dev": true,
- "peer": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
@@ -6644,15 +6614,13 @@
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
"integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
"integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@@ -6669,7 +6637,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
"integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2",
@@ -6683,7 +6650,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
"integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@@ -6696,7 +6662,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
"integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-api-error": "1.13.2",
@@ -6711,7 +6676,6 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
"integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"dev": true,
- "peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
@@ -6730,15 +6694,13 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/abab": {
"version": "2.0.6",
@@ -6774,6 +6736,7 @@
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -7573,6 +7536,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001688",
"electron-to-chromium": "^1.5.73",
@@ -7901,7 +7865,6 @@
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
"dev": true,
- "peer": true,
"engines": {
"node": ">=6.0"
}
@@ -9077,8 +9040,7 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
"integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
@@ -9184,6 +9146,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.24.0.tgz",
"integrity": "sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==",
"dev": true,
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -9351,6 +9314,7 @@
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@@ -9615,7 +9579,6 @@
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"dev": true,
- "peer": true,
"engines": {
"node": ">=0.8.x"
}
@@ -9676,6 +9639,7 @@
"version": "52.0.44",
"resolved": "https://registry.npmjs.org/expo/-/expo-52.0.44.tgz",
"integrity": "sha512-qj3+MWxmqLyBaYQ8jDOvVLEgSqNplH3cf+nDhxCo4C1cpTPD1u/HGh1foibtaeuCYLHsE5km1lrcOpRbFJ4luQ==",
+ "peer": true,
"dependencies": {
"@babel/runtime": "^7.20.0",
"@expo/cli": "0.22.24",
@@ -9740,6 +9704,7 @@
"version": "17.0.8",
"resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-17.0.8.tgz",
"integrity": "sha512-XfWRyQAf1yUNgWZ1TnE8pFBMqGmFP5Gb+SFSgszxDdOoheB/NI5D4p7q86kI2fvGyfTrxAe+D+74nZkfsGvUlg==",
+ "peer": true,
"dependencies": {
"@expo/config": "~10.0.11",
"@expo/env": "~0.4.2"
@@ -10607,8 +10572,7 @@
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "dev": true,
- "peer": true
+ "dev": true
},
"node_modules/globals": {
"version": "14.0.0",
@@ -11644,6 +11608,7 @@
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
"integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
"dev": true,
+ "peer": true,
"dependencies": {
"@jest/core": "^29.7.0",
"@jest/types": "^29.6.3",
@@ -12910,7 +12875,6 @@
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"dev": true,
- "peer": true,
"engines": {
"node": ">=6.11.5"
}
@@ -14866,7 +14830,6 @@
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
- "peer": true,
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -14919,6 +14882,7 @@
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -14956,6 +14920,7 @@
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
@@ -14979,6 +14944,15 @@
"react": ">=17.0.0"
}
},
+ "node_modules/react-icons": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.6.0.tgz",
+ "integrity": "sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -15080,7 +15054,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.78.2.tgz",
"integrity": "sha512-VHqQqjj1rnh2KQeS3yx4IfFSxIIIDi1jR4yUeC438Q6srwxDohR4W0UkXuSIz0imhlems5eS7yZTjdgSpWHRUQ==",
- "peer": true,
"engines": {
"node": ">=18"
}
@@ -15089,7 +15062,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.78.2.tgz",
"integrity": "sha512-0MnQOhIaOdWbQ3Dx3dz0MBbG+1ggBiyUL+Y+xHAeSDSaiRATT8DIsrSloeJU0A+2p5TxF8ITJyJ6KEQkMyB/Zw==",
- "peer": true,
"dependencies": {
"@babel/traverse": "^7.25.3",
"@react-native/codegen": "0.78.2"
@@ -15102,7 +15074,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.78.2.tgz",
"integrity": "sha512-VGOLhztQY/0vktMXrBr01HUN/iBSdkKBRiiZYfrLqx9fB2ql55gZb/6X9lzItjVyYoOc2jyHXSX8yoSfDcWDZg==",
- "peer": true,
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-proposal-export-default-from": "^7.24.7",
@@ -15161,7 +15132,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.78.2.tgz",
"integrity": "sha512-4r3/W1h22/GAmAMuMRMJWsw/9JGUEDAnSbYNya7zID1XSvizLoA5Yn8Qv+phrRwwsl0eZLxOqONh/nzXJcvpyg==",
- "peer": true,
"dependencies": {
"@babel/parser": "^7.25.3",
"glob": "^7.1.1",
@@ -15182,7 +15152,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.78.2.tgz",
"integrity": "sha512-xqEnpqxvBlm02mRY58L0NBjF25MTHmbaeA2qBx5VtheH/pXL6MHUbtwB1Q2dJrg9XcK0Np1i9h7N5h9gFwA2Mg==",
- "peer": true,
"dependencies": {
"@react-native/dev-middleware": "0.78.2",
"@react-native/metro-babel-transformer": "0.78.2",
@@ -15211,7 +15180,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.78.2.tgz",
"integrity": "sha512-qNJT679OU/cdAKmZxfBFjqTG+ZC5i/4sLyvbcQjFFypunGSOaWl3mMQFQQdCBIQN+DFDPVSUXTPZQK1uI2j/ow==",
- "peer": true,
"engines": {
"node": ">=18"
}
@@ -15220,7 +15188,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.78.2.tgz",
"integrity": "sha512-/u0pGiWVgvx09cYNO4/Okj8v1ZNt4K941pQJPhdwg5AHYuggVHNJjROukXJzZiElYFcJhMfOuxwksiIyx/GAkA==",
- "peer": true,
"dependencies": {
"@isaacs/ttlcache": "^1.4.1",
"@react-native/debugger-frontend": "0.78.2",
@@ -15243,7 +15210,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.78.2.tgz",
"integrity": "sha512-LHgmdrbyK9fcBDdxtn2GLOoDAE+aFHtDHgu6vUZ5CSCi9CMd5Krq8IWAmWjeq+BQr+D1rwSXDAHtOrfJ6qOolA==",
- "peer": true,
"engines": {
"node": ">=18"
}
@@ -15252,7 +15218,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.78.2.tgz",
"integrity": "sha512-b7eCPAs3uogdDeTvOTrU6i8DTTsHyjyp48R5pVakJIREhEx+SkUnlVk11PYjbCKGYjYgN939Tb5b1QWNtdrPIQ==",
- "peer": true,
"engines": {
"node": ">=18"
}
@@ -15261,7 +15226,6 @@
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.78.2.tgz",
"integrity": "sha512-H4614LjcbrG+lUtg+ysMX5RnovY8AwrWj4rH8re6ErfhPFwLQXV0LIrl/fgFpq07Vjc5e3ZXzuKuMJF6l7eeTQ==",
- "peer": true,
"dependencies": {
"@babel/core": "^7.25.2",
"@react-native/babel-preset": "0.78.2",
@@ -15278,14 +15242,12 @@
"node_modules/react-native/node_modules/@react-native/normalize-colors": {
"version": "0.78.2",
"resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.78.2.tgz",
- "integrity": "sha512-CA/3ynRO6/g1LDbqU8ewrv0js/1lU4+j04L7qz6btXbLTDk1UkF+AfpGRJGbIVY9UmFBJ7l1AOmzwutrWb3Txw==",
- "peer": true
+ "integrity": "sha512-CA/3ynRO6/g1LDbqU8ewrv0js/1lU4+j04L7qz6btXbLTDk1UkF+AfpGRJGbIVY9UmFBJ7l1AOmzwutrWb3Txw=="
},
"node_modules/react-native/node_modules/ast-types": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
"integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
- "peer": true,
"dependencies": {
"tslib": "^2.0.1"
},
@@ -15297,7 +15259,6 @@
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz",
"integrity": "sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==",
- "peer": true,
"dependencies": {
"hermes-parser": "0.25.1"
}
@@ -15306,7 +15267,6 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "peer": true,
"dependencies": {
"ms": "2.0.0"
}
@@ -15314,14 +15274,12 @@
"node_modules/react-native/node_modules/hermes-estree": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
- "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
- "peer": true
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="
},
"node_modules/react-native/node_modules/hermes-parser": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
"integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
- "peer": true,
"dependencies": {
"hermes-estree": "0.25.1"
}
@@ -15330,7 +15288,6 @@
"version": "17.3.0",
"resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-17.3.0.tgz",
"integrity": "sha512-LjFrGOIORqXBU+jwfC9nbkjmQfFldtMIoS6d9z2LG/lkmyNXsJAySPT+2SWXJEoE68/bCWcxKpXH37npftgmow==",
- "peer": true,
"dependencies": {
"@babel/core": "^7.24.7",
"@babel/parser": "^7.24.7",
@@ -15369,14 +15326,12 @@
"node_modules/react-native/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "peer": true
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/react-native/node_modules/react-devtools-core": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.1.tgz",
"integrity": "sha512-TFo1MEnkqE6hzAbaztnyR5uLTMoz6wnEWwWBsCUzNt+sVXJycuRJdDqvL078M4/h65BI/YO5XWTaxZDWVsW0fw==",
- "peer": true,
"dependencies": {
"shell-quote": "^1.6.1",
"ws": "^7"
@@ -15386,7 +15341,6 @@
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
- "peer": true,
"engines": {
"node": ">=8.3.0"
},
@@ -15407,7 +15361,6 @@
"version": "0.23.11",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz",
"integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==",
- "peer": true,
"dependencies": {
"ast-types": "^0.16.1",
"esprima": "~4.0.0",
@@ -15422,14 +15375,12 @@
"node_modules/react-native/node_modules/scheduler": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz",
- "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==",
- "peer": true
+ "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="
},
"node_modules/react-native/node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "peer": true,
"engines": {
"node": ">=14"
},
@@ -15441,7 +15392,6 @@
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
"integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
- "peer": true,
"engines": {
"node": ">=14.14"
}
@@ -15450,7 +15400,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
"integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
- "peer": true,
"dependencies": {
"imurmurhash": "^0.1.4",
"signal-exit": "^4.0.1"
@@ -15916,6 +15865,7 @@
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -16015,7 +15965,6 @@
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
- "peer": true,
"dependencies": {
"randombytes": "^2.1.0"
}
@@ -17082,7 +17031,6 @@
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
"integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
"dev": true,
- "peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
@@ -17117,7 +17065,6 @@
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
"dev": true,
- "peer": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -17132,7 +17079,6 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
- "peer": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -17193,8 +17139,7 @@
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
- "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
- "peer": true
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="
},
"node_modules/tinyglobby": {
"version": "0.2.12",
@@ -17231,6 +17176,7 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -17465,6 +17411,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -17785,7 +17732,6 @@
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
"integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
"dev": true,
- "peer": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -17824,7 +17770,6 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.0.tgz",
"integrity": "sha512-//MpHjkKV7dhKheJ1lJuHkR6tv8ycfYy7YVzVhhIpwKuKCu5/Zty/vGpFi0fV2RRAWTYDuj6oKn4vYyLzRh55g==",
"dev": true,
- "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.6",
@@ -17871,7 +17816,6 @@
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
"dev": true,
- "peer": true,
"engines": {
"node": ">=10.13.0"
}
@@ -17881,7 +17825,6 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"dev": true,
- "peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -17895,7 +17838,6 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true,
- "peer": true,
"engines": {
"node": ">=4.0"
}