Style estimation session list

This commit is contained in:
Pijus Kamandulis 2024-10-06 17:31:02 +03:00
parent 517bc11c56
commit 0c158a4b22
5 changed files with 116 additions and 8 deletions

29
src/components/Card.tsx Normal file
View File

@ -0,0 +1,29 @@
import classNames from 'classnames';
interface CardProps {
title: string;
description: string;
onClick?: () => void;
}
const Card: React.FC<CardProps> = ({ title, description, onClick }) => {
const className = classNames(
'p-4 border rounded-lg shadow-sm transition',
{
'hover:bg-gray-100 dark:hover:bg-nero-800 cursor-pointer': onClick,
'cursor-default': !onClick,
},
'border-gray-300 dark:border-nero-700',
'bg-white dark:bg-nero-900',
'text-gray-800 dark:text-nero-200',
);
return (
<div className={className} onClick={onClick}>
<h3 className="text-lg font-bold">{title}</h3>
<p className="mt-2">{description}</p>
</div>
);
};
export default Card;

View File

@ -0,0 +1,41 @@
interface GridListProps<T> {
items: T[];
colNum: number;
onAddItem: () => void;
itemComponent: React.ComponentType<{ item: T }>;
}
const AddItemButton = ({ onAddItem }: { onAddItem: () => void }) => {
return (
<div
onClick={onAddItem}
className="flex cursor-pointer items-center justify-center rounded-md border-2 border-dashed border-gray-400 hover:border-gray-600"
>
<span className="text-gray-500">+ Add Item</span>
</div>
);
};
const GridList = <T,>({
items,
colNum,
onAddItem,
itemComponent: ItemComponent,
}: GridListProps<T>) => {
return (
<div
className={`grid gap-4`}
style={{
gridTemplateColumns: `repeat(${colNum}, minmax(0, 1fr))`,
}}
>
{onAddItem && <AddItemButton onAddItem={onAddItem} />}
{items.map((item, index) => (
<ItemComponent key={index} item={item} />
))}
</div>
);
};
export default GridList;

View File

@ -1,4 +1,6 @@
import Input from './Input';
import Button, { ButtonColor } from './Button';
import GridList from './GridList';
import Card from './Card';
export { Input, Button, ButtonColor };
export { Input, Button, ButtonColor, GridList, Card };

View File

@ -1,12 +1,16 @@
import reactLogo from '../assets/react.svg';
import viteLogo from '/vite.svg';
import './Home.css';
import { Link } from '@tanstack/react-router';
import { getRouteApi, Link } from '@tanstack/react-router';
import { useUser } from '../lib/context/user';
import { useEstimationSessions } from '../lib/context/estimationSession';
import { Card, GridList } from '../components';
const route = getRouteApi('/');
function Home() {
const user = useUser();
const navigate = route.useNavigate();
const estimationSessions = useEstimationSessions();
return (
@ -33,11 +37,28 @@ function Home() {
<div>
<p>Estimation sessions</p>
{estimationSessions?.current.map((session) => (
<Link key={session.$id} to={`/estimate/session/${session.$id}`}>
{session.Name}
</Link>
))}
<GridList
colNum={2}
items={estimationSessions?.current ?? []}
itemComponent={({ item }) => (
<Card
key={item.$id}
title={item.Name}
description={item.$id}
onClick={() => {
navigate({
to: '/estimate/session/$sessionId',
params: { sessionId: item.$id },
});
}}
/>
)}
onAddItem={() =>
navigate({
to: '/estimate/new',
})
}
/>
</div>
</>
);

View File

@ -2,7 +2,22 @@
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {},
extend: {
colors: {
nero: {
50: '#f7f7f7',
100: '#e1e1e1',
200: '#cfcfcf',
300: '#a8a8a8',
400: '#737373',
500: '#4e4e4e',
600: '#383838',
700: '#2f2f2f',
800: '#282828',
900: '#242424',
},
},
},
},
plugins: [],
};