Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add employer name #9

Merged
merged 5 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from 4 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
7 changes: 6 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ import { QuestionsProvider } from './context/QuestionsProvider';
const AppContent: React.FC = () => {
const { data, setData } = useEntries();

const handleLoginSubmit = (username: string, managerEmail: string) => {
const handleLoginSubmit = (
username: string,
managerName: string,
managerEmail: string
) => {
// Dispatch an action to update the username in context.
setData({ type: 'SET_USERNAME', payload: username });
setData({ type: 'SET_MANAGER_NAME', payload: managerName });
setData({ type: 'SET_MANAGER_EMAIL', payload: managerEmail });
};

Expand Down
123 changes: 73 additions & 50 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
// src/components/Header.tsx
import React, { useState, useEffect } from 'react';
import { useEntries } from '../hooks/useEntries';

import {
Expand All @@ -18,22 +19,34 @@ import SmallCircularQuestionCounter from './ui/questionCounter/smallCircularQues
import LargeCircularQuestionCounter from './ui/questionCounter/LargeCircularQuestionCounter';

const Header: React.FC = () => {
// const { questions, setQuestions } = useQuestions();
const { data, setData } = useEntries();
const [isDashboardOpen, setIsDashboardOpen] = useState(false);
const [isEditingEmail, setIsEditingEmail] = useState(false);
// Combined editing state for manager details
const [isEditingContact, setIsEditingContact] = useState(false);
const [managerEmailInput, setManagerEmailInput] = useState(
data.managerEmail || ''
);
const [managerNameInput, setManagerNameInput] = useState(
data.managerName || ''
);
const [emailError, setEmailError] = useState('');

const handleEmailSave = () => {
if (!validateEmail(managerEmailInput.trim())) {
// Sync local inputs with context when edit mode is activated.
useEffect(() => {
if (isEditingContact) {
setManagerEmailInput(data.managerEmail || '');
setManagerNameInput(data.managerName || '');
}
}, [isEditingContact, data.managerEmail, data.managerName]);

const handleSaveContact = () => {
if (managerEmailInput.trim() && !validateEmail(managerEmailInput.trim())) {
setEmailError('Please enter a valid email address.');
return;
}
setData({ type: 'SET_MANAGER_EMAIL', payload: managerEmailInput });
setIsEditingEmail(false);
setData({ type: 'SET_MANAGER_NAME', payload: managerNameInput });
setIsEditingContact(false);
setEmailError('');
};

Expand All @@ -45,7 +58,7 @@ const Header: React.FC = () => {
<img src='/lift_logo.png' alt='Logo' className='h-10 mr-2' />
<h1 className='text-2xl font-bold'>Beacons</h1>
</div>
{/* Right side: Clickable container with border that opens the dialog */}
{/* Right side: User info & dashboard */}
{data.username ? (
<Dialog open={isDashboardOpen} onOpenChange={setIsDashboardOpen}>
<DialogTrigger asChild>
Expand Down Expand Up @@ -75,26 +88,38 @@ const Header: React.FC = () => {
{data.username || 'Not set'}
</div>
</div>
{/* Manager email section */}
{/* Manager contact section */}
<div className='mt-4'>
<div className='text-sm font-semibold text-gray-700 mb-1'>
Your line's manager email:
Your line manager's details:
</div>
<div className='flex items-center space-x-2'>
{isEditingEmail ? (
<>
<Input
value={managerEmailInput}
onChange={(e) => setManagerEmailInput(e.target.value)}
placeholder='Enter new manager email'
aria-label='Manager Email'
className='w-full'
/>
{isEditingContact ? (
<div className='space-y-2'>
<Input
value={managerNameInput}
onChange={(e) => setManagerNameInput(e.target.value)}
placeholder="Enter manager's name (optional)"
aria-label='Manager Name'
className='w-full'
/>
<Input
value={managerEmailInput}
onChange={(e) => setManagerEmailInput(e.target.value)}
placeholder="Enter manager's email (optional)"
aria-label='Manager Email'
className='w-full'
/>
{emailError && (
<div className='text-red-500 text-xs mt-1'>
{emailError}
</div>
)}
<div className='flex space-x-2'>
<Button
onClick={handleEmailSave}
onClick={handleSaveContact}
variant='outline'
size='sm'
aria-label='Save Email'
aria-label='Save Contact'
disabled={
managerEmailInput.trim() !== '' &&
!validateEmail(managerEmailInput.trim())
Expand All @@ -104,8 +129,9 @@ const Header: React.FC = () => {
</Button>
<Button
onClick={() => {
setIsEditingEmail(false);
setIsEditingContact(false);
setManagerEmailInput(data.managerEmail || '');
setManagerNameInput(data.managerName || '');
setEmailError('');
}}
variant='outline'
Expand All @@ -114,36 +140,34 @@ const Header: React.FC = () => {
>
<X size={16} />
</Button>
</>
) : (
<>
<span className='text-sm text-gray-800'>
{data.managerEmail || 'Not set'}
</span>
<Tooltip>
<TooltipTrigger asChild>
<button
className='flex items-center justify-center rounded-full bg-white p-2 text-brand-pink'
aria-label="Edit your line's manager email"
onClick={() => setIsEditingEmail(true)}
>
<Edit2 size={16} />
</button>
</TooltipTrigger>
<TooltipContent>
Edit your line's manager email
</TooltipContent>
</Tooltip>
</>
)}
</div>
{emailError && (
<div className='text-red-500 text-xs mt-1'>
{emailError}
</div>
</div>
) : (
<div className='flex items-center space-x-2'>
<div className='text-sm text-gray-800'>
{data.managerName ? data.managerName : 'Name not set'} |{' '}
{data.managerEmail
? data.managerEmail
: 'Email not set'}
</div>
<Tooltip>
<TooltipTrigger asChild>
<button
className='flex items-center justify-center rounded-full bg-white p-2 text-brand-pink'
aria-label="Edit your line manager's details"
onClick={() => setIsEditingContact(true)}
>
<Edit2 size={16} />
</button>
</TooltipTrigger>
<TooltipContent>
Edit your line manager's details
</TooltipContent>
</Tooltip>
</div>
)}
</div>
{/* Question counter */}
{/* Progress section */}
<div>
<div className='text-sm font-semibold text-gray-700 mb-1'>
Your progress:
Expand All @@ -165,7 +189,6 @@ const Header: React.FC = () => {
</DialogContent>
</Dialog>
) : (
// Change: Render non-clickable container if there is no username.
<div className='flex items-center border-2 border-white rounded-full px-4 py-2 cursor-default'>
<span className='mr-2'>Not logged</span>
<SmallCircularQuestionCounter />
Expand Down
64 changes: 37 additions & 27 deletions src/components/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ import { AlertCircle } from 'lucide-react';
import { validateEmail } from '../../utils/validateEmail';

interface LoginPageProps {
onSubmit: (username: string, managerEmail: string) => void;
onSubmit: (
username: string,
managerName: string,
managerEmail: string
) => void;
}

const LoginPage: React.FC<LoginPageProps> = ({ onSubmit }) => {
const [name, setName] = useState('');
const [managerEmail, setManagerEmail] = useState('');
const [managerName, setManagerName] = useState('');
const [emailError, setEmailError] = useState('');

const handleEmailBlur = () => {
Expand All @@ -28,7 +33,7 @@ const LoginPage: React.FC<LoginPageProps> = ({ onSubmit }) => {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (name.trim() && !emailError) {
onSubmit(name.trim(), managerEmail.trim());
onSubmit(name.trim(), managerName.trim(), managerEmail.trim());
}
};

Expand All @@ -40,8 +45,8 @@ const LoginPage: React.FC<LoginPageProps> = ({ onSubmit }) => {
<div className='bg-white shadow-lg rounded-lg p-8 max-w-md w-full'>
<h1 className='text-3xl font-bold mb-6 text-center'>Welcome!</h1>
<p className='mb-6 text-center text-gray-700'>
Please enter your name and, optionally, your line manager's email to
continue.
Please enter your name and, optionally, your line manager's name and
email to continue.
</p>
<form onSubmit={handleSubmit} className='space-y-4'>
<Input
Expand All @@ -50,31 +55,36 @@ const LoginPage: React.FC<LoginPageProps> = ({ onSubmit }) => {
onChange={(e) => setName(e.target.value)}
className='w-full'
/>
<div className='relative flex items-center'>
<Input
placeholder="Enter your manager's email (optional)"
value={managerEmail}
onChange={(e) => setManagerEmail(e.target.value)}
onBlur={handleEmailBlur}
className='w-full pr-10'
/>
{emailError && (
<Tooltip>
<TooltipTrigger asChild>
<div className='absolute right-2'>
<AlertCircle className='w-5 h-5 text-red-500' />
</div>
</TooltipTrigger>
<TooltipContent className='bg-red-500 text-white p-2 rounded'>
{emailError}
</TooltipContent>
</Tooltip>
)}
</div>
<Input
placeholder="Enter your manager's name (optional)"
value={managerName}
onChange={(e) => setManagerName(e.target.value)}
className='w-full pr-10'
/>
<Input
placeholder="Enter your manager's email (optional)"
value={managerEmail}
onChange={(e) => setManagerEmail(e.target.value)}
onBlur={handleEmailBlur}
className='w-full pr-10'
/>
{emailError && (
<Tooltip>
<TooltipTrigger asChild>
<div className='absolute right-2'>
<AlertCircle className='w-5 h-5 text-red-500' />
</div>
</TooltipTrigger>
<TooltipContent className='bg-red-500 text-white p-2 rounded'>
{emailError}
</TooltipContent>
</Tooltip>
)}

<Button
type='submit'
variant='ghost'
className='w-full mt-4'
variant='pink'
className='mx-auto'
disabled={isSubmitDisabled}
>
Continue
Expand Down
38 changes: 29 additions & 9 deletions src/components/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import React from 'react';
import { Tooltip, TooltipTrigger, TooltipContent } from './ui/tooltip';
import StatementList from './statements/StatementList';
import { useEntries } from '../hooks/useEntries';
import { Button } from './ui/button';
Expand All @@ -10,10 +11,17 @@ import ShareEmailModal from './ShareEmailModal'; // Import the new modal

const MainPage: React.FC = () => {
const { data } = useEntries();
const { username } = data;
const { username, managerEmail, entries } = data;
const [isWizardOpen, setIsWizardOpen] = React.useState(false);
const [isShareModalOpen, setIsShareModalOpen] = React.useState(false);

// Determine if email button should be disabled:
const hasManagerEmail = managerEmail && managerEmail.trim().length > 0;
const publicStatementsCount = entries.filter(
(entry) => entry.isPublic && !entry.isResolved
).length;
const isEmailDisabled = !hasManagerEmail || publicStatementsCount === 0;

// Handler to open the wizard for creating a new statement from scratch
const handleNewStatement = () => {
setIsWizardOpen(true);
Expand All @@ -34,14 +42,26 @@ const MainPage: React.FC = () => {
</div>
{/* Floating Buttons Container */}
<div className='fixed bottom-8 right-8 flex items-center space-x-4'>
{/* Email Button on the left */}
<Button
onClick={handleShareEmail}
variant='outline'
className='rounded-full p-3 shadow-lg bg-white hover:bg-gray-100'
>
<Mail className='w-6 h-6 text-brand-pink' />
</Button>
{/* Email Button: Disabled if there's no manager email or no public statements */}
<Tooltip>
<TooltipTrigger asChild>
<span>
<Button
onClick={handleShareEmail}
variant='outline'
className='rounded-full p-3 shadow-lg bg-white hover:bg-gray-100'
disabled={isEmailDisabled}
>
<Mail className='w-6 h-6 text-brand-pink' />
</Button>
</span>
</TooltipTrigger>
<TooltipContent className='bg-gray-800 text-white p-2 rounded'>
{isEmailDisabled
? "Please add your line manager's email and ensure you have public statements to share."
: 'Send email to your line manager with your public statements.'}
</TooltipContent>
</Tooltip>
{/* Create Your Own Statement Button */}
<Button
onClick={handleNewStatement}
Expand Down
7 changes: 5 additions & 2 deletions src/components/statementWizard/PrivacySelector.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Button } from '../ui/button';
import { Eye, EyeOff } from 'lucide-react';

Check failure on line 3 in src/components/statementWizard/PrivacySelector.tsx

View workflow job for this annotation

GitHub Actions / Deploy

All imports in import declaration are unused.
import { Mail } from 'lucide-react';

interface PrivacySelectorProps {
isPublic: boolean;
Expand All @@ -24,7 +25,8 @@
onClick={() => onChange(false)}
>
<div className='flex items-center space-x-3'>
<EyeOff className='w-5 h-5' />
{/* <EyeOff className='w-5 h-5' /> */}
<Mail className='w-5 h-5 text-gray-500' />
<div className='text-left'>
<div className='font-medium'>Private</div>
<div className='text-sm text-muted-foreground'>
Expand All @@ -41,7 +43,8 @@
onClick={() => onChange(true)}
>
<div className='flex items-center space-x-3'>
<Eye className='w-5 h-5' />
{/* <Eye className='w-5 h-5' /> */}
<Mail className='w-5 h-5 text-green-500' />
<div className='text-left'>
<div className='font-medium'>Public</div>
<div className='text-sm text-muted-foreground'>
Expand Down
Loading
Loading