diff --git a/src/App.tsx b/src/App.tsx index 476f13e..11a64ab 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,24 +1,23 @@ 'use client'; import React, { useEffect } from 'react'; -import { TooltipProvider } from './components/ui/better-tooltip'; +import { TooltipProvider } from './components/ui/BetterTooltip'; // Providers -import { AuthProvider } from './features/auth/AuthProvider'; +import { AuthProvider } from './features/auth/context/AuthProvider'; import { EntriesProvider } from './features/statements/context/EntriesProvider'; -import { QuestionsProvider } from './providers/QuestionsProvider'; -import { HelpProvider } from './components/ui/tour'; +import { QuestionsProvider } from './features/questions/context/QuestionsProvider'; +import { HelpProvider } from './features/help'; // Components import LoginPage from './features/auth/components/LoginPage'; -import Header from './layouts/components/Header'; -import MainPage from './layouts/components/MainPage'; +import { Header, MainPage } from './components/layout'; import MockNotification from './features/auth/components/MockNotification'; // Hooks and Utilities import { useEntries } from './features/statements/hooks/useEntries'; import { useAuth } from './features/auth/api/hooks'; -import { handleMagicLinkVerification } from './features/auth/authUtils'; +import { handleMagicLinkVerification } from './features/auth/utils/authUtils'; // Outer Component: Responsible only for setting up the environment (the providers) for the rest of the app. const AppContent: React.FC = () => { @@ -33,43 +32,59 @@ const AppContent: React.FC = () => { verifyToken(); }, []); - + // Force synchronization between auth state and entries state when component mounts useEffect(() => { if (authState.user && authState.isAuthenticated) { - console.log('AppContent: Found authenticated user, dispatching event:', authState.user); + console.log( + 'AppContent: Found authenticated user, dispatching event:', + authState.user + ); // Dispatch event to ensure EntriesProvider gets the user data - window.dispatchEvent(new CustomEvent('authStateChanged', { - detail: { user: authState.user } - })); + window.dispatchEvent( + new CustomEvent('authStateChanged', { + detail: { user: authState.user }, + }) + ); } }, [authState.user, authState.isAuthenticated]); - + // Listen for magic link verification and ensure user email is saved to entries context useEffect(() => { - const handleMagicLinkVerified = (event: any) => { + interface MagicLinkVerifiedEvent extends CustomEvent { + detail: { + user: { + email: string; + [key: string]: unknown; + }; + }; + } + + const handleMagicLinkVerified = (event: MagicLinkVerifiedEvent) => { if (event.detail?.user?.email) { - console.log('App: Magic link verified with email:', event.detail.user.email); + console.log( + 'App: Magic link verified with email:', + event.detail.user.email + ); // Dispatch event with user email to entries context - window.dispatchEvent(new CustomEvent('authStateChanged', { - detail: { user: { email: event.detail.user.email }} - })); + window.dispatchEvent( + new CustomEvent('authStateChanged', { + detail: { user: { email: event.detail.user.email } }, + }) + ); } }; - - window.addEventListener('magicLinkVerified', handleMagicLinkVerified); - return () => window.removeEventListener('magicLinkVerified', handleMagicLinkVerified); + + window.addEventListener('magicLinkVerified', handleMagicLinkVerified as EventListener); + return () => + window.removeEventListener('magicLinkVerified', handleMagicLinkVerified as EventListener); }, []); return ( // MainPage and Header receives the username from context. <> - {data.username ? ( - - ) : ( - - )} + {data.username ? : } > ); }; diff --git a/src/layouts/components/Footer.tsx b/src/components/layout/Footer.tsx similarity index 100% rename from src/layouts/components/Footer.tsx rename to src/components/layout/Footer.tsx diff --git a/src/layouts/components/Header.tsx b/src/components/layout/Header.tsx similarity index 85% rename from src/layouts/components/Header.tsx rename to src/components/layout/Header.tsx index 5735ec0..9f4469c 100644 --- a/src/layouts/components/Header.tsx +++ b/src/components/layout/Header.tsx @@ -1,9 +1,9 @@ -// src/components/Header.tsx +// src/components/layout/Header.tsx import React, { useState } from 'react'; -import { useEntries } from '../../features/statements/hooks/useEntries'; -import SmallCircularQuestionCounter from '../../components/ui/questionCounter/smallCircularQuestionCounter'; -import UserDataModal from '../../components/modals/UserDataModal'; -// import { Tooltip, TooltipTrigger, TooltipContent } from '../../components/ui/better-tooltip'; +import { useEntries } from '@/features/statements'; +import { SmallCircularQuestionCounter } from '@/components/ui'; +import { UserDataModal } from '@/components/modals'; +// import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui'; const Header: React.FC = () => { const { data } = useEntries(); diff --git a/src/layouts/components/MainPage.tsx b/src/components/layout/MainPage.tsx similarity index 88% rename from src/layouts/components/MainPage.tsx rename to src/components/layout/MainPage.tsx index 3a26a44..086cc24 100644 --- a/src/layouts/components/MainPage.tsx +++ b/src/components/layout/MainPage.tsx @@ -5,14 +5,14 @@ import { Tooltip, TooltipTrigger, TooltipContent, -} from '../../components/ui/better-tooltip'; -import StatementList from '../../features/statements/components/StatementList'; -import { useEntries } from '../../features/statements/hooks/useEntries'; -import { Button } from '../../components/ui/button'; + Button +} from '@/components/ui'; +import { StatementList } from '@/features/statements/components'; +import { useEntries } from '@/features/statements'; import { Mail } from 'lucide-react'; -import StatementWizard from '../../features/wizard/components/StatementWizard'; -import ShareEmailModal from '../../components/modals/ShareEmailModal'; -// import TestStatementButton from '../../components/debug/TestButton'; +import StatementWizard from '@/features/wizard/components/StatementWizard'; +import { ShareEmailModal } from '@/components/modals'; +// import TestStatementButton from '@/components/debug/TestButton'; import Footer from './Footer'; const MainPage: React.FC = () => { diff --git a/src/components/layout/index.ts b/src/components/layout/index.ts new file mode 100644 index 0000000..8cb505e --- /dev/null +++ b/src/components/layout/index.ts @@ -0,0 +1,10 @@ +/** + * Barrel file for layout components + * + * Provides unified access to structural page components + * including header, footer, and main content containers. + */ + +export { default as Header } from './Header'; +export { default as Footer } from './Footer'; +export { default as MainPage } from './MainPage'; \ No newline at end of file diff --git a/src/components/modals/GratitudeModal.tsx b/src/components/modals/GratitudeModal.tsx index bc7c620..7f2a6a7 100644 --- a/src/components/modals/GratitudeModal.tsx +++ b/src/components/modals/GratitudeModal.tsx @@ -5,10 +5,10 @@ import { SimpleDialog as Dialog, SimpleDialogContent as DialogContent, SimpleDialogDescription as DialogDescription, -} from '../ui/simple-dialog'; -import { Button } from '../ui/button'; +} from '../ui/Dialog'; +import { Button } from '../ui/Button'; import { Loader2, Heart } from 'lucide-react'; -import { sendGratitude } from '../../features/email/api/gratitudeApi'; +import { sendGratitude } from '../../features/email/api/emailGratitudeApi'; import { useEntries } from '../../features/statements/hooks/useEntries'; import { Action } from '../../types/entries'; @@ -115,8 +115,8 @@ const GratitudeModal: React.FC = ({ > {/* Heart decoration - smaller on mobile */} - - + + @@ -144,7 +144,9 @@ const GratitudeModal: React.FC = ({ Action - {action.action} + + {action.action} + {action.byDate && ( Due by: {action.byDate} @@ -191,8 +193,8 @@ const GratitudeModal: React.FC = ({ > )} - diff --git a/src/components/modals/ShareEmailModal.tsx b/src/components/modals/ShareEmailModal.tsx index f7780f2..9ed8988 100644 --- a/src/components/modals/ShareEmailModal.tsx +++ b/src/components/modals/ShareEmailModal.tsx @@ -5,12 +5,12 @@ import { SimpleDialog as Dialog, SimpleDialogContent as DialogContent, SimpleDialogDescription as DialogDescription, -} from '../ui/simple-dialog'; -import { Button } from '../ui/button'; -import { useEntries } from '../../features/statements/hooks/useEntries'; -import { shareStatements } from '../../features/email/api/emailApi'; +} from '@/components/ui/Dialog'; +import { Button } from '@/components/ui/Button'; +import { useEntries } from '@/features/statements'; +import { shareStatements } from '@/features/email/api/emailStatementsApi'; import { Loader2 } from 'lucide-react'; -import { getVerbName } from '../../lib/utils/verbUtils'; +import { getVerbName } from '@/lib/utils/verbUtils'; import PrivacyModal from './PrivacyModal'; const ShareEmailModal: React.FC<{ onClose: () => void }> = ({ onClose }) => { diff --git a/src/components/modals/UserDataModal.tsx b/src/components/modals/UserDataModal.tsx index 7a0e9c6..9548d00 100644 --- a/src/components/modals/UserDataModal.tsx +++ b/src/components/modals/UserDataModal.tsx @@ -1,13 +1,13 @@ 'use client'; import React, { useState, useEffect, useRef } from 'react'; -import { useEntries } from '../../features/statements/hooks/useEntries'; -import { useAuth } from '../../features/auth/api/hooks'; -import { Button } from '../ui/button'; +import { useEntries } from '@/features/statements'; +import { useAuth } from '@/features/auth/api/hooks'; +import { Button } from '@/components/ui/Button'; import { Save, X, User, Mail, Award, Edit2, LogOut } from 'lucide-react'; -import { validateEmail } from '../../lib/utils/validateEmail'; -import QuestionCounter from '../ui/questionCounter/QuestionCounter'; -import ProgressWithFeedback from '../ui/progress/ProgressWithFeedback'; +import { validateEmail } from '@/lib/utils/validateEmail'; +import { QuestionCounter } from '@/components/ui'; +import ProgressWithFeedback from '@/features/progress/components/ProgressWithFeedback'; interface UserDataModalProps { onOpenChange: (open: boolean) => void; diff --git a/src/components/modals/index.ts b/src/components/modals/index.ts new file mode 100644 index 0000000..e6e6b48 --- /dev/null +++ b/src/components/modals/index.ts @@ -0,0 +1,12 @@ +/** + * Barrel file for modal components + * + * Provides unified access to modal dialog components + * for various purposes throughout the application. + */ + +export { default as GratitudeModal } from './GratitudeModal'; +export { default as PrivacyModal } from './PrivacyModal'; +export { default as ShareEmailModal } from './ShareEmailModal'; +export { default as TermsModal } from './TermsModal'; +export { default as UserDataModal } from './UserDataModal'; \ No newline at end of file diff --git a/src/components/ui/better-tooltip.tsx b/src/components/ui/BetterTooltip.tsx similarity index 95% rename from src/components/ui/better-tooltip.tsx rename to src/components/ui/BetterTooltip.tsx index 75eba2d..25c5039 100644 --- a/src/components/ui/better-tooltip.tsx +++ b/src/components/ui/BetterTooltip.tsx @@ -142,11 +142,10 @@ export const TooltipContent: React.FC<{ children: React.ReactNode; className?: string; sideOffset?: number; -}> = ( - // We're intentionally not using the props here but TooltipContent element acts as a data container - { children: _children } -) => { - return null; // This doesn't render directly, content is passed to portal via context +}> = () => { + // This component doesn't render its children directly + // Content is passed to portal via context in the parent Tooltip component + return null; }; // Portal component that actually renders the tooltip @@ -212,7 +211,7 @@ const TooltipPortal: React.FC = () => { window.removeEventListener('resize', updatePosition); window.removeEventListener('scroll', updatePosition); }; - }, [open, triggerRef.current, tooltipRef.current, isMobile]); + }, [open, triggerRef, tooltipRef, isMobile]); if (!open) return null; diff --git a/src/components/ui/button.tsx b/src/components/ui/Button.tsx similarity index 88% rename from src/components/ui/button.tsx rename to src/components/ui/Button.tsx index dd5d961..f0ab423 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/Button.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; -import { Slot } from './simple-slot'; +import { Slot } from './Slot'; import type { VariantProps } from 'class-variance-authority'; import { cn } from '@/lib/utils'; -import { buttonVariants } from './buttonVariants'; +import { buttonVariants } from './ButtonVariants'; export interface ButtonProps extends React.ButtonHTMLAttributes, @@ -23,6 +23,7 @@ const Button = React.forwardRef( ); } ); + Button.displayName = 'Button'; export { Button }; diff --git a/src/components/ui/buttonVariants.ts b/src/components/ui/ButtonVariants.ts similarity index 100% rename from src/components/ui/buttonVariants.ts rename to src/components/ui/ButtonVariants.ts diff --git a/src/components/ui/confirmation-dialog.tsx b/src/components/ui/ConfirmationDialog.tsx similarity index 98% rename from src/components/ui/confirmation-dialog.tsx rename to src/components/ui/ConfirmationDialog.tsx index 3f82aab..ad5671f 100644 --- a/src/components/ui/confirmation-dialog.tsx +++ b/src/components/ui/ConfirmationDialog.tsx @@ -1,4 +1,4 @@ -import { Button } from './button'; +import { Button } from './Button'; interface ConfirmationDialogProps { isOpen: boolean; onClose: () => void; diff --git a/src/components/ui/simple-dialog.tsx b/src/components/ui/Dialog.tsx similarity index 51% rename from src/components/ui/simple-dialog.tsx rename to src/components/ui/Dialog.tsx index e13021d..8d64862 100644 --- a/src/components/ui/simple-dialog.tsx +++ b/src/components/ui/Dialog.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; import { cn } from '@/lib/utils'; -import { SimpleDialogContext } from './simple-dialog-context'; +import { SimpleDialogContext } from './DialogContext'; interface SimpleDialogProps { isOpen?: boolean; @@ -34,94 +34,107 @@ interface SimpleDialogDescriptionProps { className?: string; } -const SimpleDialogPortal: React.FC<{ children: React.ReactNode }> = ({ children }) => { +const SimpleDialogPortal: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { return <>{children}>; }; -const SimpleDialogOverlay: React.FC<{ className?: string; onClick?: () => void }> = ({ - className, - onClick -}) => { +const SimpleDialogOverlay: React.FC<{ + className?: string; + onClick?: () => void; +}> = ({ className, onClick }) => { return ( - ); }; -const SimpleDialogContent = React.forwardRef( - ({ className, children, headerTitle, onOpenAutoFocus, ...props }, ref) => { - // Always define the useEffect, but make its behavior conditional inside - useEffect(() => { - if (onOpenAutoFocus) { - const handler = (e: Event) => { - onOpenAutoFocus(e); - }; - document.addEventListener('focus', handler, { once: true }); - return () => document.removeEventListener('focus', handler); - } - // Return empty cleanup function when onOpenAutoFocus is not provided - return () => {}; - }, [onOpenAutoFocus]); - - // Stop click propagation to prevent closing the dialog when clicking content - const handleContentClick = (e: React.MouseEvent) => { - e.stopPropagation(); - }; +const SimpleDialogContent = React.forwardRef< + HTMLDivElement, + SimpleDialogContentProps +>(({ className, children, headerTitle, onOpenAutoFocus, ...props }, ref) => { + // Always define the useEffect, but make its behavior conditional inside + useEffect(() => { + if (onOpenAutoFocus) { + const handler = (e: Event) => { + onOpenAutoFocus(e); + }; + document.addEventListener('focus', handler, { once: true }); + return () => document.removeEventListener('focus', handler); + } + // Return empty cleanup function when onOpenAutoFocus is not provided + return () => {}; + }, [onOpenAutoFocus]); + + // Stop click propagation to prevent closing the dialog when clicking content + const handleContentClick = (e: React.MouseEvent) => { + e.stopPropagation(); + }; - return ( - - {/* If there's a header title, add it as a styled header */} - {headerTitle && ( - - {headerTitle} - - )} - {/* Main content with scroll capability */} - - {children} + return ( + + {/* If there's a header title, add it as a styled header */} + {headerTitle && ( + + + {headerTitle} + - - ); - } -); + )} + {/* Main content with scroll capability */} + {children} + + ); +}); SimpleDialogContent.displayName = 'SimpleDialogContent'; -const SimpleDialogClose: React.FC<{ children: React.ReactNode; className?: string; asChild?: boolean }> = ({ - children, - className, -}) => { - return ( - - {children} - - ); +const SimpleDialogClose: React.FC<{ + children: React.ReactNode; + className?: string; + asChild?: boolean; +}> = ({ children, className }) => { + return {children}; }; -const SimpleDialogTitle: React.FC = ({ children, className }) => { +const SimpleDialogTitle: React.FC = ({ + children, + className, +}) => { return ( - + {children} ); }; -const SimpleDialogDescription: React.FC = ({ children, className }) => { +const SimpleDialogDescription: React.FC = ({ + children, + className, +}) => { return ( - + {children} ); @@ -129,53 +142,61 @@ const SimpleDialogDescription: React.FC = ({ child // Context is now imported from separate file -const SimpleDialogTrigger: React.FC = ({ children }) => { +const SimpleDialogTrigger: React.FC = ({ + children, +}) => { // Get the dialog context to control the dialog's open state const { onOpenChange } = React.useContext(SimpleDialogContext); - + // Create a clickable wrapper that opens the dialog const handleClick = (e: React.MouseEvent) => { e.preventDefault(); console.log('SimpleDialogTrigger: Opening dialog'); onOpenChange(true); }; - + // If asChild is true, we'd clone the child element and add an onClick handler // For simplicity, we'll just wrap the children in a div with an onClick return ( - + {children} ); }; -const SimpleDialog: React.FC = ({ - isOpen, +const SimpleDialog: React.FC = ({ + isOpen, open, - onOpenChange, - children, - className + onOpenChange, + children, + className, }) => { // Support both isOpen and open props for compatibility - const isDialogOpen = open !== undefined ? open : isOpen !== undefined ? isOpen : false; - + const isDialogOpen = + open !== undefined ? open : isOpen !== undefined ? isOpen : false; + // Handle ESC key press useEffect(() => { if (!isDialogOpen) return; - + const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onOpenChange(false); } }; - + window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [isDialogOpen, onOpenChange]); // Provide the dialog state to all children via context return ( - + {isDialogOpen ? ( onOpenChange(false)} /> @@ -190,10 +211,10 @@ const SimpleDialog: React.FC = ({ }; // For compatibility with existing code -const SimpleDialogHeader: React.FC<{ className?: string; children: React.ReactNode }> = ({ - className, - children -}) => ( +const SimpleDialogHeader: React.FC<{ + className?: string; + children: React.ReactNode; +}> = ({ className, children }) => ( ); -const SimpleDialogFooter: React.FC<{ className?: string; children: React.ReactNode }> = ({ - className, - children -}) => ( +const SimpleDialogFooter: React.FC<{ + className?: string; + children: React.ReactNode; +}> = ({ className, children }) => ( { children: React.ReactNode; asChild?: boolean; onClick?: (e: React.MouseEvent) => void; className?: string; - [key: string]: any; // Allow any other props } -interface SimpleDropdownMenuContentProps { +interface SimpleDropdownMenuContentProps extends React.HTMLAttributes { children: React.ReactNode; className?: string; sideOffset?: number; - [key: string]: any; + align?: string; } -interface SimpleDropdownMenuItemProps { +interface SimpleDropdownMenuItemProps extends React.HTMLAttributes { children: React.ReactNode; className?: string; onClick?: (e: React.MouseEvent) => void; - [key: string]: any; + disabled?: boolean; + title?: string; } -interface SimpleDropdownMenuSeparatorProps { +interface SimpleDropdownMenuSeparatorProps extends React.HTMLAttributes { className?: string; - [key: string]: any; } // The root dropdown component @@ -58,7 +57,7 @@ const SimpleDropdownMenu: React.FC = ({ children }) => // Pass the open state and toggle function to the children if (child.type === SimpleDropdownMenuTrigger) { - return React.cloneElement(child as React.ReactElement, { + return React.cloneElement(child as React.ReactElement, { onClick: (e: React.MouseEvent) => { e.stopPropagation(); // Prevent event bubbling setIsOpen(!isOpen); @@ -123,14 +122,20 @@ const SimpleDropdownMenuTrigger: React.FC = ({ // The dropdown content container const SimpleDropdownMenuContent = React.forwardRef( ({ children, className, sideOffset = 4, ...props }, ref) => { + // Use sideOffset for positioning + const offsetStyles = { + marginTop: `${sideOffset}px` + }; + return ( {children} diff --git a/src/components/ui/input.tsx b/src/components/ui/Input.tsx similarity index 97% rename from src/components/ui/input.tsx rename to src/components/ui/Input.tsx index 38d70f0..ab36a80 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/Input.tsx @@ -18,6 +18,7 @@ const Input = React.forwardRef< /> ); }); + Input.displayName = 'Input'; -export { Input }; +export { Input }; \ No newline at end of file diff --git a/src/components/ui/simple-label.tsx b/src/components/ui/Label.tsx similarity index 100% rename from src/components/ui/simple-label.tsx rename to src/components/ui/Label.tsx diff --git a/src/components/ui/simple-slot.tsx b/src/components/ui/Slot.tsx similarity index 77% rename from src/components/ui/simple-slot.tsx rename to src/components/ui/Slot.tsx index cf335be..eed4f8c 100644 --- a/src/components/ui/simple-slot.tsx +++ b/src/components/ui/Slot.tsx @@ -2,11 +2,12 @@ import React from 'react'; // A simple Slot component that just renders its children // This is a simplified version that doesn't try to do ref forwarding -const Slot: React.FC<{ - children?: React.ReactNode; +interface SlotProps extends React.HTMLAttributes { + children?: React.ReactNode; className?: string; - [key: string]: any; -}> = ({ +} + +const Slot: React.FC = ({ children, ...props }) => { diff --git a/src/components/ui/simple-tooltip.tsx b/src/components/ui/Tooltip.tsx similarity index 100% rename from src/components/ui/simple-tooltip.tsx rename to src/components/ui/Tooltip.tsx diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts new file mode 100644 index 0000000..41b89ba --- /dev/null +++ b/src/components/ui/index.ts @@ -0,0 +1,44 @@ +/** + * Barrel file for UI components + * + * Provides unified access to reusable UI components + * that serve as building blocks across the application. + */ + +// Export individual UI components +export { Button } from './Button'; +export { Input } from './Input'; +export { Slot } from './Slot'; +export { ConfirmationDialog } from './ConfirmationDialog'; + +// Export dialog components +export { + SimpleDialog, + SimpleDialogContent, + SimpleDialogTitle, + SimpleDialogDescription, + SimpleDialogFooter, + SimpleDialogHeader +} from './Dialog'; + +// Export dropdown components +export { + SimpleDropdownMenu, + SimpleDropdownMenuTrigger, + SimpleDropdownMenuContent, + SimpleDropdownMenuItem, + SimpleDropdownMenuSeparator +} from './Dropdown'; + +// Export tooltip components +export { + Tooltip, + TooltipTrigger, + TooltipContent, + TooltipProvider +} from './BetterTooltip'; + +// Export question counter components +export { default as QuestionCounter } from './questionCounter/QuestionCounter'; +export { default as LargeCircularQuestionCounter } from './questionCounter/LargeCircularQuestionCounter'; +export { default as SmallCircularQuestionCounter } from './questionCounter/SmallCircularQuestionCounter'; \ No newline at end of file diff --git a/src/components/ui/questionCounter/smallCircularQuestionCounter.tsx b/src/components/ui/questionCounter/SmallCircularQuestionCounter.tsx similarity index 100% rename from src/components/ui/questionCounter/smallCircularQuestionCounter.tsx rename to src/components/ui/questionCounter/SmallCircularQuestionCounter.tsx diff --git a/src/data/helpContent.json b/src/data/helpContent.json index 65248a8..4469814 100644 --- a/src/data/helpContent.json +++ b/src/data/helpContent.json @@ -80,6 +80,34 @@ "details": "For each statement, you can choose whether it's private (only visible to you) or public (visible to your line manager). You can change the privacy setting at any time." } ], + + "resources": [ + { + "title": "Communication Guide", + "description": "Comprehensive guide on effective workplace communication strategies.", + "link": "https://example.com/communication-guide" + }, + { + "title": "Manager Conversation Toolkit", + "description": "Tools and templates for having productive conversations with your manager.", + "link": "https://example.com/manager-conversation-toolkit" + }, + { + "title": "Workplace Accommodations FAQ", + "description": "Frequently asked questions about requesting and implementing workplace accommodations.", + "link": "https://example.com/workplace-accommodations-faq" + }, + { + "title": "Career Development Resources", + "description": "Resources to help plan and discuss your career development with your manager.", + "link": "https://example.com/career-development" + }, + { + "title": "Wellbeing Support", + "description": "Information and resources for maintaining wellbeing in the workplace.", + "link": "https://example.com/wellbeing-support" + } + ], "versions": [ { "version": "1.0.0", diff --git a/src/features/auth/api/hooks/index.ts b/src/features/auth/api/hooks/index.ts index cb62303..f5feed4 100644 --- a/src/features/auth/api/hooks/index.ts +++ b/src/features/auth/api/hooks/index.ts @@ -1 +1,7 @@ +/** + * Barrel file for auth hooks exports + * + * Consolidates auth hook exports for cleaner imports. + */ + export * from './useAuth'; \ No newline at end of file diff --git a/src/features/auth/api/hooks/useAuth.ts b/src/features/auth/api/hooks/useAuth.ts index ebd2031..66815d4 100644 --- a/src/features/auth/api/hooks/useAuth.ts +++ b/src/features/auth/api/hooks/useAuth.ts @@ -1,5 +1,5 @@ import { useContext } from 'react'; -import { AuthContext } from '../../AuthContext'; +import { AuthContext } from '../../context/AuthContext'; export const useAuth = () => { const context = useContext(AuthContext); diff --git a/src/features/auth/components/LoginPage.tsx b/src/features/auth/components/LoginPage.tsx index 7822c4f..a7b9e71 100644 --- a/src/features/auth/components/LoginPage.tsx +++ b/src/features/auth/components/LoginPage.tsx @@ -6,7 +6,7 @@ import { useEntries } from '../../statements/hooks/useEntries'; import MagicLinkForm from './MagicLinkForm'; import { Input } from '../../../components/ui/input'; import { Button } from '../../../components/ui/button'; -import { handleMagicLinkVerification } from '../authUtils'; +import { handleMagicLinkVerification } from '../utils/authUtils'; import { Loader2 } from 'lucide-react'; import PrivacyModal from '../../../components/modals/PrivacyModal'; import TermsModal from '../../../components/modals/TermsModal'; diff --git a/src/features/auth/components/MagicLinkForm.tsx b/src/features/auth/components/MagicLinkForm.tsx index 099e3b6..e9a2f0e 100644 --- a/src/features/auth/components/MagicLinkForm.tsx +++ b/src/features/auth/components/MagicLinkForm.tsx @@ -1,8 +1,8 @@ import React, { useState } from 'react'; import { useAuth } from '../api/hooks'; import { validateEmail } from '@/lib/utils/validateEmail'; -import { Input } from '@/components/ui/input'; -import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/Input'; +import { Button } from '@/components/ui/Button'; import { Mail, Loader2 } from 'lucide-react'; interface MagicLinkFormProps { diff --git a/src/features/auth/AuthContext.ts b/src/features/auth/context/AuthContext.ts similarity index 95% rename from src/features/auth/AuthContext.ts rename to src/features/auth/context/AuthContext.ts index 7410e25..707c020 100644 --- a/src/features/auth/AuthContext.ts +++ b/src/features/auth/context/AuthContext.ts @@ -1,5 +1,5 @@ import { createContext } from 'react'; -import { AuthState } from './api/authApi'; +import { AuthState } from '../api/authApi'; // Initial auth state export const initialAuthState: AuthState = { diff --git a/src/features/auth/AuthProvider.tsx b/src/features/auth/context/AuthProvider.tsx similarity index 99% rename from src/features/auth/AuthProvider.tsx rename to src/features/auth/context/AuthProvider.tsx index 8fec6c3..f925166 100644 --- a/src/features/auth/AuthProvider.tsx +++ b/src/features/auth/context/AuthProvider.tsx @@ -5,7 +5,7 @@ import { requestMagicLink as apiRequestMagicLink, signOut as apiSignOut, updateUserProfile -} from './api/authApi'; +} from '../api/authApi'; type AuthAction = | { type: 'AUTH_LOADING' } diff --git a/src/features/auth/index.ts b/src/features/auth/index.ts new file mode 100644 index 0000000..a02a11a --- /dev/null +++ b/src/features/auth/index.ts @@ -0,0 +1,20 @@ +/** + * Barrel file for auth feature + * + * Provides unified access to authentication-related functionality + * including context, providers, hooks, and components. + */ + +// Re-export context and provider +export { AuthContext } from './context/AuthContext'; +export { AuthProvider } from './context/AuthProvider'; + +// Re-export hooks +export { useAuth } from './api/hooks'; + +// Re-export utilities +export { handleMagicLinkVerification } from './utils/authUtils'; + +// Re-export components as needed +export { default as LoginPage } from './components/LoginPage'; +export { default as MagicLinkForm } from './components/MagicLinkForm'; \ No newline at end of file diff --git a/src/features/auth/authUtils.ts b/src/features/auth/utils/authUtils.ts similarity index 96% rename from src/features/auth/authUtils.ts rename to src/features/auth/utils/authUtils.ts index 5fd3bff..585bc20 100644 --- a/src/features/auth/authUtils.ts +++ b/src/features/auth/utils/authUtils.ts @@ -1,4 +1,4 @@ -import { verifyMagicLink } from './api/authApi'; +import { verifyMagicLink } from '../api/authApi'; /** * Extract and verify magic link token from URL diff --git a/src/features/email/api/gratitudeApi.ts b/src/features/email/api/emailGratitudeApi.ts similarity index 100% rename from src/features/email/api/gratitudeApi.ts rename to src/features/email/api/emailGratitudeApi.ts diff --git a/src/features/email/api/emailApi.ts b/src/features/email/api/emailStatementsApi.ts similarity index 80% rename from src/features/email/api/emailApi.ts rename to src/features/email/api/emailStatementsApi.ts index bbf84a4..0bb5c63 100644 --- a/src/features/email/api/emailApi.ts +++ b/src/features/email/api/emailStatementsApi.ts @@ -1,9 +1,9 @@ -import { Email } from "../../../types/emails"; +import { Email } from '../../../types/emails'; // Check if we should use mock implementation const shouldUseMock = () => { return ( - import.meta.env.VITE_MOCK_EMAIL_SENDING === 'true' || + import.meta.env.VITE_MOCK_EMAIL_SENDING === 'true' || typeof import.meta.env.VITE_MOCK_EMAIL_SENDING === 'undefined' ); }; @@ -11,15 +11,15 @@ const shouldUseMock = () => { // Mock implementation of sending email const mockSendEmail = async (email: Email) => { console.log('MOCK: Sending email with:', email); - + // Simulate network delay - await new Promise(resolve => setTimeout(resolve, 800)); - + await new Promise((resolve) => setTimeout(resolve, 800)); + // Return mock success response return { success: true, message: 'Email sent successfully (mock)', - id: `mock-email-${Date.now()}` + id: `mock-email-${Date.now()}`, }; }; @@ -29,7 +29,7 @@ export async function sendEmail(email: Email) { if (shouldUseMock()) { return mockSendEmail(email); } - + // Real implementation try { const response = await fetch('/api/email/send', { @@ -39,31 +39,31 @@ export async function sendEmail(email: Email) { }, body: JSON.stringify(email), }); - + if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || 'Failed to send email'); } - + return await response.json(); } catch (error) { - console.error("Error sending email:", error); + console.error('Error sending email:', error); throw error; } } // Mock implementation of sharing statements const mockShareStatements = async (recipientEmail: string) => { - console.log('MOCK: Sharing statements with:', recipientEmail); - + console.log('MOCK: Sharing statements from:', recipientEmail); + // Simulate network delay - await new Promise(resolve => setTimeout(resolve, 800)); - + await new Promise((resolve) => setTimeout(resolve, 800)); + // Return mock success response return { success: true, message: 'Statements shared successfully (mock)', - id: `mock-share-${Date.now()}` + id: `mock-share-${Date.now()}`, }; }; @@ -73,7 +73,7 @@ export async function shareStatements(recipientEmail: string) { if (shouldUseMock()) { return mockShareStatements(recipientEmail); } - + // Real implementation try { const response = await fetch('/api/email/share-statements', { @@ -83,15 +83,15 @@ export async function shareStatements(recipientEmail: string) { }, body: JSON.stringify({ recipientEmail }), }); - + if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || 'Failed to share statements'); } - + return await response.json(); } catch (error) { - console.error("Error sharing statements:", error); + console.error('Error sharing statements:', error); throw error; } -} \ No newline at end of file +} diff --git a/src/components/ui/tour/HelpButton.tsx b/src/features/help/components/HelpButton.tsx similarity index 100% rename from src/components/ui/tour/HelpButton.tsx rename to src/features/help/components/HelpButton.tsx diff --git a/src/components/ui/tour/HelpCenter.tsx b/src/features/help/components/HelpCenter.tsx similarity index 83% rename from src/components/ui/tour/HelpCenter.tsx rename to src/features/help/components/HelpCenter.tsx index e101149..9f108fd 100644 --- a/src/components/ui/tour/HelpCenter.tsx +++ b/src/features/help/components/HelpCenter.tsx @@ -1,8 +1,8 @@ 'use client'; import React, { useState } from 'react'; -import { X, Info, PlayCircle, BookOpen, History } from 'lucide-react'; -import { Button } from '@/components/ui/button'; +import { X, Info, PlayCircle, BookOpen, History, Link as LinkIcon } from 'lucide-react'; +import { Button } from '@/components/ui/Button'; import helpContent from '@/data/helpContent.json'; interface HelpCenterProps { @@ -10,7 +10,7 @@ interface HelpCenterProps { initialTab?: string; } -type TabType = 'welcome' | 'tutorials' | 'features' | 'versions'; +type TabType = 'welcome' | 'tutorials' | 'features' | 'resources' | 'versions'; const HelpCenter: React.FC = ({ onClose, @@ -73,7 +73,7 @@ const HelpCenter: React.FC = ({ {/* Tabs - grid for mobile, flex for desktop */} - + = ({ Features + handleTabChange('resources')} + > + + Resources + = ({ )} + {/* Resources Tab */} + {activeTab === 'resources' && ( + + + Helpful Resources + + + + {helpContent.resources.map((resource, index) => ( + + + + + {resource.title} + + + {resource.description} + + + + ))} + + + )} + {/* Versions Tab */} {activeTab === 'versions' && ( @@ -272,4 +313,4 @@ const HelpCenter: React.FC = ({ ); }; -export default HelpCenter; +export default HelpCenter; \ No newline at end of file diff --git a/src/components/ui/tour/WelcomePanel.tsx b/src/features/help/components/WelcomePanel.tsx similarity index 98% rename from src/components/ui/tour/WelcomePanel.tsx rename to src/features/help/components/WelcomePanel.tsx index cd73694..465f255 100644 --- a/src/components/ui/tour/WelcomePanel.tsx +++ b/src/features/help/components/WelcomePanel.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { Info, PlayCircle, ArrowRight, X } from 'lucide-react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import helpContent from '@/data/helpContent.json'; interface WelcomePanelProps { diff --git a/src/components/ui/tour/index.ts b/src/features/help/components/index.ts similarity index 71% rename from src/components/ui/tour/index.ts rename to src/features/help/components/index.ts index 8aa8ba7..3ab2076 100644 --- a/src/components/ui/tour/index.ts +++ b/src/features/help/components/index.ts @@ -1,4 +1,3 @@ -export { default as HelpProvider, useHelp } from './HelpProvider'; export { default as HelpButton } from './HelpButton'; export { default as HelpCenter } from './HelpCenter'; export { default as WelcomePanel } from './WelcomePanel'; \ No newline at end of file diff --git a/src/features/help/context/HelpContext.ts b/src/features/help/context/HelpContext.ts new file mode 100644 index 0000000..b896f0b --- /dev/null +++ b/src/features/help/context/HelpContext.ts @@ -0,0 +1,9 @@ +'use client'; + +import { createContext } from 'react'; + +export interface HelpContextType { + showHelpCenter: (tab?: string) => void; +} + +export const HelpContext = createContext(undefined); diff --git a/src/components/ui/tour/HelpProvider.tsx b/src/features/help/context/HelpProvider.tsx similarity index 77% rename from src/components/ui/tour/HelpProvider.tsx rename to src/features/help/context/HelpProvider.tsx index f0deb58..01bbde3 100644 --- a/src/components/ui/tour/HelpProvider.tsx +++ b/src/features/help/context/HelpProvider.tsx @@ -1,23 +1,10 @@ 'use client'; -import React, { createContext, useContext, useState, useEffect } from 'react'; -import WelcomePanel from './WelcomePanel'; -import HelpButton from './HelpButton'; -import HelpCenter from './HelpCenter'; - -interface HelpContextType { - showHelpCenter: (tab?: string) => void; -} - -const HelpContext = createContext(undefined); - -export const useHelp = () => { - const context = useContext(HelpContext); - if (!context) { - throw new Error('useHelp must be used within a HelpProvider'); - } - return context; -}; +import React, { useState, useEffect } from 'react'; +import { HelpContext } from './HelpContext'; +import WelcomePanel from '../components/WelcomePanel'; +import HelpButton from '../components/HelpButton'; +import HelpCenter from '../components/HelpCenter'; interface HelpProviderProps { children: React.ReactNode; @@ -91,6 +78,4 @@ export const HelpProvider: React.FC = ({ children }) => { )} ); -}; - -export default HelpProvider; \ No newline at end of file +}; \ No newline at end of file diff --git a/src/features/help/hooks/useHelp.ts b/src/features/help/hooks/useHelp.ts new file mode 100644 index 0000000..8f051e7 --- /dev/null +++ b/src/features/help/hooks/useHelp.ts @@ -0,0 +1,12 @@ +'use client'; + +import { useContext } from 'react'; +import { HelpContext } from '../context/HelpContext'; + +export const useHelp = () => { + const context = useContext(HelpContext); + if (!context) { + throw new Error('useHelp must be used within a HelpProvider'); + } + return context; +}; diff --git a/src/features/help/index.ts b/src/features/help/index.ts new file mode 100644 index 0000000..70eef64 --- /dev/null +++ b/src/features/help/index.ts @@ -0,0 +1,10 @@ +/** + * Barrel file for help feature + * + * Provides unified access to help center functionality + * including context, providers, hooks, and components. + */ + +export { HelpProvider } from './context/HelpProvider'; +export { useHelp } from './hooks/useHelp'; +export { HelpButton, HelpCenter, WelcomePanel } from './components'; \ No newline at end of file diff --git a/src/components/ui/progress/ProgressWithFeedback.tsx b/src/features/progress/components/ProgressWithFeedback.tsx similarity index 84% rename from src/components/ui/progress/ProgressWithFeedback.tsx rename to src/features/progress/components/ProgressWithFeedback.tsx index 2d8c950..895afe4 100644 --- a/src/components/ui/progress/ProgressWithFeedback.tsx +++ b/src/features/progress/components/ProgressWithFeedback.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useAnsweredCount } from '@/features/questions/hooks/useAnsweredCount'; -import { useProgressFeedback } from '@/hooks/useProgressFeedback'; -import LargeCircularQuestionCounter from '../questionCounter/LargeCircularQuestionCounter'; +import { useProgressFeedback } from '../hooks/useProgressFeedback'; +import { LargeCircularQuestionCounter } from '@/components/ui'; const ProgressWithFeedback: React.FC = () => { const { answered, total } = useAnsweredCount(); diff --git a/src/hooks/useProgressFeedback.ts b/src/features/progress/hooks/useProgressFeedback.ts similarity index 100% rename from src/hooks/useProgressFeedback.ts rename to src/features/progress/hooks/useProgressFeedback.ts diff --git a/src/providers/QuestionsContext.ts b/src/features/questions/context/QuestionsContext.ts similarity index 100% rename from src/providers/QuestionsContext.ts rename to src/features/questions/context/QuestionsContext.ts diff --git a/src/providers/QuestionsProvider.tsx b/src/features/questions/context/QuestionsProvider.tsx similarity index 100% rename from src/providers/QuestionsProvider.tsx rename to src/features/questions/context/QuestionsProvider.tsx diff --git a/src/features/questions/hooks/useQuestions.ts b/src/features/questions/hooks/useQuestions.ts index 02ce37c..0505e16 100644 --- a/src/features/questions/hooks/useQuestions.ts +++ b/src/features/questions/hooks/useQuestions.ts @@ -1,5 +1,5 @@ import { useContext } from 'react'; -import { QuestionsContext } from '../../../providers/QuestionsContext'; +import { QuestionsContext } from '../context/QuestionsContext'; export function useQuestions() { const context = useContext(QuestionsContext); diff --git a/src/features/questions/index.ts b/src/features/questions/index.ts new file mode 100644 index 0000000..80d2166 --- /dev/null +++ b/src/features/questions/index.ts @@ -0,0 +1,14 @@ +/** + * Barrel file for questions feature + * + * Provides unified access to questions-related functionality + * including context, providers, hooks, and components. + */ + +// Re-export context and provider +export { QuestionsContext } from './context/QuestionsContext'; +export { QuestionsProvider } from './context/QuestionsProvider'; + +// Re-export hooks +export { useQuestions } from './hooks/useQuestions'; +export { useAnsweredCount } from './hooks/useAnsweredCount'; \ No newline at end of file diff --git a/src/features/statements/components/ActionLine.tsx b/src/features/statements/components/ActionLine.tsx index 9ab56db..d7cd4fa 100644 --- a/src/features/statements/components/ActionLine.tsx +++ b/src/features/statements/components/ActionLine.tsx @@ -13,19 +13,19 @@ import { SimpleDropdownMenuContent as DropdownMenuContent, SimpleDropdownMenuItem as DropdownMenuItem, SimpleDropdownMenuSeparator as DropdownMenuSeparator, -} from '../../../components/ui/simple-dropdown'; +} from '../../../components/ui/Dropdown'; import ActionForm from './ActionForm'; -import { ConfirmationDialog } from '../../../components/ui/confirmation-dialog'; +import { ConfirmationDialog } from '../../../components/ui/ConfirmationDialog'; import type { Action } from '../../../types/entries'; import { CheckCircle2, XCircle } from 'lucide-react'; import GratitudeModal from '../../../components/modals/GratitudeModal'; -import { markGratitudeSent } from '../../../features/email/api/gratitudeApi'; +import { markGratitudeSent } from '../../email/api/emailGratitudeApi'; import { useEntries } from '../hooks/useEntries'; import { Tooltip, TooltipTrigger, TooltipContent, -} from '../../../components/ui/better-tooltip'; +} from '../../../components/ui/BetterTooltip'; export interface ActionLineProps { statementId: string; @@ -253,16 +253,24 @@ const ActionLine: React.FC = ({ {!action.gratitude?.sent && ( <> - + { if (hasManagerEmail) { setGratitudeModal({ isOpen: true, action }); } }} - className={hasManagerEmail ? "text-pink-600" : "text-pink-300 cursor-not-allowed"} + className={ + hasManagerEmail + ? 'text-pink-600' + : 'text-pink-300 cursor-not-allowed' + } disabled={!hasManagerEmail} - title={!hasManagerEmail ? "Manager's email is required to send gratitude" : ""} + title={ + !hasManagerEmail + ? "Manager's email is required to send gratitude" + : '' + } > Send gratitude diff --git a/src/features/statements/components/QuestionCard.tsx b/src/features/statements/components/QuestionCard.tsx index 95439f2..82e124a 100644 --- a/src/features/statements/components/QuestionCard.tsx +++ b/src/features/statements/components/QuestionCard.tsx @@ -8,7 +8,7 @@ import { Tooltip, TooltipTrigger, TooltipContent, -} from '../../../components/ui/better-tooltip'; +} from '../../../components/ui/BetterTooltip'; export interface QuestionCardProps { presetQuestion: SetQuestion; diff --git a/src/features/statements/components/StatementItem.tsx b/src/features/statements/components/StatementItem.tsx index b450135..8a7c38d 100644 --- a/src/features/statements/components/StatementItem.tsx +++ b/src/features/statements/components/StatementItem.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import { getVerbName } from '@/lib/utils/verbUtils'; import { Trash2, @@ -19,14 +19,14 @@ import { SimpleDropdownMenuTrigger as DropdownMenuTrigger, SimpleDropdownMenuContent as DropdownMenuContent, SimpleDropdownMenuItem as DropdownMenuItem, -} from '@/components/ui/simple-dropdown'; +} from '@/components/ui/Dropdown'; import ActionsCounter from './ActionsCounter'; import ActionLine from './ActionLine'; import { Tooltip, TooltipTrigger, TooltipContent, -} from '@/components/ui/better-tooltip'; +} from '@/components/ui/BetterTooltip'; import statementsCategories from '@/data/statementsCategories.json'; import { formatCategoryName } from '@/lib/utils'; diff --git a/src/features/statements/components/StatementList.tsx b/src/features/statements/components/StatementList.tsx index 7fdf256..2b92786 100644 --- a/src/features/statements/components/StatementList.tsx +++ b/src/features/statements/components/StatementList.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { useEntries } from '../hooks/useEntries'; -import { ConfirmationDialog } from '../../../components/ui/confirmation-dialog'; +import { ConfirmationDialog } from '../../../components/ui/ConfirmationDialog'; import type { Entry, SetQuestion } from '@/types/entries'; import QuestionCard from './QuestionCard'; import StatementItem from './StatementItem'; diff --git a/src/features/statements/components/index.ts b/src/features/statements/components/index.ts new file mode 100644 index 0000000..35684c1 --- /dev/null +++ b/src/features/statements/components/index.ts @@ -0,0 +1,7 @@ +// Barrel file for statements components +export { default as ActionForm } from './ActionForm'; +export { default as ActionLine } from './ActionLine'; +export { default as ActionsCounter } from './ActionsCounter'; +export { default as QuestionCard } from './QuestionCard'; +export { default as StatementItem } from './StatementItem'; +export { default as StatementList } from './StatementList'; \ No newline at end of file diff --git a/src/features/statements/index.ts b/src/features/statements/index.ts new file mode 100644 index 0000000..7a59ed4 --- /dev/null +++ b/src/features/statements/index.ts @@ -0,0 +1,8 @@ +/** + * Barrel file for statements feature + * + * Provides unified access to statements-related functionality + * including context, providers, hooks, and components. + */ +export { useEntries } from './hooks/useEntries'; +export { EntriesProvider } from './context/EntriesProvider'; \ No newline at end of file diff --git a/src/features/wizard/components/EditStatementModal.tsx b/src/features/wizard/components/EditStatementModal.tsx index 1987da2..f9dc6d7 100644 --- a/src/features/wizard/components/EditStatementModal.tsx +++ b/src/features/wizard/components/EditStatementModal.tsx @@ -4,8 +4,8 @@ import { SimpleDialogContent as DialogContent, SimpleDialogTitle as DialogTitle, SimpleDialogDescription as DialogDescription, -} from '@/components/ui/simple-dialog'; -import { Button } from '@/components/ui/button'; +} from '@/components/ui/Dialog'; +import { Button } from '@/components/ui/Button'; import type { Entry } from '@/types/entries'; import { SubjectStep } from './steps/SubjectStep'; import { VerbStep } from './steps/VerbStep'; @@ -77,7 +77,7 @@ export const EditStatementModal: React.FC = ({ // Create a completely new object with a deeper clone to ensure React detects the change // Force category to be a string to avoid type issues const categoryValue = localValue ? String(localValue) : ''; - + // Create a new object with the modified category const newStatement = { ...statement, @@ -86,7 +86,7 @@ export const EditStatementModal: React.FC = ({ _needsScroll: true, // Flag to indicate this needs scrolling category: categoryValue, }; - + // Deep clone to ensure all references are fresh updatedStatement = JSON.parse(JSON.stringify(newStatement)); diff --git a/src/features/wizard/components/StatementWizard.tsx b/src/features/wizard/components/StatementWizard.tsx index 0195514..700a8ad 100644 --- a/src/features/wizard/components/StatementWizard.tsx +++ b/src/features/wizard/components/StatementWizard.tsx @@ -6,7 +6,7 @@ import { SimpleDialogContent as DialogContent, SimpleDialogDescription as DialogDescription, SimpleDialogTitle as DialogTitle, -} from '@/components/ui/simple-dialog'; +} from '@/components/ui/Dialog'; import { AnimatePresence, motion } from 'framer-motion'; import { useEntries } from '@/features/statements/hooks/useEntries'; import { postNewEntry } from '@/features/statements/api/entriesApi'; @@ -18,7 +18,7 @@ import { CategoryStep } from './steps/CategoryStep'; import { PrivacyStep } from './steps/PrivacyStep'; import { ComplementStep } from './steps/ComplementStep'; import StatementPreview from './StatementPreview'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; interface StatementWizardProps { username: string; @@ -82,7 +82,7 @@ const StatementWizard: React.FC = ({ presetId: presetQuestion.id, })); } else { - // For custom statements, set default category to "uncategorised" + // For custom statements, set default category to "uncategorised" // but still show the category screen first setSelection((prev) => ({ ...prev, @@ -313,7 +313,7 @@ const StatementWizard: React.FC = ({ )} Wizard Steps Wizard Steps - + {/* Scrollable Content Area */} @@ -328,7 +328,7 @@ const StatementWizard: React.FC = ({ - + {/* Bottom Section - Always Visible */} {/* Navigation Panel */} diff --git a/src/features/wizard/components/SubjectTiles.tsx b/src/features/wizard/components/SubjectTiles.tsx index 2ef8bc2..e3d6318 100644 --- a/src/features/wizard/components/SubjectTiles.tsx +++ b/src/features/wizard/components/SubjectTiles.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { Button } from '../../../components/ui/button'; +import { Button } from '../../../components/ui/Button'; import descriptorsData from '../../../data/descriptors.json'; import type { SetQuestion, DescriptorsData } from '../../../types/entries'; diff --git a/src/features/wizard/components/VerbGrid.tsx b/src/features/wizard/components/VerbGrid.tsx index c49706b..102758a 100644 --- a/src/features/wizard/components/VerbGrid.tsx +++ b/src/features/wizard/components/VerbGrid.tsx @@ -1,7 +1,7 @@ 'use client'; import React from 'react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import type { Verb, Category } from '@/types/entries'; import { getVerbColor } from '@/lib/utils/categoryUtils'; import { getContrastColor } from '@/lib/utils/colorUtils'; diff --git a/src/features/wizard/components/index.ts b/src/features/wizard/components/index.ts new file mode 100644 index 0000000..68d4534 --- /dev/null +++ b/src/features/wizard/components/index.ts @@ -0,0 +1,10 @@ +// Barrel file for wizard components +export { default as StatementWizard } from './StatementWizard'; +export { default as StatementPreview } from './StatementPreview'; +export { EditStatementModal } from './EditStatementModal'; +export { default as FilterBar } from './FilterBar'; +export { default as SentimentVerbPicker } from './SentimentVerbPicker'; +export { default as StepContainer } from './StepContainer'; +export { default as SubjectTiles } from './SubjectTiles'; +export { default as VerbGrid } from './VerbGrid'; +export { default as VerbSelector } from './VerbSelector'; \ No newline at end of file diff --git a/src/features/wizard/components/steps/CategoryStep.tsx b/src/features/wizard/components/steps/CategoryStep.tsx index ec08d88..3226699 100644 --- a/src/features/wizard/components/steps/CategoryStep.tsx +++ b/src/features/wizard/components/steps/CategoryStep.tsx @@ -1,7 +1,7 @@ // src/components/statementWizard/steps/CategoryStep.tsx import React from 'react'; import StepContainer from '../StepContainer'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import statementsCategories from '@/data/statementsCategories.json'; interface CategoryStepProps { diff --git a/src/features/wizard/components/steps/PrivacyStep.tsx b/src/features/wizard/components/steps/PrivacyStep.tsx index c120edf..dc578c3 100644 --- a/src/features/wizard/components/steps/PrivacyStep.tsx +++ b/src/features/wizard/components/steps/PrivacyStep.tsx @@ -1,6 +1,6 @@ import React from 'react'; import StepContainer from '../StepContainer'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import { MailX, MailPlus } from 'lucide-react'; import { useEntries } from '@/features/statements/hooks/useEntries'; diff --git a/src/features/wizard/components/steps/index.ts b/src/features/wizard/components/steps/index.ts new file mode 100644 index 0000000..6d4f9e4 --- /dev/null +++ b/src/features/wizard/components/steps/index.ts @@ -0,0 +1,7 @@ +// Barrel file for wizard step components +export { CategoryStep } from './CategoryStep'; +export { ComplementStep } from './ComplementStep'; +export { ObjectStep } from './ObjectStep'; +export { PrivacyStep } from './PrivacyStep'; +export { SubjectStep } from './SubjectStep'; +export { VerbStep } from './VerbStep'; \ No newline at end of file diff --git a/src/lib/utils/ssr-hooks.ts b/src/lib/utils/ssrHooks.ts similarity index 100% rename from src/lib/utils/ssr-hooks.ts rename to src/lib/utils/ssrHooks.ts diff --git a/tsconfig.app.json b/tsconfig.app.json index cf567a6..ec1467a 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -28,7 +28,9 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noUncheckedSideEffectImports": true, + /* Case sensitivity */ + "forceConsistentCasingInFileNames": false }, "include": [ "src"
{action.action}
+ {action.action} +
Due by: {action.byDate} @@ -191,8 +193,8 @@ const GratitudeModal: React.FC = ({ > )} - diff --git a/src/components/modals/ShareEmailModal.tsx b/src/components/modals/ShareEmailModal.tsx index f7780f2..9ed8988 100644 --- a/src/components/modals/ShareEmailModal.tsx +++ b/src/components/modals/ShareEmailModal.tsx @@ -5,12 +5,12 @@ import { SimpleDialog as Dialog, SimpleDialogContent as DialogContent, SimpleDialogDescription as DialogDescription, -} from '../ui/simple-dialog'; -import { Button } from '../ui/button'; -import { useEntries } from '../../features/statements/hooks/useEntries'; -import { shareStatements } from '../../features/email/api/emailApi'; +} from '@/components/ui/Dialog'; +import { Button } from '@/components/ui/Button'; +import { useEntries } from '@/features/statements'; +import { shareStatements } from '@/features/email/api/emailStatementsApi'; import { Loader2 } from 'lucide-react'; -import { getVerbName } from '../../lib/utils/verbUtils'; +import { getVerbName } from '@/lib/utils/verbUtils'; import PrivacyModal from './PrivacyModal'; const ShareEmailModal: React.FC<{ onClose: () => void }> = ({ onClose }) => { diff --git a/src/components/modals/UserDataModal.tsx b/src/components/modals/UserDataModal.tsx index 7a0e9c6..9548d00 100644 --- a/src/components/modals/UserDataModal.tsx +++ b/src/components/modals/UserDataModal.tsx @@ -1,13 +1,13 @@ 'use client'; import React, { useState, useEffect, useRef } from 'react'; -import { useEntries } from '../../features/statements/hooks/useEntries'; -import { useAuth } from '../../features/auth/api/hooks'; -import { Button } from '../ui/button'; +import { useEntries } from '@/features/statements'; +import { useAuth } from '@/features/auth/api/hooks'; +import { Button } from '@/components/ui/Button'; import { Save, X, User, Mail, Award, Edit2, LogOut } from 'lucide-react'; -import { validateEmail } from '../../lib/utils/validateEmail'; -import QuestionCounter from '../ui/questionCounter/QuestionCounter'; -import ProgressWithFeedback from '../ui/progress/ProgressWithFeedback'; +import { validateEmail } from '@/lib/utils/validateEmail'; +import { QuestionCounter } from '@/components/ui'; +import ProgressWithFeedback from '@/features/progress/components/ProgressWithFeedback'; interface UserDataModalProps { onOpenChange: (open: boolean) => void; diff --git a/src/components/modals/index.ts b/src/components/modals/index.ts new file mode 100644 index 0000000..e6e6b48 --- /dev/null +++ b/src/components/modals/index.ts @@ -0,0 +1,12 @@ +/** + * Barrel file for modal components + * + * Provides unified access to modal dialog components + * for various purposes throughout the application. + */ + +export { default as GratitudeModal } from './GratitudeModal'; +export { default as PrivacyModal } from './PrivacyModal'; +export { default as ShareEmailModal } from './ShareEmailModal'; +export { default as TermsModal } from './TermsModal'; +export { default as UserDataModal } from './UserDataModal'; \ No newline at end of file diff --git a/src/components/ui/better-tooltip.tsx b/src/components/ui/BetterTooltip.tsx similarity index 95% rename from src/components/ui/better-tooltip.tsx rename to src/components/ui/BetterTooltip.tsx index 75eba2d..25c5039 100644 --- a/src/components/ui/better-tooltip.tsx +++ b/src/components/ui/BetterTooltip.tsx @@ -142,11 +142,10 @@ export const TooltipContent: React.FC<{ children: React.ReactNode; className?: string; sideOffset?: number; -}> = ( - // We're intentionally not using the props here but TooltipContent element acts as a data container - { children: _children } -) => { - return null; // This doesn't render directly, content is passed to portal via context +}> = () => { + // This component doesn't render its children directly + // Content is passed to portal via context in the parent Tooltip component + return null; }; // Portal component that actually renders the tooltip @@ -212,7 +211,7 @@ const TooltipPortal: React.FC = () => { window.removeEventListener('resize', updatePosition); window.removeEventListener('scroll', updatePosition); }; - }, [open, triggerRef.current, tooltipRef.current, isMobile]); + }, [open, triggerRef, tooltipRef, isMobile]); if (!open) return null; diff --git a/src/components/ui/button.tsx b/src/components/ui/Button.tsx similarity index 88% rename from src/components/ui/button.tsx rename to src/components/ui/Button.tsx index dd5d961..f0ab423 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/Button.tsx @@ -1,9 +1,9 @@ import * as React from 'react'; -import { Slot } from './simple-slot'; +import { Slot } from './Slot'; import type { VariantProps } from 'class-variance-authority'; import { cn } from '@/lib/utils'; -import { buttonVariants } from './buttonVariants'; +import { buttonVariants } from './ButtonVariants'; export interface ButtonProps extends React.ButtonHTMLAttributes, @@ -23,6 +23,7 @@ const Button = React.forwardRef( ); } ); + Button.displayName = 'Button'; export { Button }; diff --git a/src/components/ui/buttonVariants.ts b/src/components/ui/ButtonVariants.ts similarity index 100% rename from src/components/ui/buttonVariants.ts rename to src/components/ui/ButtonVariants.ts diff --git a/src/components/ui/confirmation-dialog.tsx b/src/components/ui/ConfirmationDialog.tsx similarity index 98% rename from src/components/ui/confirmation-dialog.tsx rename to src/components/ui/ConfirmationDialog.tsx index 3f82aab..ad5671f 100644 --- a/src/components/ui/confirmation-dialog.tsx +++ b/src/components/ui/ConfirmationDialog.tsx @@ -1,4 +1,4 @@ -import { Button } from './button'; +import { Button } from './Button'; interface ConfirmationDialogProps { isOpen: boolean; onClose: () => void; diff --git a/src/components/ui/simple-dialog.tsx b/src/components/ui/Dialog.tsx similarity index 51% rename from src/components/ui/simple-dialog.tsx rename to src/components/ui/Dialog.tsx index e13021d..8d64862 100644 --- a/src/components/ui/simple-dialog.tsx +++ b/src/components/ui/Dialog.tsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; import { cn } from '@/lib/utils'; -import { SimpleDialogContext } from './simple-dialog-context'; +import { SimpleDialogContext } from './DialogContext'; interface SimpleDialogProps { isOpen?: boolean; @@ -34,94 +34,107 @@ interface SimpleDialogDescriptionProps { className?: string; } -const SimpleDialogPortal: React.FC<{ children: React.ReactNode }> = ({ children }) => { +const SimpleDialogPortal: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { return <>{children}>; }; -const SimpleDialogOverlay: React.FC<{ className?: string; onClick?: () => void }> = ({ - className, - onClick -}) => { +const SimpleDialogOverlay: React.FC<{ + className?: string; + onClick?: () => void; +}> = ({ className, onClick }) => { return ( - ); }; -const SimpleDialogContent = React.forwardRef( - ({ className, children, headerTitle, onOpenAutoFocus, ...props }, ref) => { - // Always define the useEffect, but make its behavior conditional inside - useEffect(() => { - if (onOpenAutoFocus) { - const handler = (e: Event) => { - onOpenAutoFocus(e); - }; - document.addEventListener('focus', handler, { once: true }); - return () => document.removeEventListener('focus', handler); - } - // Return empty cleanup function when onOpenAutoFocus is not provided - return () => {}; - }, [onOpenAutoFocus]); - - // Stop click propagation to prevent closing the dialog when clicking content - const handleContentClick = (e: React.MouseEvent) => { - e.stopPropagation(); - }; +const SimpleDialogContent = React.forwardRef< + HTMLDivElement, + SimpleDialogContentProps +>(({ className, children, headerTitle, onOpenAutoFocus, ...props }, ref) => { + // Always define the useEffect, but make its behavior conditional inside + useEffect(() => { + if (onOpenAutoFocus) { + const handler = (e: Event) => { + onOpenAutoFocus(e); + }; + document.addEventListener('focus', handler, { once: true }); + return () => document.removeEventListener('focus', handler); + } + // Return empty cleanup function when onOpenAutoFocus is not provided + return () => {}; + }, [onOpenAutoFocus]); + + // Stop click propagation to prevent closing the dialog when clicking content + const handleContentClick = (e: React.MouseEvent) => { + e.stopPropagation(); + }; - return ( - - {/* If there's a header title, add it as a styled header */} - {headerTitle && ( - - {headerTitle} - - )} - {/* Main content with scroll capability */} - - {children} + return ( + + {/* If there's a header title, add it as a styled header */} + {headerTitle && ( + + + {headerTitle} + - - ); - } -); + )} + {/* Main content with scroll capability */} + {children} + + ); +}); SimpleDialogContent.displayName = 'SimpleDialogContent'; -const SimpleDialogClose: React.FC<{ children: React.ReactNode; className?: string; asChild?: boolean }> = ({ - children, - className, -}) => { - return ( - - {children} - - ); +const SimpleDialogClose: React.FC<{ + children: React.ReactNode; + className?: string; + asChild?: boolean; +}> = ({ children, className }) => { + return {children}; }; -const SimpleDialogTitle: React.FC = ({ children, className }) => { +const SimpleDialogTitle: React.FC = ({ + children, + className, +}) => { return ( - + {children} ); }; -const SimpleDialogDescription: React.FC = ({ children, className }) => { +const SimpleDialogDescription: React.FC = ({ + children, + className, +}) => { return ( - + {children} ); @@ -129,53 +142,61 @@ const SimpleDialogDescription: React.FC = ({ child // Context is now imported from separate file -const SimpleDialogTrigger: React.FC = ({ children }) => { +const SimpleDialogTrigger: React.FC = ({ + children, +}) => { // Get the dialog context to control the dialog's open state const { onOpenChange } = React.useContext(SimpleDialogContext); - + // Create a clickable wrapper that opens the dialog const handleClick = (e: React.MouseEvent) => { e.preventDefault(); console.log('SimpleDialogTrigger: Opening dialog'); onOpenChange(true); }; - + // If asChild is true, we'd clone the child element and add an onClick handler // For simplicity, we'll just wrap the children in a div with an onClick return ( - + {children} ); }; -const SimpleDialog: React.FC = ({ - isOpen, +const SimpleDialog: React.FC = ({ + isOpen, open, - onOpenChange, - children, - className + onOpenChange, + children, + className, }) => { // Support both isOpen and open props for compatibility - const isDialogOpen = open !== undefined ? open : isOpen !== undefined ? isOpen : false; - + const isDialogOpen = + open !== undefined ? open : isOpen !== undefined ? isOpen : false; + // Handle ESC key press useEffect(() => { if (!isDialogOpen) return; - + const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onOpenChange(false); } }; - + window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [isDialogOpen, onOpenChange]); // Provide the dialog state to all children via context return ( - + {isDialogOpen ? ( onOpenChange(false)} /> @@ -190,10 +211,10 @@ const SimpleDialog: React.FC = ({ }; // For compatibility with existing code -const SimpleDialogHeader: React.FC<{ className?: string; children: React.ReactNode }> = ({ - className, - children -}) => ( +const SimpleDialogHeader: React.FC<{ + className?: string; + children: React.ReactNode; +}> = ({ className, children }) => ( ); -const SimpleDialogFooter: React.FC<{ className?: string; children: React.ReactNode }> = ({ - className, - children -}) => ( +const SimpleDialogFooter: React.FC<{ + className?: string; + children: React.ReactNode; +}> = ({ className, children }) => ( { children: React.ReactNode; asChild?: boolean; onClick?: (e: React.MouseEvent) => void; className?: string; - [key: string]: any; // Allow any other props } -interface SimpleDropdownMenuContentProps { +interface SimpleDropdownMenuContentProps extends React.HTMLAttributes { children: React.ReactNode; className?: string; sideOffset?: number; - [key: string]: any; + align?: string; } -interface SimpleDropdownMenuItemProps { +interface SimpleDropdownMenuItemProps extends React.HTMLAttributes { children: React.ReactNode; className?: string; onClick?: (e: React.MouseEvent) => void; - [key: string]: any; + disabled?: boolean; + title?: string; } -interface SimpleDropdownMenuSeparatorProps { +interface SimpleDropdownMenuSeparatorProps extends React.HTMLAttributes { className?: string; - [key: string]: any; } // The root dropdown component @@ -58,7 +57,7 @@ const SimpleDropdownMenu: React.FC = ({ children }) => // Pass the open state and toggle function to the children if (child.type === SimpleDropdownMenuTrigger) { - return React.cloneElement(child as React.ReactElement, { + return React.cloneElement(child as React.ReactElement, { onClick: (e: React.MouseEvent) => { e.stopPropagation(); // Prevent event bubbling setIsOpen(!isOpen); @@ -123,14 +122,20 @@ const SimpleDropdownMenuTrigger: React.FC = ({ // The dropdown content container const SimpleDropdownMenuContent = React.forwardRef( ({ children, className, sideOffset = 4, ...props }, ref) => { + // Use sideOffset for positioning + const offsetStyles = { + marginTop: `${sideOffset}px` + }; + return ( {children} diff --git a/src/components/ui/input.tsx b/src/components/ui/Input.tsx similarity index 97% rename from src/components/ui/input.tsx rename to src/components/ui/Input.tsx index 38d70f0..ab36a80 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/Input.tsx @@ -18,6 +18,7 @@ const Input = React.forwardRef< /> ); }); + Input.displayName = 'Input'; -export { Input }; +export { Input }; \ No newline at end of file diff --git a/src/components/ui/simple-label.tsx b/src/components/ui/Label.tsx similarity index 100% rename from src/components/ui/simple-label.tsx rename to src/components/ui/Label.tsx diff --git a/src/components/ui/simple-slot.tsx b/src/components/ui/Slot.tsx similarity index 77% rename from src/components/ui/simple-slot.tsx rename to src/components/ui/Slot.tsx index cf335be..eed4f8c 100644 --- a/src/components/ui/simple-slot.tsx +++ b/src/components/ui/Slot.tsx @@ -2,11 +2,12 @@ import React from 'react'; // A simple Slot component that just renders its children // This is a simplified version that doesn't try to do ref forwarding -const Slot: React.FC<{ - children?: React.ReactNode; +interface SlotProps extends React.HTMLAttributes { + children?: React.ReactNode; className?: string; - [key: string]: any; -}> = ({ +} + +const Slot: React.FC = ({ children, ...props }) => { diff --git a/src/components/ui/simple-tooltip.tsx b/src/components/ui/Tooltip.tsx similarity index 100% rename from src/components/ui/simple-tooltip.tsx rename to src/components/ui/Tooltip.tsx diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts new file mode 100644 index 0000000..41b89ba --- /dev/null +++ b/src/components/ui/index.ts @@ -0,0 +1,44 @@ +/** + * Barrel file for UI components + * + * Provides unified access to reusable UI components + * that serve as building blocks across the application. + */ + +// Export individual UI components +export { Button } from './Button'; +export { Input } from './Input'; +export { Slot } from './Slot'; +export { ConfirmationDialog } from './ConfirmationDialog'; + +// Export dialog components +export { + SimpleDialog, + SimpleDialogContent, + SimpleDialogTitle, + SimpleDialogDescription, + SimpleDialogFooter, + SimpleDialogHeader +} from './Dialog'; + +// Export dropdown components +export { + SimpleDropdownMenu, + SimpleDropdownMenuTrigger, + SimpleDropdownMenuContent, + SimpleDropdownMenuItem, + SimpleDropdownMenuSeparator +} from './Dropdown'; + +// Export tooltip components +export { + Tooltip, + TooltipTrigger, + TooltipContent, + TooltipProvider +} from './BetterTooltip'; + +// Export question counter components +export { default as QuestionCounter } from './questionCounter/QuestionCounter'; +export { default as LargeCircularQuestionCounter } from './questionCounter/LargeCircularQuestionCounter'; +export { default as SmallCircularQuestionCounter } from './questionCounter/SmallCircularQuestionCounter'; \ No newline at end of file diff --git a/src/components/ui/questionCounter/smallCircularQuestionCounter.tsx b/src/components/ui/questionCounter/SmallCircularQuestionCounter.tsx similarity index 100% rename from src/components/ui/questionCounter/smallCircularQuestionCounter.tsx rename to src/components/ui/questionCounter/SmallCircularQuestionCounter.tsx diff --git a/src/data/helpContent.json b/src/data/helpContent.json index 65248a8..4469814 100644 --- a/src/data/helpContent.json +++ b/src/data/helpContent.json @@ -80,6 +80,34 @@ "details": "For each statement, you can choose whether it's private (only visible to you) or public (visible to your line manager). You can change the privacy setting at any time." } ], + + "resources": [ + { + "title": "Communication Guide", + "description": "Comprehensive guide on effective workplace communication strategies.", + "link": "https://example.com/communication-guide" + }, + { + "title": "Manager Conversation Toolkit", + "description": "Tools and templates for having productive conversations with your manager.", + "link": "https://example.com/manager-conversation-toolkit" + }, + { + "title": "Workplace Accommodations FAQ", + "description": "Frequently asked questions about requesting and implementing workplace accommodations.", + "link": "https://example.com/workplace-accommodations-faq" + }, + { + "title": "Career Development Resources", + "description": "Resources to help plan and discuss your career development with your manager.", + "link": "https://example.com/career-development" + }, + { + "title": "Wellbeing Support", + "description": "Information and resources for maintaining wellbeing in the workplace.", + "link": "https://example.com/wellbeing-support" + } + ], "versions": [ { "version": "1.0.0", diff --git a/src/features/auth/api/hooks/index.ts b/src/features/auth/api/hooks/index.ts index cb62303..f5feed4 100644 --- a/src/features/auth/api/hooks/index.ts +++ b/src/features/auth/api/hooks/index.ts @@ -1 +1,7 @@ +/** + * Barrel file for auth hooks exports + * + * Consolidates auth hook exports for cleaner imports. + */ + export * from './useAuth'; \ No newline at end of file diff --git a/src/features/auth/api/hooks/useAuth.ts b/src/features/auth/api/hooks/useAuth.ts index ebd2031..66815d4 100644 --- a/src/features/auth/api/hooks/useAuth.ts +++ b/src/features/auth/api/hooks/useAuth.ts @@ -1,5 +1,5 @@ import { useContext } from 'react'; -import { AuthContext } from '../../AuthContext'; +import { AuthContext } from '../../context/AuthContext'; export const useAuth = () => { const context = useContext(AuthContext); diff --git a/src/features/auth/components/LoginPage.tsx b/src/features/auth/components/LoginPage.tsx index 7822c4f..a7b9e71 100644 --- a/src/features/auth/components/LoginPage.tsx +++ b/src/features/auth/components/LoginPage.tsx @@ -6,7 +6,7 @@ import { useEntries } from '../../statements/hooks/useEntries'; import MagicLinkForm from './MagicLinkForm'; import { Input } from '../../../components/ui/input'; import { Button } from '../../../components/ui/button'; -import { handleMagicLinkVerification } from '../authUtils'; +import { handleMagicLinkVerification } from '../utils/authUtils'; import { Loader2 } from 'lucide-react'; import PrivacyModal from '../../../components/modals/PrivacyModal'; import TermsModal from '../../../components/modals/TermsModal'; diff --git a/src/features/auth/components/MagicLinkForm.tsx b/src/features/auth/components/MagicLinkForm.tsx index 099e3b6..e9a2f0e 100644 --- a/src/features/auth/components/MagicLinkForm.tsx +++ b/src/features/auth/components/MagicLinkForm.tsx @@ -1,8 +1,8 @@ import React, { useState } from 'react'; import { useAuth } from '../api/hooks'; import { validateEmail } from '@/lib/utils/validateEmail'; -import { Input } from '@/components/ui/input'; -import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/Input'; +import { Button } from '@/components/ui/Button'; import { Mail, Loader2 } from 'lucide-react'; interface MagicLinkFormProps { diff --git a/src/features/auth/AuthContext.ts b/src/features/auth/context/AuthContext.ts similarity index 95% rename from src/features/auth/AuthContext.ts rename to src/features/auth/context/AuthContext.ts index 7410e25..707c020 100644 --- a/src/features/auth/AuthContext.ts +++ b/src/features/auth/context/AuthContext.ts @@ -1,5 +1,5 @@ import { createContext } from 'react'; -import { AuthState } from './api/authApi'; +import { AuthState } from '../api/authApi'; // Initial auth state export const initialAuthState: AuthState = { diff --git a/src/features/auth/AuthProvider.tsx b/src/features/auth/context/AuthProvider.tsx similarity index 99% rename from src/features/auth/AuthProvider.tsx rename to src/features/auth/context/AuthProvider.tsx index 8fec6c3..f925166 100644 --- a/src/features/auth/AuthProvider.tsx +++ b/src/features/auth/context/AuthProvider.tsx @@ -5,7 +5,7 @@ import { requestMagicLink as apiRequestMagicLink, signOut as apiSignOut, updateUserProfile -} from './api/authApi'; +} from '../api/authApi'; type AuthAction = | { type: 'AUTH_LOADING' } diff --git a/src/features/auth/index.ts b/src/features/auth/index.ts new file mode 100644 index 0000000..a02a11a --- /dev/null +++ b/src/features/auth/index.ts @@ -0,0 +1,20 @@ +/** + * Barrel file for auth feature + * + * Provides unified access to authentication-related functionality + * including context, providers, hooks, and components. + */ + +// Re-export context and provider +export { AuthContext } from './context/AuthContext'; +export { AuthProvider } from './context/AuthProvider'; + +// Re-export hooks +export { useAuth } from './api/hooks'; + +// Re-export utilities +export { handleMagicLinkVerification } from './utils/authUtils'; + +// Re-export components as needed +export { default as LoginPage } from './components/LoginPage'; +export { default as MagicLinkForm } from './components/MagicLinkForm'; \ No newline at end of file diff --git a/src/features/auth/authUtils.ts b/src/features/auth/utils/authUtils.ts similarity index 96% rename from src/features/auth/authUtils.ts rename to src/features/auth/utils/authUtils.ts index 5fd3bff..585bc20 100644 --- a/src/features/auth/authUtils.ts +++ b/src/features/auth/utils/authUtils.ts @@ -1,4 +1,4 @@ -import { verifyMagicLink } from './api/authApi'; +import { verifyMagicLink } from '../api/authApi'; /** * Extract and verify magic link token from URL diff --git a/src/features/email/api/gratitudeApi.ts b/src/features/email/api/emailGratitudeApi.ts similarity index 100% rename from src/features/email/api/gratitudeApi.ts rename to src/features/email/api/emailGratitudeApi.ts diff --git a/src/features/email/api/emailApi.ts b/src/features/email/api/emailStatementsApi.ts similarity index 80% rename from src/features/email/api/emailApi.ts rename to src/features/email/api/emailStatementsApi.ts index bbf84a4..0bb5c63 100644 --- a/src/features/email/api/emailApi.ts +++ b/src/features/email/api/emailStatementsApi.ts @@ -1,9 +1,9 @@ -import { Email } from "../../../types/emails"; +import { Email } from '../../../types/emails'; // Check if we should use mock implementation const shouldUseMock = () => { return ( - import.meta.env.VITE_MOCK_EMAIL_SENDING === 'true' || + import.meta.env.VITE_MOCK_EMAIL_SENDING === 'true' || typeof import.meta.env.VITE_MOCK_EMAIL_SENDING === 'undefined' ); }; @@ -11,15 +11,15 @@ const shouldUseMock = () => { // Mock implementation of sending email const mockSendEmail = async (email: Email) => { console.log('MOCK: Sending email with:', email); - + // Simulate network delay - await new Promise(resolve => setTimeout(resolve, 800)); - + await new Promise((resolve) => setTimeout(resolve, 800)); + // Return mock success response return { success: true, message: 'Email sent successfully (mock)', - id: `mock-email-${Date.now()}` + id: `mock-email-${Date.now()}`, }; }; @@ -29,7 +29,7 @@ export async function sendEmail(email: Email) { if (shouldUseMock()) { return mockSendEmail(email); } - + // Real implementation try { const response = await fetch('/api/email/send', { @@ -39,31 +39,31 @@ export async function sendEmail(email: Email) { }, body: JSON.stringify(email), }); - + if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || 'Failed to send email'); } - + return await response.json(); } catch (error) { - console.error("Error sending email:", error); + console.error('Error sending email:', error); throw error; } } // Mock implementation of sharing statements const mockShareStatements = async (recipientEmail: string) => { - console.log('MOCK: Sharing statements with:', recipientEmail); - + console.log('MOCK: Sharing statements from:', recipientEmail); + // Simulate network delay - await new Promise(resolve => setTimeout(resolve, 800)); - + await new Promise((resolve) => setTimeout(resolve, 800)); + // Return mock success response return { success: true, message: 'Statements shared successfully (mock)', - id: `mock-share-${Date.now()}` + id: `mock-share-${Date.now()}`, }; }; @@ -73,7 +73,7 @@ export async function shareStatements(recipientEmail: string) { if (shouldUseMock()) { return mockShareStatements(recipientEmail); } - + // Real implementation try { const response = await fetch('/api/email/share-statements', { @@ -83,15 +83,15 @@ export async function shareStatements(recipientEmail: string) { }, body: JSON.stringify({ recipientEmail }), }); - + if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.message || 'Failed to share statements'); } - + return await response.json(); } catch (error) { - console.error("Error sharing statements:", error); + console.error('Error sharing statements:', error); throw error; } -} \ No newline at end of file +} diff --git a/src/components/ui/tour/HelpButton.tsx b/src/features/help/components/HelpButton.tsx similarity index 100% rename from src/components/ui/tour/HelpButton.tsx rename to src/features/help/components/HelpButton.tsx diff --git a/src/components/ui/tour/HelpCenter.tsx b/src/features/help/components/HelpCenter.tsx similarity index 83% rename from src/components/ui/tour/HelpCenter.tsx rename to src/features/help/components/HelpCenter.tsx index e101149..9f108fd 100644 --- a/src/components/ui/tour/HelpCenter.tsx +++ b/src/features/help/components/HelpCenter.tsx @@ -1,8 +1,8 @@ 'use client'; import React, { useState } from 'react'; -import { X, Info, PlayCircle, BookOpen, History } from 'lucide-react'; -import { Button } from '@/components/ui/button'; +import { X, Info, PlayCircle, BookOpen, History, Link as LinkIcon } from 'lucide-react'; +import { Button } from '@/components/ui/Button'; import helpContent from '@/data/helpContent.json'; interface HelpCenterProps { @@ -10,7 +10,7 @@ interface HelpCenterProps { initialTab?: string; } -type TabType = 'welcome' | 'tutorials' | 'features' | 'versions'; +type TabType = 'welcome' | 'tutorials' | 'features' | 'resources' | 'versions'; const HelpCenter: React.FC = ({ onClose, @@ -73,7 +73,7 @@ const HelpCenter: React.FC = ({ {/* Tabs - grid for mobile, flex for desktop */} - + = ({ Features + handleTabChange('resources')} + > + + Resources + = ({ )} + {/* Resources Tab */} + {activeTab === 'resources' && ( + + + Helpful Resources + + + + {helpContent.resources.map((resource, index) => ( + + + + + {resource.title} + + + {resource.description} + + + + ))} + + + )} + {/* Versions Tab */} {activeTab === 'versions' && ( @@ -272,4 +313,4 @@ const HelpCenter: React.FC = ({ ); }; -export default HelpCenter; +export default HelpCenter; \ No newline at end of file diff --git a/src/components/ui/tour/WelcomePanel.tsx b/src/features/help/components/WelcomePanel.tsx similarity index 98% rename from src/components/ui/tour/WelcomePanel.tsx rename to src/features/help/components/WelcomePanel.tsx index cd73694..465f255 100644 --- a/src/components/ui/tour/WelcomePanel.tsx +++ b/src/features/help/components/WelcomePanel.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react'; import { Info, PlayCircle, ArrowRight, X } from 'lucide-react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import helpContent from '@/data/helpContent.json'; interface WelcomePanelProps { diff --git a/src/components/ui/tour/index.ts b/src/features/help/components/index.ts similarity index 71% rename from src/components/ui/tour/index.ts rename to src/features/help/components/index.ts index 8aa8ba7..3ab2076 100644 --- a/src/components/ui/tour/index.ts +++ b/src/features/help/components/index.ts @@ -1,4 +1,3 @@ -export { default as HelpProvider, useHelp } from './HelpProvider'; export { default as HelpButton } from './HelpButton'; export { default as HelpCenter } from './HelpCenter'; export { default as WelcomePanel } from './WelcomePanel'; \ No newline at end of file diff --git a/src/features/help/context/HelpContext.ts b/src/features/help/context/HelpContext.ts new file mode 100644 index 0000000..b896f0b --- /dev/null +++ b/src/features/help/context/HelpContext.ts @@ -0,0 +1,9 @@ +'use client'; + +import { createContext } from 'react'; + +export interface HelpContextType { + showHelpCenter: (tab?: string) => void; +} + +export const HelpContext = createContext(undefined); diff --git a/src/components/ui/tour/HelpProvider.tsx b/src/features/help/context/HelpProvider.tsx similarity index 77% rename from src/components/ui/tour/HelpProvider.tsx rename to src/features/help/context/HelpProvider.tsx index f0deb58..01bbde3 100644 --- a/src/components/ui/tour/HelpProvider.tsx +++ b/src/features/help/context/HelpProvider.tsx @@ -1,23 +1,10 @@ 'use client'; -import React, { createContext, useContext, useState, useEffect } from 'react'; -import WelcomePanel from './WelcomePanel'; -import HelpButton from './HelpButton'; -import HelpCenter from './HelpCenter'; - -interface HelpContextType { - showHelpCenter: (tab?: string) => void; -} - -const HelpContext = createContext(undefined); - -export const useHelp = () => { - const context = useContext(HelpContext); - if (!context) { - throw new Error('useHelp must be used within a HelpProvider'); - } - return context; -}; +import React, { useState, useEffect } from 'react'; +import { HelpContext } from './HelpContext'; +import WelcomePanel from '../components/WelcomePanel'; +import HelpButton from '../components/HelpButton'; +import HelpCenter from '../components/HelpCenter'; interface HelpProviderProps { children: React.ReactNode; @@ -91,6 +78,4 @@ export const HelpProvider: React.FC = ({ children }) => { )} ); -}; - -export default HelpProvider; \ No newline at end of file +}; \ No newline at end of file diff --git a/src/features/help/hooks/useHelp.ts b/src/features/help/hooks/useHelp.ts new file mode 100644 index 0000000..8f051e7 --- /dev/null +++ b/src/features/help/hooks/useHelp.ts @@ -0,0 +1,12 @@ +'use client'; + +import { useContext } from 'react'; +import { HelpContext } from '../context/HelpContext'; + +export const useHelp = () => { + const context = useContext(HelpContext); + if (!context) { + throw new Error('useHelp must be used within a HelpProvider'); + } + return context; +}; diff --git a/src/features/help/index.ts b/src/features/help/index.ts new file mode 100644 index 0000000..70eef64 --- /dev/null +++ b/src/features/help/index.ts @@ -0,0 +1,10 @@ +/** + * Barrel file for help feature + * + * Provides unified access to help center functionality + * including context, providers, hooks, and components. + */ + +export { HelpProvider } from './context/HelpProvider'; +export { useHelp } from './hooks/useHelp'; +export { HelpButton, HelpCenter, WelcomePanel } from './components'; \ No newline at end of file diff --git a/src/components/ui/progress/ProgressWithFeedback.tsx b/src/features/progress/components/ProgressWithFeedback.tsx similarity index 84% rename from src/components/ui/progress/ProgressWithFeedback.tsx rename to src/features/progress/components/ProgressWithFeedback.tsx index 2d8c950..895afe4 100644 --- a/src/components/ui/progress/ProgressWithFeedback.tsx +++ b/src/features/progress/components/ProgressWithFeedback.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useAnsweredCount } from '@/features/questions/hooks/useAnsweredCount'; -import { useProgressFeedback } from '@/hooks/useProgressFeedback'; -import LargeCircularQuestionCounter from '../questionCounter/LargeCircularQuestionCounter'; +import { useProgressFeedback } from '../hooks/useProgressFeedback'; +import { LargeCircularQuestionCounter } from '@/components/ui'; const ProgressWithFeedback: React.FC = () => { const { answered, total } = useAnsweredCount(); diff --git a/src/hooks/useProgressFeedback.ts b/src/features/progress/hooks/useProgressFeedback.ts similarity index 100% rename from src/hooks/useProgressFeedback.ts rename to src/features/progress/hooks/useProgressFeedback.ts diff --git a/src/providers/QuestionsContext.ts b/src/features/questions/context/QuestionsContext.ts similarity index 100% rename from src/providers/QuestionsContext.ts rename to src/features/questions/context/QuestionsContext.ts diff --git a/src/providers/QuestionsProvider.tsx b/src/features/questions/context/QuestionsProvider.tsx similarity index 100% rename from src/providers/QuestionsProvider.tsx rename to src/features/questions/context/QuestionsProvider.tsx diff --git a/src/features/questions/hooks/useQuestions.ts b/src/features/questions/hooks/useQuestions.ts index 02ce37c..0505e16 100644 --- a/src/features/questions/hooks/useQuestions.ts +++ b/src/features/questions/hooks/useQuestions.ts @@ -1,5 +1,5 @@ import { useContext } from 'react'; -import { QuestionsContext } from '../../../providers/QuestionsContext'; +import { QuestionsContext } from '../context/QuestionsContext'; export function useQuestions() { const context = useContext(QuestionsContext); diff --git a/src/features/questions/index.ts b/src/features/questions/index.ts new file mode 100644 index 0000000..80d2166 --- /dev/null +++ b/src/features/questions/index.ts @@ -0,0 +1,14 @@ +/** + * Barrel file for questions feature + * + * Provides unified access to questions-related functionality + * including context, providers, hooks, and components. + */ + +// Re-export context and provider +export { QuestionsContext } from './context/QuestionsContext'; +export { QuestionsProvider } from './context/QuestionsProvider'; + +// Re-export hooks +export { useQuestions } from './hooks/useQuestions'; +export { useAnsweredCount } from './hooks/useAnsweredCount'; \ No newline at end of file diff --git a/src/features/statements/components/ActionLine.tsx b/src/features/statements/components/ActionLine.tsx index 9ab56db..d7cd4fa 100644 --- a/src/features/statements/components/ActionLine.tsx +++ b/src/features/statements/components/ActionLine.tsx @@ -13,19 +13,19 @@ import { SimpleDropdownMenuContent as DropdownMenuContent, SimpleDropdownMenuItem as DropdownMenuItem, SimpleDropdownMenuSeparator as DropdownMenuSeparator, -} from '../../../components/ui/simple-dropdown'; +} from '../../../components/ui/Dropdown'; import ActionForm from './ActionForm'; -import { ConfirmationDialog } from '../../../components/ui/confirmation-dialog'; +import { ConfirmationDialog } from '../../../components/ui/ConfirmationDialog'; import type { Action } from '../../../types/entries'; import { CheckCircle2, XCircle } from 'lucide-react'; import GratitudeModal from '../../../components/modals/GratitudeModal'; -import { markGratitudeSent } from '../../../features/email/api/gratitudeApi'; +import { markGratitudeSent } from '../../email/api/emailGratitudeApi'; import { useEntries } from '../hooks/useEntries'; import { Tooltip, TooltipTrigger, TooltipContent, -} from '../../../components/ui/better-tooltip'; +} from '../../../components/ui/BetterTooltip'; export interface ActionLineProps { statementId: string; @@ -253,16 +253,24 @@ const ActionLine: React.FC = ({ {!action.gratitude?.sent && ( <> - + { if (hasManagerEmail) { setGratitudeModal({ isOpen: true, action }); } }} - className={hasManagerEmail ? "text-pink-600" : "text-pink-300 cursor-not-allowed"} + className={ + hasManagerEmail + ? 'text-pink-600' + : 'text-pink-300 cursor-not-allowed' + } disabled={!hasManagerEmail} - title={!hasManagerEmail ? "Manager's email is required to send gratitude" : ""} + title={ + !hasManagerEmail + ? "Manager's email is required to send gratitude" + : '' + } > Send gratitude diff --git a/src/features/statements/components/QuestionCard.tsx b/src/features/statements/components/QuestionCard.tsx index 95439f2..82e124a 100644 --- a/src/features/statements/components/QuestionCard.tsx +++ b/src/features/statements/components/QuestionCard.tsx @@ -8,7 +8,7 @@ import { Tooltip, TooltipTrigger, TooltipContent, -} from '../../../components/ui/better-tooltip'; +} from '../../../components/ui/BetterTooltip'; export interface QuestionCardProps { presetQuestion: SetQuestion; diff --git a/src/features/statements/components/StatementItem.tsx b/src/features/statements/components/StatementItem.tsx index b450135..8a7c38d 100644 --- a/src/features/statements/components/StatementItem.tsx +++ b/src/features/statements/components/StatementItem.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import { getVerbName } from '@/lib/utils/verbUtils'; import { Trash2, @@ -19,14 +19,14 @@ import { SimpleDropdownMenuTrigger as DropdownMenuTrigger, SimpleDropdownMenuContent as DropdownMenuContent, SimpleDropdownMenuItem as DropdownMenuItem, -} from '@/components/ui/simple-dropdown'; +} from '@/components/ui/Dropdown'; import ActionsCounter from './ActionsCounter'; import ActionLine from './ActionLine'; import { Tooltip, TooltipTrigger, TooltipContent, -} from '@/components/ui/better-tooltip'; +} from '@/components/ui/BetterTooltip'; import statementsCategories from '@/data/statementsCategories.json'; import { formatCategoryName } from '@/lib/utils'; diff --git a/src/features/statements/components/StatementList.tsx b/src/features/statements/components/StatementList.tsx index 7fdf256..2b92786 100644 --- a/src/features/statements/components/StatementList.tsx +++ b/src/features/statements/components/StatementList.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { useEntries } from '../hooks/useEntries'; -import { ConfirmationDialog } from '../../../components/ui/confirmation-dialog'; +import { ConfirmationDialog } from '../../../components/ui/ConfirmationDialog'; import type { Entry, SetQuestion } from '@/types/entries'; import QuestionCard from './QuestionCard'; import StatementItem from './StatementItem'; diff --git a/src/features/statements/components/index.ts b/src/features/statements/components/index.ts new file mode 100644 index 0000000..35684c1 --- /dev/null +++ b/src/features/statements/components/index.ts @@ -0,0 +1,7 @@ +// Barrel file for statements components +export { default as ActionForm } from './ActionForm'; +export { default as ActionLine } from './ActionLine'; +export { default as ActionsCounter } from './ActionsCounter'; +export { default as QuestionCard } from './QuestionCard'; +export { default as StatementItem } from './StatementItem'; +export { default as StatementList } from './StatementList'; \ No newline at end of file diff --git a/src/features/statements/index.ts b/src/features/statements/index.ts new file mode 100644 index 0000000..7a59ed4 --- /dev/null +++ b/src/features/statements/index.ts @@ -0,0 +1,8 @@ +/** + * Barrel file for statements feature + * + * Provides unified access to statements-related functionality + * including context, providers, hooks, and components. + */ +export { useEntries } from './hooks/useEntries'; +export { EntriesProvider } from './context/EntriesProvider'; \ No newline at end of file diff --git a/src/features/wizard/components/EditStatementModal.tsx b/src/features/wizard/components/EditStatementModal.tsx index 1987da2..f9dc6d7 100644 --- a/src/features/wizard/components/EditStatementModal.tsx +++ b/src/features/wizard/components/EditStatementModal.tsx @@ -4,8 +4,8 @@ import { SimpleDialogContent as DialogContent, SimpleDialogTitle as DialogTitle, SimpleDialogDescription as DialogDescription, -} from '@/components/ui/simple-dialog'; -import { Button } from '@/components/ui/button'; +} from '@/components/ui/Dialog'; +import { Button } from '@/components/ui/Button'; import type { Entry } from '@/types/entries'; import { SubjectStep } from './steps/SubjectStep'; import { VerbStep } from './steps/VerbStep'; @@ -77,7 +77,7 @@ export const EditStatementModal: React.FC = ({ // Create a completely new object with a deeper clone to ensure React detects the change // Force category to be a string to avoid type issues const categoryValue = localValue ? String(localValue) : ''; - + // Create a new object with the modified category const newStatement = { ...statement, @@ -86,7 +86,7 @@ export const EditStatementModal: React.FC = ({ _needsScroll: true, // Flag to indicate this needs scrolling category: categoryValue, }; - + // Deep clone to ensure all references are fresh updatedStatement = JSON.parse(JSON.stringify(newStatement)); diff --git a/src/features/wizard/components/StatementWizard.tsx b/src/features/wizard/components/StatementWizard.tsx index 0195514..700a8ad 100644 --- a/src/features/wizard/components/StatementWizard.tsx +++ b/src/features/wizard/components/StatementWizard.tsx @@ -6,7 +6,7 @@ import { SimpleDialogContent as DialogContent, SimpleDialogDescription as DialogDescription, SimpleDialogTitle as DialogTitle, -} from '@/components/ui/simple-dialog'; +} from '@/components/ui/Dialog'; import { AnimatePresence, motion } from 'framer-motion'; import { useEntries } from '@/features/statements/hooks/useEntries'; import { postNewEntry } from '@/features/statements/api/entriesApi'; @@ -18,7 +18,7 @@ import { CategoryStep } from './steps/CategoryStep'; import { PrivacyStep } from './steps/PrivacyStep'; import { ComplementStep } from './steps/ComplementStep'; import StatementPreview from './StatementPreview'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; interface StatementWizardProps { username: string; @@ -82,7 +82,7 @@ const StatementWizard: React.FC = ({ presetId: presetQuestion.id, })); } else { - // For custom statements, set default category to "uncategorised" + // For custom statements, set default category to "uncategorised" // but still show the category screen first setSelection((prev) => ({ ...prev, @@ -313,7 +313,7 @@ const StatementWizard: React.FC = ({ )} Wizard Steps Wizard Steps - + {/* Scrollable Content Area */} @@ -328,7 +328,7 @@ const StatementWizard: React.FC = ({ - + {/* Bottom Section - Always Visible */} {/* Navigation Panel */} diff --git a/src/features/wizard/components/SubjectTiles.tsx b/src/features/wizard/components/SubjectTiles.tsx index 2ef8bc2..e3d6318 100644 --- a/src/features/wizard/components/SubjectTiles.tsx +++ b/src/features/wizard/components/SubjectTiles.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react'; -import { Button } from '../../../components/ui/button'; +import { Button } from '../../../components/ui/Button'; import descriptorsData from '../../../data/descriptors.json'; import type { SetQuestion, DescriptorsData } from '../../../types/entries'; diff --git a/src/features/wizard/components/VerbGrid.tsx b/src/features/wizard/components/VerbGrid.tsx index c49706b..102758a 100644 --- a/src/features/wizard/components/VerbGrid.tsx +++ b/src/features/wizard/components/VerbGrid.tsx @@ -1,7 +1,7 @@ 'use client'; import React from 'react'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import type { Verb, Category } from '@/types/entries'; import { getVerbColor } from '@/lib/utils/categoryUtils'; import { getContrastColor } from '@/lib/utils/colorUtils'; diff --git a/src/features/wizard/components/index.ts b/src/features/wizard/components/index.ts new file mode 100644 index 0000000..68d4534 --- /dev/null +++ b/src/features/wizard/components/index.ts @@ -0,0 +1,10 @@ +// Barrel file for wizard components +export { default as StatementWizard } from './StatementWizard'; +export { default as StatementPreview } from './StatementPreview'; +export { EditStatementModal } from './EditStatementModal'; +export { default as FilterBar } from './FilterBar'; +export { default as SentimentVerbPicker } from './SentimentVerbPicker'; +export { default as StepContainer } from './StepContainer'; +export { default as SubjectTiles } from './SubjectTiles'; +export { default as VerbGrid } from './VerbGrid'; +export { default as VerbSelector } from './VerbSelector'; \ No newline at end of file diff --git a/src/features/wizard/components/steps/CategoryStep.tsx b/src/features/wizard/components/steps/CategoryStep.tsx index ec08d88..3226699 100644 --- a/src/features/wizard/components/steps/CategoryStep.tsx +++ b/src/features/wizard/components/steps/CategoryStep.tsx @@ -1,7 +1,7 @@ // src/components/statementWizard/steps/CategoryStep.tsx import React from 'react'; import StepContainer from '../StepContainer'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import statementsCategories from '@/data/statementsCategories.json'; interface CategoryStepProps { diff --git a/src/features/wizard/components/steps/PrivacyStep.tsx b/src/features/wizard/components/steps/PrivacyStep.tsx index c120edf..dc578c3 100644 --- a/src/features/wizard/components/steps/PrivacyStep.tsx +++ b/src/features/wizard/components/steps/PrivacyStep.tsx @@ -1,6 +1,6 @@ import React from 'react'; import StepContainer from '../StepContainer'; -import { Button } from '@/components/ui/button'; +import { Button } from '@/components/ui/Button'; import { MailX, MailPlus } from 'lucide-react'; import { useEntries } from '@/features/statements/hooks/useEntries'; diff --git a/src/features/wizard/components/steps/index.ts b/src/features/wizard/components/steps/index.ts new file mode 100644 index 0000000..6d4f9e4 --- /dev/null +++ b/src/features/wizard/components/steps/index.ts @@ -0,0 +1,7 @@ +// Barrel file for wizard step components +export { CategoryStep } from './CategoryStep'; +export { ComplementStep } from './ComplementStep'; +export { ObjectStep } from './ObjectStep'; +export { PrivacyStep } from './PrivacyStep'; +export { SubjectStep } from './SubjectStep'; +export { VerbStep } from './VerbStep'; \ No newline at end of file diff --git a/src/lib/utils/ssr-hooks.ts b/src/lib/utils/ssrHooks.ts similarity index 100% rename from src/lib/utils/ssr-hooks.ts rename to src/lib/utils/ssrHooks.ts diff --git a/tsconfig.app.json b/tsconfig.app.json index cf567a6..ec1467a 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -28,7 +28,9 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noUncheckedSideEffectImports": true, + /* Case sensitivity */ + "forceConsistentCasingInFileNames": false }, "include": [ "src"
+
{children}
+ {resource.description} +