Skip to content

Commit 96f5fac

Browse files
authored
Merge pull request #13 from HiEventsDev/develop
Fix quantity validation bug + i18n
2 parents f61896f + fbbc6e9 commit 96f5fac

File tree

33 files changed

+1078
-953
lines changed

33 files changed

+1078
-953
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
</div>
2222

23+
<div align="center">
24+
🌟 A star would be much appreciated! 🌟
25+
</div>
26+
2327
<hr/>
2428

2529
## Table of Contents
@@ -93,7 +97,7 @@ a quick start, follow these steps:
9397
cd hi.events/docker/all-in-one
9498
```
9599

96-
3. **Run the set-up script:**
100+
3. **Start the Docker Containers:**
97101
```bash
98102
docker-compose up -d
99103
```

backend/app/Http/Request/User/CreateUserRequest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class CreateUserRequest extends BaseRequest
1313
public function rules(): array
1414
{
1515
return [
16-
'first_name' => 'required|min:2',
17-
'last_name' => 'required|min:2',
16+
'first_name' => 'required|min:1',
17+
'last_name' => 'required|min:1',
1818
'role' => Rule::in(Role::valuesArray()),
1919
'email' => [
2020
'required',

backend/app/Http/Request/User/UpdateMeRequest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ class UpdateMeRequest extends BaseRequest
1414
public function rules(): array
1515
{
1616
return [
17-
'first_name' => 'required_without_all:current_password,password,password_confirmation|min:2',
18-
'last_name' => 'required_without_all:current_password,password,password_confirmation|min:2',
17+
'first_name' => 'required_without_all:current_password,password,password_confirmation|min:1',
18+
'last_name' => 'required_without_all:current_password,password,password_confirmation|min:1',
1919
'email' => 'required_without_all:current_password,password,password_confirmation|email',
2020
'timezone' => 'required_without_all:current_password,password,password_confirmation|timezone',
2121

backend/app/Repository/Eloquent/TicketRepository.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public function getQuantityRemainingForTicketPrice(int $ticketId, int $ticketPri
5959
WHERE order_items.ticket_price_id = :ticketPriceId
6060
AND orders.status in ('RESERVED')
6161
AND current_timestamp < orders.reserved_until
62+
AND orders.deleted_at IS NULL
63+
AND order_items.deleted_at IS NULL
6264
), 0)
6365
) AS quantity_remaining,
6466
ticket_prices.initial_quantity_available IS NULL AS unlimited_tickets_available

backend/app/Resources/Account/AccountResource.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public function toArray(Request $request): array
1616
return [
1717
'id' => $this->getId(),
1818
'name' => $this->getName(),
19-
'email' => $this->getEmail(),
2019
'currency_code' => $this->getCurrencyCode(),
2120
'timezone' => $this->getTimezone(),
2221
'updated_at' => $this->getUpdatedAt(),

backend/app/Resources/Ticket/TicketResourcePublic.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function toArray(Request $request): array
2727
'is_before_sale_start_date' => $this->isBeforeSaleStartDate(),
2828
'is_after_sale_end_date' => $this->isAfterSaleEndDate(),
2929
'price' => $this->when(
30-
(bool)$this->getTicketPrices() && !$this->isTieredType(),
30+
$this->getTicketPrices() && !$this->isTieredType(),
3131
fn() => $this->getPrice(),
3232
),
3333
'prices' => $this->when(
@@ -40,6 +40,7 @@ public function toArray(Request $request): array
4040
),
4141
$this->mergeWhen((bool)$this->getTicketPrices(), fn() => [
4242
'is_available' => $this->isAvailable(),
43+
'is_sold_out' => $this->isSoldOut(),
4344
]),
4445
];
4546
}

backend/app/Services/Domain/Order/OrderCreateRequestValidationService.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,23 @@ private function validateTicketQuantity(int $ticketIndex, array $ticketAndQuanti
170170
$totalQuantity = collect($ticketAndQuantities['quantities'])->sum('quantity');
171171
$maxPerOrder = (int)$ticket->getMaxPerOrder() ?: 100; // Placeholder for config value
172172
$minPerOrder = (int)$ticket->getMinPerOrder() ?: 1;
173+
$ticketQuantityAvailable = $this->ticketRepository->getQuantityRemainingForTicketPrice(
174+
ticketId: $ticket->getId(),
175+
ticketPriceId: $ticketAndQuantities['quantities'][0]['price_id']
176+
);
177+
178+
if ($totalQuantity > $ticketQuantityAvailable) {
179+
throw ValidationException::withMessages([
180+
"tickets.$ticketIndex" => __("The maximum number of tickets available for :ticket is :max", [
181+
'max' => $ticketQuantityAvailable,
182+
'ticket' => $ticket->getTitle(),
183+
]),
184+
]);
185+
}
173186

174187
if ($totalQuantity > $maxPerOrder) {
175188
throw ValidationException::withMessages([
176-
"tickets.$ticketIndex" => __("The maximum numbers number of tickets for :tickets is :max", [
189+
"tickets.$ticketIndex" => __("The maximum number of tickets available for :tickets is :max", [
177190
'max' => $maxPerOrder,
178191
'ticket' => $ticket->getTitle(),
179192
]),

backend/resources/views/emails/auth/reset-password-success.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
Your password has been reset for your account on {{ config('app.name') }}.
55

6-
If you did not request a password reset, please let us know.
6+
If you did not request a password reset, please immediately contact reset your password.
77

88
Thank you
99
</x-mail::message>

docker/development/docker-compose.dev.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ services:
4343
build:
4444
context: ./../../frontend
4545
dockerfile: Dockerfile.ssr.dev
46-
container_name: frontend-ssr
46+
container_name: frontend
4747
ports:
4848
- "5678:5678"
4949
- "24678:24678"

docker/development/start-dev.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ done
7575

7676
echo -e "\n${GREEN}Database is ready. Proceeding with migrations...${NC}"
7777

78-
if [ ! -f ./../backend/.env ]; then
78+
if [ ! -f ./../../backend/.env ]; then
7979
$COMPOSE_CMD exec backend cp .env.example .env
8080
fi
8181

82-
if [ ! -f ./../frontend/.env ]; then
82+
if [ ! -f ./../../frontend/.env ]; then
8383
$COMPOSE_CMD exec frontend cp .env.example .env
8484
fi
8585

frontend/src/components/forms/QuestionForm/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export const QuestionForm = ({form, tickets}: QuestionFormProps) => {
111111
icon: <IconCircleCheck/>,
112112
label: t`Radio Option`,
113113
value: QuestionType.RADIO,
114-
description: t`A Radio option allows has multiple options but only one can be selected.`,
114+
description: t`A Radio option has multiple options but only one can be selected.`,
115115
},
116116
{
117117
icon: <IconSelector/>,

frontend/src/components/routes/account/ManageAccount/sections/AccountSettings/index.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const AccountSettings = () => {
2121
name: '',
2222
currency_code: '',
2323
timezone: '',
24-
email: '',
2524
}
2625
});
2726
const accountQuery = useGetAccount();
@@ -57,20 +56,13 @@ const AccountSettings = () => {
5756
<Card className={classes.tabContent}>
5857
<LoadingMask/>
5958
<fieldset disabled={updateMutation.isLoading || accountQuery.isLoading || !isUserAdmin}>
60-
<form onSubmit={form.onSubmit(handleSubmit)}>
59+
<form onSubmit={form.onSubmit(handleSubmit as any)}>
6160
<TextInput
6261
{...form.getInputProps('name')}
6362
label={t`Account Name`}
6463
placeholder={t`Name`}
6564
description={t`Your account name is used on event pages and in emails.`}
6665
/>
67-
<TextInput
68-
type={'email'}
69-
{...form.getInputProps('email')}
70-
label={t`Account Email`}
71-
placeholder={t`Email`}
72-
description={t`Your account email in outgoing emails.`}
73-
/>
7466
<Select
7567
searchable
7668
data={Object.entries(currencies).map(([key, value]) => ({

frontend/src/components/routes/account/ManageAccount/sections/PaymentSettings/index.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,19 @@ import {Anchor, Button, Group} from "@mantine/core";
88
import {StripeConnectDetails} from "../../../../../../types.ts";
99
import paymentClasses from "./PaymentSettings.module.scss"
1010
import classes from "../../ManageAccount.module.scss"
11+
import {useEffect, useState} from "react";
1112

1213
const ConnectStatus = (props: { stripeDetails: StripeConnectDetails }) => {
13-
const isReturn = window?.location.search.includes('is_return');
14-
const isRefresh = window?.location.search.includes('is_refresh');
15-
const isReturningFromStripe = isReturn || isRefresh;
14+
const [isReturningFromStripe, setIsReturningFromStripe] = useState(false);
15+
16+
useEffect(() => {
17+
if (typeof window === 'undefined') {
18+
return;
19+
}
20+
setIsReturningFromStripe(
21+
window.location.search.includes('is_return') || window.location.search.includes('is_refresh')
22+
);
23+
}, []);
1624

1725
return (
1826
<div className={paymentClasses.stripeInfo}>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.header {
2+
text-align: center;
3+
margin-bottom: 30px;
4+
5+
h2 {
6+
margin: 0;
7+
}
8+
9+
p {
10+
margin-top: -0;
11+
}
12+
}

frontend/src/components/routes/auth/ResetPassword/index.tsx

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {ResetPasswordRequest} from "../../../../types.ts";
99
import {useFormErrorResponseHandler} from "../../../../hooks/useFormErrorResponseHandler.tsx";
1010
import {t} from "@lingui/macro";
1111
import {Card} from "../../../common/Card";
12+
import classes from "./ResetPassword.module.scss";
1213

1314
export const ResetPassword = () => {
1415
const form = useForm({
@@ -48,18 +49,25 @@ export const ResetPassword = () => {
4849
});
4950

5051
return (
51-
<Card>
52-
<form onSubmit={form.onSubmit(handleSubmit)}>
53-
<PasswordInput {...form.getInputProps('password')} label={t`New Password`} required/>
54-
<PasswordInput {...form.getInputProps('password_confirmation')} label={t`Confirm Password`} required/>
55-
<Button type="submit" fullWidth disabled={mutate.isLoading}>
56-
{mutate.isLoading ? t`Working...` : t`Reset password`}
57-
</Button>
58-
</form>
59-
<footer>
60-
<NavLink to={'/auth/login'}>{t`Back to login`}</NavLink>
61-
</footer>
62-
</Card>
52+
<>
53+
<header className={classes.header}>
54+
<h2>{t`Reset Password`}</h2>
55+
<p>{t`Please enter your new password`}</p>
56+
</header>
57+
<Card>
58+
<form onSubmit={form.onSubmit(handleSubmit)}>
59+
<PasswordInput {...form.getInputProps('password')} label={t`New Password`} required/>
60+
<PasswordInput {...form.getInputProps('password_confirmation')} label={t`Confirm Password`} required/>
61+
<Button type="submit" fullWidth disabled={mutate.isLoading}>
62+
{mutate.isLoading ? t`Working...` : t`Reset password`}
63+
</Button>
64+
</form>
65+
<footer>
66+
<NavLink to={'/auth/login'}>{t`Back to login`}</NavLink>
67+
</footer>
68+
</Card>
69+
</>
70+
6371
)
6472
}
6573

frontend/src/components/routes/profile/ManageProfile/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ export const ManageProfile = () => {
5252
userData: formValues,
5353
}, {
5454
onSuccess: () => {
55+
form.reset();
5556
showSuccess(t`Profile updated successfully`);
5657
},
5758
onError: (error: any) => {
58-
showError(t`Something went wrong. Please try again.`);
5959
errorHandler(form, error);
6060
}
6161
})

frontend/src/components/routes/ticket-widget/SelectTickets/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ const SelectTickets = (props: SelectTicketsProps) => {
214214
}
215215
}
216216

217+
const isButtonDisabled = ticketMutation.isLoading
218+
|| !ticketAreAvailable
219+
|| selectedTicketQuantitySum === 0
220+
|| props.widgetMode === 'preview'
221+
|| tickets?.every(ticket => ticket.is_sold_out);
222+
217223
return (
218224
<div className={'hi-ticket-widget-container'}
219225
ref={resizeRef}
@@ -326,7 +332,7 @@ const SelectTickets = (props: SelectTicketsProps) => {
326332
__html: event.settings.ticket_page_message.replace(/\n/g, '<br/>')
327333
}} className={'hi-ticket-page-message'}/>
328334
)}
329-
<Button disabled={props.widgetMode === 'preview'} fullWidth className={'hi-continue-button'}
335+
<Button disabled={isButtonDisabled} fullWidth className={'hi-continue-button'}
330336
type={"submit"}
331337
loading={ticketMutation.isLoading}>
332338
{props.continueButtonText || event?.settings?.continue_button_text || t`Continue`}

frontend/src/locales/de.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)