some minor fixes
This commit is contained in:
@ -3,14 +3,15 @@
|
||||
## Development
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yaml.prod up -d --build
|
||||
docker compose up -d --build
|
||||
docker compose exec -it backend python mange.py migrate
|
||||
docker compose exec -it backend python mange.py createsuperuser
|
||||
```
|
||||
|
||||
Po czym
|
||||
- backend jest dostępny na porcie ```8000```
|
||||
- frontend jest dostępny na porcie ```3000```
|
||||
|
||||
- backend jest dostępny na porcie ``8000``
|
||||
- frontend jest dostępny na porcie ``3000``
|
||||
|
||||
## Produkcja
|
||||
|
||||
@ -21,4 +22,4 @@ docker compose -f docker-compose.yaml.prod exec -it backend python mange.py crea
|
||||
docker compose -f docker-compose.yaml.prod exec -it backend python manage.py collectstatic
|
||||
```
|
||||
|
||||
Po czym aplikacja jest dostępna na porcie ```8080```
|
||||
Po czym aplikacja jest dostępna na porcie ``8080``
|
||||
|
@ -29,6 +29,7 @@ class Meal(models.Model):
|
||||
class Meta:
|
||||
verbose_name = _('Danie')
|
||||
verbose_name_plural = _('Dania')
|
||||
ordering = ['name',]
|
||||
|
||||
|
||||
class Order(models.Model):
|
||||
|
@ -55,6 +55,8 @@ class MealSerializer(serializers.ModelSerializer):
|
||||
class MealViewSet(viewsets.ModelViewSet):
|
||||
queryset = Meal.objects.all()
|
||||
serializer_class = MealSerializer
|
||||
filter_backends = [filters.OrderingFilter]
|
||||
ordering = ['name']
|
||||
|
||||
|
||||
class OrderSerializer(serializers.ModelSerializer):
|
||||
@ -88,9 +90,9 @@ class OrderViewSet(viewsets.ModelViewSet):
|
||||
ordering = ['-created_on']
|
||||
|
||||
def get_queryset(self):
|
||||
five_minutes_ago = timezone.now() + datetime.timedelta(minutes=-5)
|
||||
five_minutes_ago = timezone.now() + datetime.timedelta(minutes=-15)
|
||||
return Order.objects.filter(
|
||||
~Q(status=Order.StatusChoices.FINALIZED)
|
||||
~Q(status__gte=Order.StatusChoices.READY)
|
||||
| Q(updated_on__gte=five_minutes_ago)
|
||||
)
|
||||
|
||||
|
@ -5,8 +5,6 @@ services:
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- django_static_prod:/usr/src/app/static
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
SECRET_KEY: ${SECRET_KEY}
|
||||
DEBUG: False
|
||||
@ -24,8 +22,6 @@ services:
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
ports:
|
||||
- "3000:3000"
|
||||
|
||||
redis:
|
||||
restart: unless-stopped
|
||||
|
@ -16,6 +16,10 @@ textarea {
|
||||
@apply p-1 ps-2 transition ease-in-out focus:outline-none border-b-2 border-b-gray-400 mb-2 focus:bg-gray-100 focus:border-gray-600 appearance-none;
|
||||
}
|
||||
|
||||
.error {
|
||||
@apply !bg-red-200 ring-2 ring-red-400;
|
||||
}
|
||||
|
||||
form#form select {
|
||||
@apply p-2 ps-2 rounded-md bg-gray-100;
|
||||
}
|
||||
|
@ -84,10 +84,10 @@ export default function Home() {
|
||||
}
|
||||
className="form border-2 my-2 border-gray-500"
|
||||
>
|
||||
<option value="1">Zamówienie złożone</option>
|
||||
{/* <option value="1">Zamówienie złożone</option> */}
|
||||
<option value="2">Zamówienie w trakcie przygotowywania</option>
|
||||
<option value="3">Zamówienie gotowe</option>
|
||||
<option value="4">Zamówienie zrealizowane</option>
|
||||
{/* <option value="4">Zamówienie zrealizowane</option> */}
|
||||
</select>
|
||||
</h3>
|
||||
<div className="">
|
||||
@ -103,7 +103,7 @@ export default function Home() {
|
||||
onChange={(e) => update_finished(oi, i, e.target.checked)}
|
||||
/>
|
||||
<div>
|
||||
<p className="text-lg">{dish.item} - {dish.takeout ? 'Na wynos' : 'Na miejscu'}</p>
|
||||
<p className="text-lg">{dish.item}{dish.times > 1 ? ` - x${dish.times}`: ''} - {dish.takeout ? 'Na wynos' : 'Na miejscu'}</p>
|
||||
<div>{dish.additional_info}</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -3,6 +3,7 @@ export type Dish = {
|
||||
additional_info: string;
|
||||
finished: boolean;
|
||||
takeout: boolean;
|
||||
times: number;
|
||||
};
|
||||
|
||||
export type Order = {
|
||||
@ -29,6 +30,8 @@ export function getOrderBg(order: Order): string {
|
||||
}
|
||||
|
||||
export function getDishBg(dish: Dish): string {
|
||||
if (dish.finished) return 'bg-red-200 border-red-400';
|
||||
|
||||
return dish.takeout
|
||||
? 'bg-blue-300 border-blue-500'
|
||||
: 'bg-green-300 border-green-500';
|
||||
|
@ -8,10 +8,15 @@ import { fetcher } from '@/app/api/tools';
|
||||
import useSWR from 'swr';
|
||||
import { Dish } from '@/app/tools';
|
||||
|
||||
type FormDish = Dish & {
|
||||
filter: string;
|
||||
};
|
||||
|
||||
type FormValues = {
|
||||
status: number;
|
||||
client: string;
|
||||
realization_time: string;
|
||||
data: Dish[];
|
||||
data: FormDish[];
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
@ -24,22 +29,37 @@ export default function App() {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
getValues,
|
||||
setValue,
|
||||
watch,
|
||||
} = useForm<FormValues>({
|
||||
defaultValues: {
|
||||
status: 2,
|
||||
client: '',
|
||||
realization_time: new Date().toLocaleTimeString('pl-PL', { hour: '2-digit', minute: '2-digit' }),
|
||||
realization_time: new Date().toLocaleTimeString('pl-PL', {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
}),
|
||||
data: [
|
||||
{ item: 'Inne', additional_info: '', finished: false, takeout: false },
|
||||
{
|
||||
item: '',
|
||||
additional_info: '',
|
||||
finished: false,
|
||||
takeout: false,
|
||||
times: 1,
|
||||
filter: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
mode: 'all',
|
||||
criteriaMode: 'all',
|
||||
shouldFocusError: true
|
||||
});
|
||||
const { fields, append, remove } = useFieldArray({
|
||||
name: 'data',
|
||||
control,
|
||||
});
|
||||
const onSubmit = (data: FormValues) => {
|
||||
console.log(data);
|
||||
fetch('/api/orders', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ waiter: id, ...data }),
|
||||
@ -54,6 +74,8 @@ export default function App() {
|
||||
if (error) return <div>Błąd przy ładowaniu danych</div>;
|
||||
if (isLoading) return <div>Ładowanie</div>;
|
||||
|
||||
watch('data')
|
||||
|
||||
return (
|
||||
<>
|
||||
<form
|
||||
@ -95,21 +117,56 @@ export default function App() {
|
||||
required: false,
|
||||
})}
|
||||
/>
|
||||
<div className="basis-1/3">
|
||||
<div className="basis-1/3 gap-2">
|
||||
<label htmlFor={`data.${index}.item`}>Danie</label>
|
||||
<input
|
||||
{...register(`data.${index}.filter` as const, {
|
||||
required: false,
|
||||
})}
|
||||
placeholder='Wyszukaj danie'
|
||||
className={errors?.data?.[index]?.filter ? 'error' : ''}
|
||||
onChange={(e) => setValue(`data.${index}.item`, data
|
||||
?.filter((data: { id: number; name: string }) =>
|
||||
data.name
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
e.target.value.toLowerCase()
|
||||
)
|
||||
)[0].name, {shouldValidate: true})}
|
||||
/>
|
||||
<select
|
||||
{...register(`data.${index}.item` as const, {
|
||||
required: true,
|
||||
})}
|
||||
className={errors?.data?.[index]?.item ? 'error' : ''}
|
||||
>
|
||||
<option value="Inne">Inne</option>
|
||||
{data?.map((data: { id: number; name: string }) => (
|
||||
<option key={data.name} value={data.name}>
|
||||
{data.name}
|
||||
</option>
|
||||
))}
|
||||
{!!getValues(`data.${index}.filter`) ? (
|
||||
null
|
||||
) : (
|
||||
<option value="Inne">Inne</option>
|
||||
)}
|
||||
{data
|
||||
?.filter((data: { id: number; name: string }) =>
|
||||
data.name
|
||||
.toLowerCase()
|
||||
.includes(
|
||||
getValues(`data.${index}.filter`).toLowerCase()
|
||||
)
|
||||
)
|
||||
.map((data: { id: number; name: string }) => (
|
||||
<option key={data.name} value={data.name}>
|
||||
{data.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<label htmlFor={`data.${index}.times`}>Ilość</label>
|
||||
<input
|
||||
{...register(`data.${index}.times` as const, {
|
||||
required: false,
|
||||
})}
|
||||
type="number"
|
||||
className={errors?.data?.[index]?.times ? 'error' : ''}
|
||||
/>
|
||||
<section className="flex flex-row my-2 gap-2">
|
||||
<label htmlFor={`data.${index}.takeout`}>Na wynos</label>
|
||||
<input
|
||||
@ -157,6 +214,8 @@ export default function App() {
|
||||
additional_info: '',
|
||||
finished: false,
|
||||
takeout: false,
|
||||
times: 1,
|
||||
filter: '',
|
||||
})
|
||||
}
|
||||
>
|
||||
|
@ -9,7 +9,7 @@ import { OrderID } from '@/app/components';
|
||||
|
||||
export default function Home() {
|
||||
const { id } = useParams();
|
||||
const { data, error, isLoading } = useSWR(
|
||||
const { data, error, isLoading, mutate } = useSWR(
|
||||
`/api/orders?waiter=${id}`,
|
||||
fetcher,
|
||||
{
|
||||
@ -17,6 +17,30 @@ export default function Home() {
|
||||
}
|
||||
);
|
||||
|
||||
const update_finished = (o: number, i: number, v: boolean) => {
|
||||
const d = data;
|
||||
d[o].data[i].finished = v;
|
||||
fetch(`/api/orders?id=${d[o].id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(d[o]),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(() => mutate(d));
|
||||
};
|
||||
|
||||
const update_status = (o: number, v: number) => {
|
||||
const d = data;
|
||||
d[o].status = v;
|
||||
fetch(`/api/orders?id=${d[o].id}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(d[o]),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then(() => mutate(d));
|
||||
};
|
||||
|
||||
if (error) return <div>Błąd przy ładowaniu danych</div>;
|
||||
if (isLoading) return <div>Ładowanie</div>;
|
||||
|
||||
@ -29,25 +53,42 @@ export default function Home() {
|
||||
</p>
|
||||
<p className="text-4xl">Zamówienia:</p>
|
||||
<ul className="max-w-screen-md w-full">
|
||||
{data?.map((order: Order) => (
|
||||
{data?.map((order: Order, oi: number) => (
|
||||
<li
|
||||
key={order.id}
|
||||
className={`m-2 p-2 rounded-md border-2 ${getOrderBg(order)}`}
|
||||
>
|
||||
<OrderID order={order} />
|
||||
<h2 className="text-xl">Kelner: {order.waiter_name}</h2>
|
||||
<h2 className="text-xl">{order.waiter_name}</h2>
|
||||
{ (order.client) ? <h2 className="text-xl">Klient: {order.client}</h2> : <></>}
|
||||
<h3>{order.status_name}</h3>
|
||||
<h3>
|
||||
<select
|
||||
value={order.status}
|
||||
onChange={(e) =>
|
||||
update_status(oi, e.target.value as unknown as number)
|
||||
}
|
||||
className="form border-2 my-2 border-gray-500"
|
||||
>
|
||||
{/* <option value="1">Zamówienie złożone</option> */}
|
||||
<option value="2">Zamówienie w trakcie przygotowywania</option>
|
||||
<option value="3">Zamówienie gotowe</option>
|
||||
{/* <option value="4">Zamówienie zrealizowane</option> */}
|
||||
</select>
|
||||
</h3>
|
||||
<div className="">
|
||||
<ul>
|
||||
{order.data.map((dish) => (
|
||||
{order.data.map((dish, i) => (
|
||||
<li
|
||||
key={dish.item}
|
||||
className={`p-2 m-2 flex gap-4 border-2 ${getDishBg(dish)}`}
|
||||
>
|
||||
<input type="checkbox" checked={dish.finished} readOnly />
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={dish.finished}
|
||||
onChange={(e) => update_finished(oi, i, e.target.checked)}
|
||||
/>
|
||||
<div>
|
||||
<p className="text-lg">{dish.item} - {dish.takeout ? 'Na wynos' : 'Na miejscu'}</p>
|
||||
<p className="text-lg">{dish.item}{dish.times > 1 ? ` - x${dish.times}`: ''} - {dish.takeout ? 'Na wynos' : 'Na miejscu'}</p>
|
||||
<div>{dish.additional_info}</div>
|
||||
</div>
|
||||
</li>
|
||||
|
Reference in New Issue
Block a user