feat: enhance dropdown components by integrating useClickOutside hook for improved user experience and accessibility in NewWorkshopDropdown and WorkshopTabs
This commit is contained in:
@@ -4,6 +4,7 @@ import { useState, useTransition, useEffect } from 'react';
|
||||
import { createOrUpdateWeatherEntry } from '@/actions/weather';
|
||||
import { Avatar } from '@/components/ui/Avatar';
|
||||
import { Textarea } from '@/components/ui/Textarea';
|
||||
import { Select } from '@/components/ui/Select';
|
||||
|
||||
const WEATHER_EMOJIS = [
|
||||
{ emoji: '', label: 'Aucun' },
|
||||
@@ -140,29 +141,14 @@ export function WeatherCard({ sessionId, currentUserId, entry, canEdit }: Weathe
|
||||
{/* Performance */}
|
||||
<td className="w-24 px-2 py-3">
|
||||
{canEditThis ? (
|
||||
<div className="relative mx-auto w-fit">
|
||||
<select
|
||||
value={performanceEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('performance', e.target.value || null)}
|
||||
className="w-16 appearance-none rounded-lg border border-border bg-card px-2 py-2.5 pr-8 text-center text-lg text-foreground transition-colors hover:bg-card-hover focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
|
||||
>
|
||||
{WEATHER_EMOJIS.map(({ emoji }) => (
|
||||
<option key={emoji || 'none'} value={emoji}>
|
||||
{emoji}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2">
|
||||
<svg
|
||||
className="h-3 w-3 text-muted"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<Select
|
||||
value={performanceEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('performance', e.target.value || null)}
|
||||
options={WEATHER_EMOJIS.map(({ emoji }) => ({ value: emoji, label: emoji }))}
|
||||
size="sm"
|
||||
wrapperClassName="!w-fit mx-auto"
|
||||
className="!w-16 min-w-16 text-center text-lg py-2.5"
|
||||
/>
|
||||
) : (
|
||||
<div className="text-2xl text-center">{performanceEmoji || '-'}</div>
|
||||
)}
|
||||
@@ -171,29 +157,14 @@ export function WeatherCard({ sessionId, currentUserId, entry, canEdit }: Weathe
|
||||
{/* Moral */}
|
||||
<td className="w-24 px-2 py-3">
|
||||
{canEditThis ? (
|
||||
<div className="relative mx-auto w-fit">
|
||||
<select
|
||||
value={moralEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('moral', e.target.value || null)}
|
||||
className="w-16 appearance-none rounded-lg border border-border bg-card px-2 py-2.5 pr-8 text-center text-lg text-foreground transition-colors hover:bg-card-hover focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
|
||||
>
|
||||
{WEATHER_EMOJIS.map(({ emoji }) => (
|
||||
<option key={emoji || 'none'} value={emoji}>
|
||||
{emoji}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2">
|
||||
<svg
|
||||
className="h-3 w-3 text-muted"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<Select
|
||||
value={moralEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('moral', e.target.value || null)}
|
||||
options={WEATHER_EMOJIS.map(({ emoji }) => ({ value: emoji, label: emoji }))}
|
||||
size="sm"
|
||||
wrapperClassName="!w-fit mx-auto"
|
||||
className="!w-16 min-w-16 text-center text-lg py-2.5"
|
||||
/>
|
||||
) : (
|
||||
<div className="text-2xl text-center">{moralEmoji || '-'}</div>
|
||||
)}
|
||||
@@ -202,29 +173,14 @@ export function WeatherCard({ sessionId, currentUserId, entry, canEdit }: Weathe
|
||||
{/* Flux */}
|
||||
<td className="w-24 px-2 py-3">
|
||||
{canEditThis ? (
|
||||
<div className="relative mx-auto w-fit">
|
||||
<select
|
||||
value={fluxEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('flux', e.target.value || null)}
|
||||
className="w-16 appearance-none rounded-lg border border-border bg-card px-2 py-2.5 pr-8 text-center text-lg text-foreground transition-colors hover:bg-card-hover focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
|
||||
>
|
||||
{WEATHER_EMOJIS.map(({ emoji }) => (
|
||||
<option key={emoji || 'none'} value={emoji}>
|
||||
{emoji}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2">
|
||||
<svg
|
||||
className="h-3 w-3 text-muted"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<Select
|
||||
value={fluxEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('flux', e.target.value || null)}
|
||||
options={WEATHER_EMOJIS.map(({ emoji }) => ({ value: emoji, label: emoji }))}
|
||||
size="sm"
|
||||
wrapperClassName="!w-fit mx-auto"
|
||||
className="!w-16 min-w-16 text-center text-lg py-2.5"
|
||||
/>
|
||||
) : (
|
||||
<div className="text-2xl text-center">{fluxEmoji || '-'}</div>
|
||||
)}
|
||||
@@ -233,29 +189,14 @@ export function WeatherCard({ sessionId, currentUserId, entry, canEdit }: Weathe
|
||||
{/* Création de valeur */}
|
||||
<td className="w-24 px-2 py-3">
|
||||
{canEditThis ? (
|
||||
<div className="relative mx-auto w-fit">
|
||||
<select
|
||||
value={valueCreationEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('valueCreation', e.target.value || null)}
|
||||
className="w-16 appearance-none rounded-lg border border-border bg-card px-2 py-2.5 pr-8 text-center text-lg text-foreground transition-colors hover:bg-card-hover focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
|
||||
>
|
||||
{WEATHER_EMOJIS.map(({ emoji }) => (
|
||||
<option key={emoji || 'none'} value={emoji}>
|
||||
{emoji}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2">
|
||||
<svg
|
||||
className="h-3 w-3 text-muted"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<Select
|
||||
value={valueCreationEmoji || ''}
|
||||
onChange={(e) => handleEmojiChange('valueCreation', e.target.value || null)}
|
||||
options={WEATHER_EMOJIS.map(({ emoji }) => ({ value: emoji, label: emoji }))}
|
||||
size="sm"
|
||||
wrapperClassName="!w-fit mx-auto"
|
||||
className="!w-16 min-w-16 text-center text-lg py-2.5"
|
||||
/>
|
||||
) : (
|
||||
<div className="text-2xl text-center">{valueCreationEmoji || '-'}</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user