Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -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 = () => {
Expand All @@ -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.
<>
<Header />
{data.username ? (
<MainPage />
) : (
<LoginPage />
)}
{data.username ? <MainPage /> : <LoginPage />}
</>
);
};
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => {
Expand Down
10 changes: 10 additions & 0 deletions src/components/layout/index.ts
Original file line number Diff line number Diff line change
@@ -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';
18 changes: 10 additions & 8 deletions src/components/modals/GratitudeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -115,8 +115,8 @@ const GratitudeModal: React.FC<GratitudeModalProps> = ({
>
{/* Heart decoration - smaller on mobile */}
<div className='absolute top-2 right-2 sm:top-4 sm:right-4 text-pink-400 opacity-20 pointer-events-none'>
<Heart size={24} className="sm:hidden" />
<Heart size={40} className="hidden sm:block" />
<Heart size={24} className='sm:hidden' />
<Heart size={40} className='hidden sm:block' />
</div>

<DialogDescription className='mt-0 text-center text-sm'>
Expand Down Expand Up @@ -144,7 +144,9 @@ const GratitudeModal: React.FC<GratitudeModalProps> = ({
<h3 className='font-semibold text-gray-700 mb-1 sm:mb-2 flex items-center text-sm sm:text-base'>
Action
</h3>
<p className='text-gray-600 text-xs sm:text-sm break-words'>{action.action}</p>
<p className='text-gray-600 text-xs sm:text-sm break-words'>
{action.action}
</p>
{action.byDate && (
<p className='text-xs text-gray-500 mt-1'>
Due by: {action.byDate}
Expand Down Expand Up @@ -191,8 +193,8 @@ const GratitudeModal: React.FC<GratitudeModalProps> = ({
</>
)}
</Button>
<Button
variant='outline'
<Button
variant='outline'
onClick={onClose}
className='text-xs sm:text-sm px-2 sm:px-4 py-1 sm:py-2'
>
Expand Down
10 changes: 5 additions & 5 deletions src/components/modals/ShareEmailModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => {
Expand Down
12 changes: 6 additions & 6 deletions src/components/modals/UserDataModal.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
12 changes: 12 additions & 0 deletions src/components/modals/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down
5 changes: 3 additions & 2 deletions src/components/ui/button.tsx → src/components/ui/Button.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLButtonElement>,
Expand All @@ -23,6 +23,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
);
}
);

Button.displayName = 'Button';

export { Button };
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button } from './button';
import { Button } from './Button';
interface ConfirmationDialogProps {
isOpen: boolean;
onClose: () => void;
Expand Down
Loading
Loading