Enhance Badge component styling for better visibility, update GiftCard component to include Heading and FaTrashAlt icon for delete action, and refactor PersonCard to streamline layout and remove unnecessary state management.
This commit is contained in:
10
package-lock.json
generated
10
package-lock.json
generated
@@ -12,6 +12,7 @@
|
|||||||
"pocketbase": "^0.26.3",
|
"pocketbase": "^0.26.3",
|
||||||
"react": "19.2.0",
|
"react": "19.2.0",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"zustand": "^5.0.8"
|
"zustand": "^5.0.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1556,6 +1557,15 @@
|
|||||||
"react": "^19.2.0"
|
"react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-icons": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.27.0",
|
"version": "0.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"pocketbase": "^0.26.3",
|
"pocketbase": "^0.26.3",
|
||||||
"react": "19.2.0",
|
"react": "19.2.0",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
"zustand": "^5.0.8"
|
"zustand": "^5.0.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -6,5 +6,9 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const Badge: FC<Props> = ({ children, disabled }) => {
|
export const Badge: FC<Props> = ({ children, disabled }) => {
|
||||||
return <span className='px-2 py-1 text-xs font-medium text-blue-600 bg-blue-50 rounded-lg'>{children}</span>;
|
return (
|
||||||
|
<span className='px-3 py-1 text-xs font-medium text-gray-800 bg-amber-300 rounded-lg hover:bg-amber-400 transition-all duration-200 ease-in-out'>
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { useRouter } from 'next/navigation';
|
|||||||
import { Button } from '@/components/atoms/Button';
|
import { Button } from '@/components/atoms/Button';
|
||||||
import { Badge } from '@/components/atoms/Badge';
|
import { Badge } from '@/components/atoms/Badge';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { Heading } from '@/components/atoms/Heading';
|
||||||
|
import { FaTrashAlt } from 'react-icons/fa';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
hideDetails?: boolean;
|
hideDetails?: boolean;
|
||||||
@@ -20,6 +22,7 @@ export const GiftCard: FC<Gift & Props> = ({ hideDetails = false, editable = fal
|
|||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const year = useGlobalStore((s) => s.year);
|
const year = useGlobalStore((s) => s.year);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
editable = editable || !!gift.id;
|
||||||
|
|
||||||
const { title, description, cost, status, created, expand, link } = gift;
|
const { title, description, cost, status, created, expand, link } = gift;
|
||||||
|
|
||||||
@@ -38,42 +41,30 @@ export const GiftCard: FC<Gift & Props> = ({ hideDetails = false, editable = fal
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={`rounded-2xl shadow-sm p-4 my-6 md:p-6 transition-all duration-200 ease-in-out ${
|
className={`rounded-2xl shadow-sm p-4 my-6 transition-all duration-200 ease-in-out ${bgByStatus[status]} ${
|
||||||
bgByStatus[status]
|
editable ? 'cursor-pointer hover:shadow-md ' : ''
|
||||||
} ${editable ? 'cursor-pointer hover:shadow-md ' : ''}`}
|
}`}
|
||||||
onClick={editable ? () => setIsOpen(true) : undefined}>
|
onClick={editable ? () => setIsOpen(true) : undefined}>
|
||||||
<div className='flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4'>
|
<div className='flex flex-col gap-2'>
|
||||||
<div className='flex-1'>
|
<div className='flex justify-between items-center flex-wrap gap-2'>
|
||||||
<div className='flex items-center justify-between gap-3 mb-2'>
|
<div className='flex items-center gap-2'>
|
||||||
<h3 className='text-lg font-semibold text-gray-800'>{title}</h3>
|
<Heading size='small' spacing='none'>
|
||||||
|
{title}
|
||||||
|
</Heading>
|
||||||
{editable && (
|
{editable && (
|
||||||
<div className='ml-auto'>
|
<FaTrashAlt
|
||||||
<Button
|
size={14}
|
||||||
variant='danger'
|
color='red'
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleDelete();
|
handleDelete();
|
||||||
}}>
|
}}
|
||||||
Usuń
|
/>
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{description && <p className='text-base text-gray-600 mb-3'>{description}</p>}
|
|
||||||
<div
|
|
||||||
className={`flex flex-wrap text-sm text-gray-500 ${editable ? 'flex-col gap-2' : 'items-center gap-4'}`}>
|
|
||||||
<span>Data dodania: {new Date(created).toLocaleDateString()}</span>
|
|
||||||
<span>Koszt: {formatCurrency(cost)}</span>
|
|
||||||
{!hideDetails && (
|
|
||||||
<>
|
|
||||||
<span>•</span>
|
|
||||||
<span>Dla: {expand?.person.name}</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<span>Status: {formatStatus(status)}</span>
|
|
||||||
</div>
|
|
||||||
{link && (
|
{link && (
|
||||||
<div className='flex flex-wrap items-center gap-2 mt-6'>
|
<div className='flex flex-wrap items-center gap-2'>
|
||||||
{link.split('\n').map((line, index) => (
|
{link.split('\n').map((line, index) => (
|
||||||
<Link href={line} target='_blank' key={index} onClick={(e) => e.stopPropagation()}>
|
<Link href={line} target='_blank' key={index} onClick={(e) => e.stopPropagation()}>
|
||||||
<Badge>Link {index + 1}</Badge>
|
<Badge>Link {index + 1}</Badge>
|
||||||
@@ -82,6 +73,16 @@ export const GiftCard: FC<Gift & Props> = ({ hideDetails = false, editable = fal
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div className='flex flex-wrap items-center gap-2'>
|
||||||
|
<span>Koszt: {formatCurrency(cost)}</span>
|
||||||
|
{!hideDetails && (
|
||||||
|
<>
|
||||||
|
<span>•</span>
|
||||||
|
<span>Dla: {expand?.person.name}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{description && <p className='text-base text-gray-600'>{description}</p>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export const PersonCardEdit: FC<Props> = ({ person }) => {
|
|||||||
<Button variant='primary' onClick={() => setIsOpen(true)}>
|
<Button variant='primary' onClick={() => setIsOpen(true)}>
|
||||||
Edytuj
|
Edytuj
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant='secondary' onClick={handleDelete}>
|
<Button variant='danger' onClick={handleDelete}>
|
||||||
Usuń
|
Usuń
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,42 +1,36 @@
|
|||||||
'use client';
|
|
||||||
import { Heading } from '@/components/atoms/Heading';
|
import { Heading } from '@/components/atoms/Heading';
|
||||||
import { formatCurrency } from '@/helpers/formatCurrency';
|
import { formatCurrency } from '@/helpers/formatCurrency';
|
||||||
import { FC, useState } from 'react';
|
import { FC } from 'react';
|
||||||
import { GiftCard } from '../GiftCard';
|
import { GiftCard } from '../GiftCard';
|
||||||
import { GiftCardAdd, PersonCardEdit } from './client';
|
import { GiftCardAdd, PersonCardEdit } from './client';
|
||||||
import { Button } from '@/components/atoms/Button';
|
|
||||||
|
|
||||||
export const PersonCard: FC<Person> = (person) => {
|
export const PersonCard: FC<Person> = (person) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const { name, notes, expand } = person;
|
const { name, notes, expand } = person;
|
||||||
const { gifts } = expand;
|
const { gifts } = expand;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='bg-white rounded-2xl shadow-sm hover:shadow-md p-4 md:p-6 transition-all duration-200 ease-in-out mt-6'>
|
<div className='bg-white rounded-2xl shadow-sm hover:shadow-md p-4 md:p-6 transition-all duration-200 ease-in-out mt-6'>
|
||||||
<div className='flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 pb-2 mb-6 border-b border-gray-200'>
|
<div className='flex flex-col sm:items-center sm:justify-between gap-4 pb-4 mb-6 border-b border-gray-200'>
|
||||||
<div className='flex-1'>
|
<Heading size='large' spacing='none'>
|
||||||
<Heading size='large'>{name}</Heading>
|
{name}
|
||||||
</div>
|
</Heading>
|
||||||
<PersonCardEdit person={person} />
|
<PersonCardEdit person={person} />
|
||||||
|
{notes && <p className='text-gray-600'>{notes}</p>}
|
||||||
</div>
|
</div>
|
||||||
{notes && <p className='text-gray-600'>{notes}</p>}
|
|
||||||
<div className='flex flex-wrap items-center gap-4 text-sm text-gray-500'>
|
<div className='flex flex-wrap items-center gap-4 text-sm text-gray-500'>
|
||||||
<span>Ilość prezentów: {gifts?.length || 0}</span>
|
<span>Ilość prezentów: {gifts?.length || 0}</span>
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span>Koszt: {formatCurrency(gifts?.reduce((acc, gift) => acc + gift.cost, 0) || 0)}</span>
|
<span>Koszt: {formatCurrency(gifts?.reduce((acc, gift) => acc + gift.cost, 0) || 0)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-8 mb-4 flex items-start gap-4'>
|
<div className='mt-8 mb-4 flex items-start justify-between gap-4'>
|
||||||
<Heading size='medium' spacing='none'>
|
<Heading size='medium' spacing='none'>
|
||||||
Prezenty <br />
|
Prezenty <br />
|
||||||
</Heading>
|
</Heading>
|
||||||
{isOpen && <GiftCardAdd person={person} />}
|
<GiftCardAdd person={person} />
|
||||||
<div className='ml-auto'>
|
|
||||||
<Button variant='secondary' onClick={() => setIsOpen(!isOpen)}>
|
|
||||||
{isOpen ? 'Mniej' : 'Więcej'}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{isOpen && gifts?.map((gift) => <GiftCard key={gift.id} {...gift} hideDetails editable personId={person.id} />)}
|
{gifts?.map((gift) => (
|
||||||
|
<GiftCard key={gift.id} {...gift} hideDetails personId={person.id} />
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user