1 Commits

Author SHA1 Message Date
Stánek Pavel
f13cd4ffa9 fix: opravy zobrazeni sekce vybranych jidel
All checks were successful
ci/woodpecker/push/workflow Pipeline was successful
2026-02-05 10:18:58 +01:00
2 changed files with 96 additions and 69 deletions

View File

@@ -628,56 +628,77 @@ input[type="text"], input[type="email"], input[type="password"] {
tbody tr { tbody tr {
transition: var(--luncher-transition); transition: var(--luncher-transition);
border-bottom: 1px solid var(--luncher-border-light);
&:hover { &:hover {
background: var(--luncher-bg-hover); background: var(--luncher-bg-hover);
} }
&:last-child td { &:last-child {
border-bottom: none; border-bottom: none;
td {
border-bottom: none;
}
} }
} }
td { td {
padding: 12px 16px; padding: 12px 16px;
border-color: var(--luncher-border-light); border: none;
color: var(--luncher-text); color: var(--luncher-text);
white-space: nowrap;
vertical-align: middle; vertical-align: middle;
} }
}
ul { .user-row {
padding: 0; display: flex;
margin: 8px 0 0 20px; justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
li { .user-info {
color: var(--luncher-text-secondary); display: flex;
font-size: 0.9rem; align-items: center;
margin-bottom: 4px; gap: 8px;
flex-wrap: wrap;
}
.user-actions {
display: flex;
gap: 8px;
align-items: center;
white-space: nowrap;
} }
} }
.food-choices { .food-choices {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 6px; gap: 4px;
margin-top: 8px;
} }
.food-choice-item { .food-choice-item {
background: var(--luncher-primary-light); display: inline-flex;
padding: 8px 12px;
border-radius: var(--luncher-radius-sm);
display: flex;
align-items: center; align-items: center;
justify-content: space-between; gap: 6px;
font-size: 0.9rem; font-size: 0.85rem;
border-left: 3px solid var(--luncher-primary); color: var(--luncher-text-secondary);
.action-icon {
opacity: 0;
transition: var(--luncher-transition);
}
&:hover .action-icon {
opacity: 1;
}
} }
.food-choice-name { .food-choice-name {
color: var(--luncher-text); color: var(--luncher-text-secondary);
font-weight: 500; font-weight: 400;
} }
} }

View File

@@ -544,55 +544,61 @@ function App() {
const isBuyer = userPayload?.isBuyer || false; const isBuyer = userPayload?.isBuyer || false;
return <tr key={entry[0]}> return <tr key={entry[0]}>
<td> <td>
{trusted && <span className='trusted-icon' title='Uživatel ověřený doménovým přihlášením'> <div className="user-row">
<FontAwesomeIcon icon={faCircleCheck} style={{ cursor: "help" }} /> <div className="user-info">
</span>} {trusted && <span className='trusted-icon' title='Uživatel ověřený doménovým přihlášením'>
<strong>{login}</strong> <FontAwesomeIcon icon={faCircleCheck} style={{ cursor: "help" }} />
{userPayload.departureTime && <small className="ms-2" style={{ color: 'var(--luncher-text-muted)' }}>({userPayload.departureTime})</small>} </span>}
{userPayload.note && <span className="ms-2" style={{ fontSize: 'small', color: 'var(--luncher-text-secondary)' }}>({userPayload.note})</span>} <strong>{login}</strong>
{login === auth.login && canChangeChoice && locationKey === LunchChoice.OBJEDNAVAM && <span title='Označit/odznačit se jako objednávající'> {userPayload.departureTime && <small className="ms-2" style={{ color: 'var(--luncher-text-muted)' }}>({userPayload.departureTime})</small>}
<FontAwesomeIcon onClick={() => { {userPayload.note && <span className="ms-2" style={{ fontSize: 'small', color: 'var(--luncher-text-secondary)' }}>({userPayload.note})</span>}
markAsBuyer(); </div>
}} icon={faBasketShopping} className={isBuyer ? 'buyer-icon' : 'action-icon'} style={{cursor: 'pointer'}} /> <div className="user-actions">
</span>} {login === auth.login && canChangeChoice && locationKey === LunchChoice.OBJEDNAVAM && <span title='Označit/odznačit se jako objednávající'>
{login !== auth.login && locationKey === LunchChoice.OBJEDNAVAM && isBuyer && <span title='Objednávající'> <FontAwesomeIcon onClick={() => {
<FontAwesomeIcon onClick={() => { markAsBuyer();
copyNote(userPayload.note!); }} icon={faBasketShopping} className={isBuyer ? 'buyer-icon' : 'action-icon'} style={{cursor: 'pointer'}} />
}} icon={faBasketShopping} className='buyer-icon' /> </span>}
</span>} {login !== auth.login && locationKey === LunchChoice.OBJEDNAVAM && isBuyer && <span title='Objednávající'>
{login !== auth.login && canChangeChoice && userPayload?.note?.length && <span title='Převzít poznámku'> <FontAwesomeIcon onClick={() => {
<FontAwesomeIcon onClick={() => { copyNote(userPayload.note!);
copyNote(userPayload.note!); }} icon={faBasketShopping} className='buyer-icon' />
}} className='action-icon' icon={faComment} /> </span>}
</span>} {login !== auth.login && canChangeChoice && userPayload?.note?.length && <span title='Převzít poznámku'>
{login === auth.login && canChangeChoice && <span title='Upravit poznámku'> <FontAwesomeIcon onClick={() => {
<FontAwesomeIcon onClick={() => { copyNote(userPayload.note!);
setNoteModalOpen(true); }} className='action-icon' icon={faComment} />
}} className='action-icon' icon={faNoteSticky} /> </span>}
</span>} {login === auth.login && canChangeChoice && <span title='Upravit poznámku'>
{login === auth.login && canChangeChoice && <span title={`Odstranit volbu ${locationName}, včetně případných zvolených jídel`}> <FontAwesomeIcon onClick={() => {
<FontAwesomeIcon onClick={() => { setNoteModalOpen(true);
doRemoveChoices(key as LunchChoice); }} className='action-icon' icon={faNoteSticky} />
}} className='action-icon' icon={faTrashCan} /> </span>}
</span>} {login === auth.login && canChangeChoice && <span title={`Odstranit volbu ${locationName}, včetně případných zvolených jídel`}>
</td> <FontAwesomeIcon onClick={() => {
{userChoices?.length && food ? <td> doRemoveChoices(key as LunchChoice);
<div className="food-choices"> }} className='action-icon' icon={faTrashCan} />
{userChoices?.map(foodIndex => { </span>}
const restaurantKey = key as Restaurant; </div>
const foodName = food[restaurantKey]?.food?.[foodIndex].name;
return <div key={foodIndex} className="food-choice-item">
<span className="food-choice-name">{foodName}</span>
{login === auth.login && canChangeChoice &&
<span title={`Odstranit ${foodName}`}>
<FontAwesomeIcon onClick={() => {
doRemoveFoodChoice(restaurantKey, foodIndex);
}} className='action-icon' icon={faTrashCan} />
</span>}
</div>
})}
</div> </div>
</td> : null} {userChoices && userChoices.length > 0 && food && (
<div className="food-choices">
{userChoices.map(foodIndex => {
const restaurantKey = key as Restaurant;
const foodName = food[restaurantKey]?.food?.[foodIndex].name;
return <div key={foodIndex} className="food-choice-item">
<span className="food-choice-name">{foodName}</span>
{login === auth.login && canChangeChoice &&
<span title={`Odstranit ${foodName}`}>
<FontAwesomeIcon onClick={() => {
doRemoveFoodChoice(restaurantKey, foodIndex);
}} className='action-icon' icon={faTrashCan} />
</span>}
</div>
})}
</div>
)}
</td>
</tr> </tr>
} }
)} )}