-
-
Notifications
You must be signed in to change notification settings - Fork 362
Add frontend (without translations) #3837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add frontend (without translations) #3837
Conversation
…or that sessions are not constantly reset for guest users
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
resources/js/composables/checkout/useStepTwo.ts (1)
119-119: Use translation key instead of hardcoded string.Line 119 contains a hardcoded English string
trans("Something went wrong with Mollie.")instead of a proper translation key like other toast messages in this file (e.g.,trans("webshop.useStepTwo.badRequest")).Apply this diff:
- detail: trans("Something went wrong with Mollie."), + detail: trans("webshop.useStepTwo.mollieTokenError"),Note: Ensure the corresponding translation key is added to the language files.
🧹 Nitpick comments (2)
resources/js/composables/checkout/useStepTwo.ts (1)
174-183: Consider handling non-400 errors in handleError.The function currently only handles 400 status codes explicitly. Other HTTP errors (5xx, network failures, etc.) will fail silently without user feedback.
Apply this diff to provide user feedback for all error cases:
function handleError(error: AxiosError) { if (error.response?.status === 400) { toast.add({ severity: "error", summary: trans("webshop.useStepTwo.badRequest"), detail: trans("webshop.useStepTwo.invalidInput"), life: 5000, }); + } else { + toast.add({ + severity: "error", + summary: trans("webshop.useStepTwo.error"), + detail: trans("webshop.useStepTwo.genericError"), + life: 5000, + }); } }resources/js/views/webshop/CheckoutPage.vue (1)
214-248: Add error handling for initialization failures in onMounted.The async initialization in
onMountedhas several sequentialawaitcalls but no error handling. IflycheeStateStore.load()orloadCheckoutOptions()fails, the component will be in an inconsistent state.Apply this diff to add error handling:
onMounted(async () => { - await lycheeStateStore.load(); - await loadCheckoutOptions(); + try { + await lycheeStateStore.load(); + await loadCheckoutOptions(); - if (props.step === undefined) { - router.push({ name: "checkout", params: { step: "info" } }); - } else { - steps.value = stepToNumber(props.step); - } + if (props.step === undefined) { + router.push({ name: "checkout", params: { step: "info" } }); + } else { + steps.value = stepToNumber(props.step); + } - userStore.load().then(() => { - if (userStore.user && userStore.user.email) { - email.value = userStore.user.email; - } - }); - orderStore.load().then(() => { - if (order.value === undefined || order.value?.items === null || order.value.items.length === 0) { - // Redirect to basket if no items - router.push({ name: "gallery" }); - } + userStore.load().then(() => { + if (userStore.user && userStore.user.email) { + email.value = userStore.user.email; + } + }); + orderStore.load().then(() => { + if (order.value === undefined || order.value?.items === null || order.value.items.length === 0) { + // Redirect to basket if no items + router.push({ name: "gallery" }); + } - // Handle order status - if (order.value?.status === "processing") { - // Switch to step 2 if payment is in progress - steps.value = 2; - router.push({ name: "checkout", params: { step: "payment" } }); - } + // Handle order status + if (order.value?.status === "processing") { + // Switch to step 2 if payment is in progress + steps.value = 2; + router.push({ name: "checkout", params: { step: "payment" } }); + } - if (["completed", "closed", "offline"].includes(order.value?.status || "")) { - router.push({ name: "checkout", params: { step: "completed" } }); - } + if (["completed", "closed", "offline"].includes(order.value?.status || "")) { + router.push({ name: "checkout", params: { step: "completed" } }); + } - loadEmailForUser(); - }); + loadEmailForUser(); + }); + } catch (error) { + console.error("Failed to initialize checkout:", error); + toast.add({ + severity: "error", + summary: "Initialization Error", + detail: "Failed to load checkout. Please try again.", + life: 5000, + }); + router.push({ name: "gallery" }); + } });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
resources/js/components/webshop/InfoSection.vue(1 hunks)resources/js/components/webshop/QrCodeLink.vue(1 hunks)resources/js/components/webshop/ThankYou.vue(1 hunks)resources/js/composables/checkout/useStepTwo.ts(1 hunks)resources/js/router/routes.ts(2 hunks)resources/js/views/webshop/BasketList.vue(1 hunks)resources/js/views/webshop/CheckoutPage.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- resources/js/views/webshop/BasketList.vue
- resources/js/router/routes.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.vue: Use TypeScript in composition API for Vue3 and use PrimeVue for UI components
Do not use await async calls in Vue3; use .then() instead
In Vue3 components, the order should be: , then <script lang="ts">, then <style>Files:
resources/js/components/webshop/ThankYou.vueresources/js/views/webshop/CheckoutPage.vueresources/js/components/webshop/QrCodeLink.vueresources/js/components/webshop/InfoSection.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function functionName() {} syntax instead of const function = () => {}
Files:
resources/js/components/webshop/ThankYou.vueresources/js/composables/checkout/useStepTwo.tsresources/js/views/webshop/CheckoutPage.vueresources/js/components/webshop/QrCodeLink.vueresources/js/components/webshop/InfoSection.vue🧠 Learnings (12)
📓 Common learnings
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/cz/gallery.php:210-210 Timestamp: 2025-08-27T08:48:27.520Z Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Use TypeScript in composition API for Vue3 and use PrimeVue for UI componentsApplied to files:
resources/js/components/webshop/ThankYou.vue📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : In Vue3 components, the order should be: <template>, then <script lang="ts">, then <style>Applied to files:
resources/js/components/webshop/ThankYou.vue📚 Learning: 2025-11-30T17:19:00.773Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Applied to files:
resources/js/composables/checkout/useStepTwo.tsresources/js/views/webshop/CheckoutPage.vue📚 Learning: 2025-09-28T08:27:31.767Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:27-31 Timestamp: 2025-09-28T08:27:31.767Z Learning: The maintainer ildyria has indicated that error handling for rotate functions in photoActions.ts should be ignored and not flagged as an issue.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-09-28T08:27:38.332Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:39-43 Timestamp: 2025-09-28T08:27:38.332Z Learning: The user ildyria (repository maintainer) prefers to skip error handling for the rotate photo functions (rotatePhotoCW and rotatePhotoCCW) in resources/js/composables/album/photoActions.ts.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-22T06:11:18.329Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Applied to files:
resources/js/composables/checkout/useStepTwo.tsresources/js/views/webshop/CheckoutPage.vueresources/js/components/webshop/InfoSection.vue📚 Learning: 2025-08-27T08:48:45.672Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/es/gallery.php:210-210 Timestamp: 2025-08-27T08:48:45.672Z Learning: The project maintainer ildyria has indicated that language localization consistency is not a priority ("Lang = don't care"), meaning English text in non-English language files is acceptable and should not be flagged as an issue.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-16T14:00:53.808Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3504 File: resources/js/composables/selections/selections.ts:145-147 Timestamp: 2025-08-16T14:00:53.808Z Learning: In the Lychee codebase, the maintainer ildyria has indicated that bounds checking for array access in selectables.albums.value[idx] within the albumClick function in resources/js/composables/selections/selections.ts is not necessary, suggesting there are adequate safeguards elsewhere in the code or the access pattern is guaranteed to be safe.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-18T10:19:04.946Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3626 File: database/migrations/2025_06_07_144157_photo_tags_to_table.php:87-105 Timestamp: 2025-08-18T10:19:04.946Z Learning: In the Lychee photo management system, the migration `2025_06_07_144157_photo_tags_to_table.php` runs on data that only contains comma-separated tag names in tag_albums.show_tags - OR/AND expressions do not exist at this migration time, so handling them is unnecessary.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadApplied to files:
resources/js/views/webshop/CheckoutPage.vue📚 Learning: 2025-09-28T09:04:05.578Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-205 Timestamp: 2025-09-28T09:04:05.578Z Learning: In Vue3 code, the preference between async/await and promise chaining depends on context: async/await is very much preferred in services, while in other locations it depends on the specific use case.Applied to files:
resources/js/views/webshop/CheckoutPage.vue🧬 Code graph analysis (1)
resources/js/composables/checkout/useStepTwo.ts (3)
resources/js/lychee.d.ts (2)
OmnipayProviderType(106-106)CheckoutResource(909-916)resources/js/services/webshop-service.ts (1)
CardDetails(37-42)resources/js/stores/OrderManagement.ts (1)
OrderManagementStateStore(5-5)⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Feature_v2
- GitHub Check: 2️⃣ PHP 8.3 - Code Style errors
- GitHub Check: 2️⃣ PHP 8.3 - PHPStan
🔇 Additional comments (1)
resources/js/components/webshop/InfoSection.vue (1)
67-74: LGTM!The
stripfunction properly sanitizes HTML by parsing it through DOMParser and extracting only text content. This prevents XSS when user data is inserted intov-htmlwithsprintf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
resources/js/views/webshop/OrderDownload.vue (1)
227-258: Fix inconsistent translation keys and avoid wrapping hard-coded strings intrans()This section still has the two issues previously flagged:
- The
elsebranch usessummary: trans("toasts.error")while thecatchbranch usestrans("toast.error").- The detail message is a hard-coded English string in one branch and passed as a literal to
trans()in the other, which will be treated as a missing key.Recommend normalizing both branches to the same key-based translation:
- .catch(() => { - // Fallback if clipboard write fails - toast.add({ - severity: "error", - summary: trans("toast.error"), - detail: "Could not copy to clipboard.", - life: 3000, - }); - }); - } else { - toast.add({ - severity: "error", - summary: trans("toasts.error"), - detail: trans("Could not copy to clipboard."), - life: 3000, - }); - } + .catch(() => { + toast.add({ + severity: "error", + summary: trans("toast.error"), + detail: trans("webshop.orderDownload.clipboardNotSupported"), + life: 3000, + }); + }); + } else { + toast.add({ + severity: "error", + summary: trans("toast.error"), + detail: trans("webshop.orderDownload.clipboardNotSupported"), + life: 3000, + }); + }You’d just need to add the
webshop.orderDownload.clipboardNotSupportedkey to your lang files (English text is fine per your existing workflow).
🧹 Nitpick comments (3)
resources/js/views/webshop/OrderDownload.vue (3)
205-209:asynconload()is unnecessary
load()doesn’t useawaitand simply returns thePromisefromInitService.fetchGlobalRights().then(...), so theasynckeyword adds no value and can be dropped:-async function load(): Promise<void> { - return InitService.fetchGlobalRights().then((data) => { - initData.value = data.data; - }); -} +function load(): Promise<void> { + return InitService.fetchGlobalRights().then((data) => { + initData.value = data.data; + }); +}This also matches the rest of the
.then()-based style in the file.
114-141: Consider pre-filling the content URL input when editing existing linksWhen
editis toggled on anditem.content_urlis already set,showInput(item)shows an empty<InputText>instead of the current URL. That makes it harder to tweak an existing link and forces the user to retrieve/copy it from elsewhere.If
OrderItemResourceexposes the existing manual/download link, you could bind it so edits start from the current value, e.g. (conceptually):<InputText v-model="localLinkFor(item.id)" :placeholder="$t('webshop.orderDownload.enterContentUrl')" class="w-full text-left" @update:modelValue="(v) => updateItemLink({ id: item.id, download_link: v ?? '' })" />or at least initialize the field once with the existing URL when entering edit mode. Optional, but would improve admin UX.
280-287: Add error handling formarkAsDeliveredfailuresIf
WebshopService.Order.markAsDeliveredrejects, the user gets no feedback anditemsToUpdateremains populated, but the UI doesn’t explain what went wrong.Consider adding a
.catchwith an error toast and (optionally) logging:function markAsDelivered() { if (order.value) { - WebshopService.Order.markAsDelivered(order.value.id, itemsToUpdate.value).then(() => { - itemsToUpdate.value = []; - loadOrder(); - }); + WebshopService.Order.markAsDelivered(order.value.id, itemsToUpdate.value) + .then(() => { + itemsToUpdate.value = []; + loadOrder(); + }) + .catch(() => { + toast.add({ + severity: "error", + summary: trans("toast.error"), + detail: trans("webshop.orderDownload.deliverFailed"), + life: 3000, + }); + }); } }(And add
webshop.orderDownload.deliverFailedto your translations.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
resources/js/components/webshop/QrCodeLink.vue(1 hunks)resources/js/components/webshop/ThankYou.vue(1 hunks)resources/js/views/webshop/CheckoutPage.vue(1 hunks)resources/js/views/webshop/OrderDownload.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- resources/js/components/webshop/ThankYou.vue
- resources/js/views/webshop/CheckoutPage.vue
- resources/js/components/webshop/QrCodeLink.vue
🧰 Additional context used
📓 Path-based instructions (2)
**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.vue: Use TypeScript in composition API for Vue3 and use PrimeVue for UI components
Do not use await async calls in Vue3; use .then() instead
In Vue3 components, the order should be: , then <script lang="ts">, then <style>Files:
resources/js/views/webshop/OrderDownload.vue**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function functionName() {} syntax instead of const function = () => {}
Files:
resources/js/views/webshop/OrderDownload.vue🧠 Learnings (7)
📓 Common learnings
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/cz/gallery.php:210-210 Timestamp: 2025-08-27T08:48:27.520Z Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : In Vue3 components, the order should be: <template>, then <script lang="ts">, then <style>Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-11-30T17:19:00.773Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-22T06:11:18.329Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-27T08:48:45.672Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/es/gallery.php:210-210 Timestamp: 2025-08-27T08:48:45.672Z Learning: The project maintainer ildyria has indicated that language localization consistency is not a priority ("Lang = don't care"), meaning English text in non-English language files is acceptable and should not be flagged as an issue.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-20T20:35:04.474Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-27T08:48:32.956Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/pl/gallery.php:210-210 Timestamp: 2025-08-27T08:48:32.956Z Learning: The user ildyria does not prioritize strict localization consistency for new menu items in language files, as indicated by their "Lang = don't care" response when suggested to translate 'Import from Server' to Polish in lang/pl/gallery.php.Applied to files:
resources/js/views/webshop/OrderDownload.vue⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: 3️⃣ PHP dist / 8.4 - mariadb
- GitHub Check: 2️⃣ PHP tests / 8.4 - mariadb -- Install
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Unit
🔇 Additional comments (2)
resources/js/views/webshop/OrderDownload.vue (2)
1-151: Overall template structure and conditional rendering look solidThe toolbar, loading/empty/data states, and item/order sections are well-structured and align with the existing webshop UI; no structural issues spotted here.
153-292: Script setup and remaining helpers look consistent with project conventionsAside from the nits above, the imports, props, refs, navigation helpers, and updateItemLink/showInput logic all align with the existing webshop patterns and TypeScript/Composition API style in this repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
resources/js/views/webshop/CheckoutPage.vue (1)
208-212: Add null check before accessingorder.value!.provider.This uses a non-null assertion without verifying
order.valueexists. If called when the order is undefined, this will throw a runtime error.Suggested fix
function goToInfo() { canProcessPayment.value = false; - order.value!.provider = null; + if (order.value) { + order.value.provider = null; + } router.push({ name: "checkout", params: { step: "info" } }); }resources/js/views/webshop/OrderDownload.vue (1)
243-259: Translation key inconsistencies and hardcoded strings remain.Two issues persist:
- Line 248 uses a hardcoded string
"Could not copy to clipboard."withouttrans().- Line 255 uses
"toasts.error"(plural) while line 247 uses"toast.error"(singular).- Line 256 wraps a hardcoded English string in
trans()instead of using a translation key.Suggested fix
.catch(() => { // Fallback if clipboard write fails toast.add({ severity: "error", summary: trans("toast.error"), - detail: "Could not copy to clipboard.", + detail: trans("webshop.orderDownload.clipboardCopyFailed"), life: 3000, }); }); } else { toast.add({ severity: "error", - summary: trans("toasts.error"), - detail: trans("Could not copy to clipboard."), + summary: trans("toast.error"), + detail: trans("webshop.orderDownload.clipboardNotSupported"), life: 3000, }); }
🧹 Nitpick comments (2)
resources/js/composables/checkout/useStepTwo.ts (1)
103-112: Consider adding fallback for non-400 errors.The
handleErrorfunction only handles HTTP 400 responses. Other errors (network failures, 5xx responses, etc.) are silently ignored, which may leave users without feedback. A previous review comment suggested adding an else branch.Optional enhancement
function handleError(error: AxiosError) { if (error.response?.status === 400) { toast.add({ severity: "error", summary: trans("webshop.useStepTwo.badRequest"), detail: trans("webshop.useStepTwo.invalidInput"), life: 5000, }); + } else { + console.error("Payment error:", error); } }resources/js/views/webshop/OrderDownload.vue (1)
290-293: Consider adding error handling toonMounted.Both
loadOrder()andload()are called without coordinating their completion or handling potential failures. Ifload()fails,initDatawon't be populated, affecting the edit controls.Optional enhancement
onMounted(() => { loadOrder(); - load(); + load().catch((error) => { + console.error("Failed to load global rights:", error); + }); });
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (13)
package.json(1 hunks)resources/js/components/webshop/PaymentForm.vue(1 hunks)resources/js/composables/checkout/useDummy.ts(1 hunks)resources/js/composables/checkout/useMollie.ts(1 hunks)resources/js/composables/checkout/usePaypal.ts(1 hunks)resources/js/composables/checkout/useStepTwo.ts(1 hunks)resources/js/lychee.d.ts(2 hunks)resources/js/services/webshop-service.ts(1 hunks)resources/js/stores/CatalogState.ts(1 hunks)resources/js/stores/LycheeState.ts(1 hunks)resources/js/stores/OrderManagement.ts(1 hunks)resources/js/views/webshop/CheckoutPage.vue(1 hunks)resources/js/views/webshop/OrderDownload.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- resources/js/services/webshop-service.ts
- package.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function functionName() {} syntax instead of const function = () => {}
Files:
resources/js/composables/checkout/usePaypal.tsresources/js/lychee.d.tsresources/js/composables/checkout/useDummy.tsresources/js/composables/checkout/useStepTwo.tsresources/js/stores/CatalogState.tsresources/js/views/webshop/OrderDownload.vueresources/js/stores/OrderManagement.tsresources/js/components/webshop/PaymentForm.vueresources/js/views/webshop/CheckoutPage.vueresources/js/composables/checkout/useMollie.tsresources/js/stores/LycheeState.ts
**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.vue: Use TypeScript in composition API for Vue3 and use PrimeVue for UI components
Do not use await async calls in Vue3; use .then() instead
In Vue3 components, the order should be: , then <script lang="ts">, then <style>Files:
resources/js/views/webshop/OrderDownload.vueresources/js/components/webshop/PaymentForm.vueresources/js/views/webshop/CheckoutPage.vue🧠 Learnings (17)
📓 Common learnings
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/cz/gallery.php:210-210 Timestamp: 2025-08-27T08:48:27.520Z Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.📚 Learning: 2025-11-30T17:19:00.773Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Applied to files:
resources/js/composables/checkout/usePaypal.tsresources/js/composables/checkout/useDummy.tsresources/js/composables/checkout/useStepTwo.tsresources/js/views/webshop/OrderDownload.vueresources/js/components/webshop/PaymentForm.vueresources/js/views/webshop/CheckoutPage.vueresources/js/composables/checkout/useMollie.ts📚 Learning: 2025-09-28T08:46:37.299Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/stores/UserState.ts:7-11 Timestamp: 2025-09-28T08:46:37.299Z Learning: In Lychee codebase, the type `App.Enum.OauthProvidersType` is properly defined within the `App.Enum` namespace in `resources/js/lychee.d.ts` file. References to `App.Enum.OauthProvidersType` in TypeScript files are valid and resolve correctly.Applied to files:
resources/js/lychee.d.ts📚 Learning: 2025-09-28T08:27:31.767Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:27-31 Timestamp: 2025-09-28T08:27:31.767Z Learning: The maintainer ildyria has indicated that error handling for rotate functions in photoActions.ts should be ignored and not flagged as an issue.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-09-28T08:27:38.332Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:39-43 Timestamp: 2025-09-28T08:27:38.332Z Learning: The user ildyria (repository maintainer) prefers to skip error handling for the rotate photo functions (rotatePhotoCW and rotatePhotoCCW) in resources/js/composables/album/photoActions.ts.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-22T06:11:18.329Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Applied to files:
resources/js/composables/checkout/useStepTwo.tsresources/js/views/webshop/OrderDownload.vueresources/js/views/webshop/CheckoutPage.vue📚 Learning: 2025-08-27T08:48:45.672Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/es/gallery.php:210-210 Timestamp: 2025-08-27T08:48:45.672Z Learning: The project maintainer ildyria has indicated that language localization consistency is not a priority ("Lang = don't care"), meaning English text in non-English language files is acceptable and should not be flagged as an issue.Applied to files:
resources/js/composables/checkout/useStepTwo.tsresources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-16T14:00:53.808Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3504 File: resources/js/composables/selections/selections.ts:145-147 Timestamp: 2025-08-16T14:00:53.808Z Learning: In the Lychee codebase, the maintainer ildyria has indicated that bounds checking for array access in selectables.albums.value[idx] within the albumClick function in resources/js/composables/selections/selections.ts is not necessary, suggesting there are adequate safeguards elsewhere in the code or the access pattern is guaranteed to be safe.Applied to files:
resources/js/composables/checkout/useStepTwo.tsresources/js/stores/CatalogState.ts📚 Learning: 2025-08-18T10:19:04.946Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3626 File: database/migrations/2025_06_07_144157_photo_tags_to_table.php:87-105 Timestamp: 2025-08-18T10:19:04.946Z Learning: In the Lychee photo management system, the migration `2025_06_07_144157_photo_tags_to_table.php` runs on data that only contains comma-separated tag names in tag_albums.show_tags - OR/AND expressions do not exist at this migration time, so handling them is unnecessary.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-09-28T08:39:34.280Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/stores/NsfwConsentedState.ts:3-5 Timestamp: 2025-09-28T08:39:34.280Z Learning: In Lychee codebase, all Pinia store files follow the pattern of declaring the type alias before the store definition (e.g., `export type StoreType = ReturnType<typeof useStore>; export const useStore = defineStore(...)`). This pattern compiles successfully with TypeScript 5.9 and vue-tsc.Applied to files:
resources/js/stores/CatalogState.tsresources/js/stores/OrderManagement.tsresources/js/stores/LycheeState.ts📚 Learning: 2025-09-28T12:43:29.852Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-204 Timestamp: 2025-09-28T12:43:29.852Z Learning: The photoStore.load() method in resources/js/stores/PhotoState.ts already handles undefined photoId cases internally with a short circuit exit, so conditional checks before calling photoStore.load() are unnecessary.Applied to files:
resources/js/stores/CatalogState.tsresources/js/stores/OrderManagement.tsresources/js/stores/LycheeState.ts📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : In Vue3 components, the order should be: <template>, then <script lang="ts">, then <style>Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-20T20:35:04.474Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-27T08:48:32.956Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/pl/gallery.php:210-210 Timestamp: 2025-08-27T08:48:32.956Z Learning: The user ildyria does not prioritize strict localization consistency for new menu items in language files, as indicated by their "Lang = don't care" response when suggested to translate 'Import from Server' to Polish in lang/pl/gallery.php.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Use TypeScript in composition API for Vue3 and use PrimeVue for UI componentsApplied to files:
resources/js/components/webshop/PaymentForm.vue📚 Learning: 2025-11-25T21:26:03.890Z
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadApplied to files:
resources/js/views/webshop/CheckoutPage.vue📚 Learning: 2025-09-28T09:04:05.578Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-205 Timestamp: 2025-09-28T09:04:05.578Z Learning: In Vue3 code, the preference between async/await and promise chaining depends on context: async/await is very much preferred in services, while in other locations it depends on the specific use case.Applied to files:
resources/js/views/webshop/CheckoutPage.vue🧬 Code graph analysis (6)
resources/js/composables/checkout/usePaypal.ts (3)
resources/js/lychee.d.ts (1)
CheckoutOptionResource(899-911)app/DTO/DiagnosticData.php (1)
error(40-43)app/Actions/Shop/OrderService.php (1)
createOrder(92-102)resources/js/composables/checkout/useDummy.ts (2)
resources/js/services/webshop-service.ts (1)
CardDetails(37-42)resources/js/lychee.d.ts (1)
CheckoutResource(912-919)resources/js/composables/checkout/useStepTwo.ts (6)
resources/js/lychee.d.ts (2)
OmnipayProviderType(106-106)CheckoutResource(912-919)resources/js/stores/OrderManagement.ts (1)
OrderManagementStateStore(5-5)resources/js/composables/checkout/useDummy.ts (1)
useDummy(14-74)resources/js/composables/checkout/useMollie.ts (1)
useMollie(30-99)resources/js/services/webshop-service.ts (1)
CardDetails(37-42)app/Actions/Shop/CheckoutService.php (1)
processPayment(53-149)resources/js/stores/CatalogState.ts (2)
resources/js/stores/LycheeState.ts (1)
useLycheeStateStore(6-185)resources/js/config/constants.ts (1)
ALL(2-2)resources/js/stores/OrderManagement.ts (2)
resources/js/lychee.d.ts (1)
CheckoutOptionResource(899-911)resources/js/services/webshop-service.ts (2)
AddPhoto(10-17)AddAlbum(19-26)resources/js/composables/checkout/useMollie.ts (1)
resources/js/lychee.d.ts (2)
CheckoutOptionResource(899-911)CheckoutResource(912-919)⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- ImageProcessing
- GitHub Check: 2️⃣ JS front-end / Node 20
- GitHub Check: 2️⃣ JS front-end / Node 22
- GitHub Check: 2️⃣ PHP 8.3 - PHPStan
- GitHub Check: 2️⃣ PHP 8.3 - Code Style errors
🔇 Additional comments (17)
resources/js/stores/LycheeState.ts (1)
94-94: LGTM! Signature change aligns with async initialization pattern.The
asynckeyword addition allows callers toawaitthis method while the implementation correctly continues using.then()/.catch()chains as per the coding guidelines.resources/js/lychee.d.ts (1)
106-106: LGTM! Type definitions align with the new PayPal integration.The consolidation of PayPal provider variants into a single
"PayPal"type and the addition ofpaypal_client_idproperly support the modern PayPal JS SDK integration introduced in this PR.Also applies to: 908-908
resources/js/composables/checkout/useDummy.ts (1)
1-74: LGTM! Well-structured dummy payment composable.The implementation correctly follows the coding guidelines:
- Uses
functionsyntax throughout- Uses
.then()/.catch()chains instead ofawait- Includes proper Luhn algorithm validation for card numbers
- Module-level
cardDetailsref is intentional for state sharing (as per project pattern)resources/js/components/webshop/PaymentForm.vue (1)
1-130: LGTM! Well-structured multi-provider payment form.The component correctly:
- Uses TypeScript composition API with PrimeVue components
- Conditionally renders provider-specific UIs (Mollie, PayPal, generic card form)
- Integrates checkout composables and state stores properly
- Applies custom Mollie styling with dark mode support
resources/js/stores/CatalogState.ts (1)
1-65: LGTM! Well-implemented catalog state management.The store correctly:
- Follows Lychee's Pinia store pattern with type alias before definition
- Uses
.then()chains instead ofawaitas per guidelines- Sets
isLoading = truebefore loading (addressing past review feedback)- Implements proper loading guards to prevent redundant fetches and race conditions
- Guards for SE/Pro features appropriately
resources/js/composables/checkout/usePaypal.ts (2)
22-59: Replaceawaitcalls with.then()chains.Lines 36 and 49 use
awaitwhich violates the coding guideline: "Do not use await async calls in Vue3; use .then() instead".🔎 Refactor to use .then() chains
- async function mountPaypal(options: Ref<undefined | App.Http.Resources.Shop.CheckoutOptionResource>) { + function mountPaypal(options: Ref<undefined | App.Http.Resources.Shop.CheckoutOptionResource>) { if (options.value?.paypal_client_id === undefined || options.value?.paypal_client_id === null || options.value?.paypal_client_id === "") { toast.add({ severity: "error", summary: trans("webshop.usePaypal.error"), detail: trans("webshop.usePaypal.client_id_missing"), life: 3000, }); return; } - await waitForElement("paypal-button-container"); - - try { - paypal.value = await loadScript({ clientId: options.value.paypal_client_id, currency: options.value.currency }); - } catch (error) { - toast.add({ - severity: "error", - summary: "PayPal JS SDK Load Error", - detail: "failed to load the PayPal JS SDK script", - life: 3000, - }); - console.error("failed to load the PayPal JS SDK script", error); - } - - if (paypal.value !== null && paypal.value.Buttons !== undefined) { - try { - await paypal.value - .Buttons({ - createOrder: createOrder, - onApprove: onApprove, - }) - .render("#paypal-button-container"); - } catch (error) { - console.error("failed to render the PayPal Buttons", error); - } - } + waitForElement("paypal-button-container").then(() => { + loadScript({ clientId: options.value.paypal_client_id, currency: options.value.currency }) + .then((loadedPaypal) => { + paypal.value = loadedPaypal; + if (paypal.value !== null && paypal.value.Buttons !== undefined) { + paypal.value + .Buttons({ + createOrder: createOrder, + onApprove: onApprove, + }) + .render("#paypal-button-container") + .catch((error) => { + console.error("failed to render the PayPal Buttons", error); + }); + } + }) + .catch((error) => { + toast.add({ + severity: "error", + summary: "PayPal JS SDK Load Error", + detail: "failed to load the PayPal JS SDK script", + life: 3000, + }); + console.error("failed to load the PayPal JS SDK script", error); + }); + }); }As per coding guidelines.
⛔ Skipped due to learnings
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadLearnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.
61-79: Replaceawaitwith proper.then()chain and avoid mixing patterns.Line 63 uses
awaitwith.then()which violates the coding guideline: "Do not use await async calls in Vue3; use .then() instead". Also, mixingawaitand.then()is awkward.🔎 Refactor to use .then() chain only
- async function createOrder(): Promise<string> { - try { - return await WebshopService.Checkout.processCheckout({ additional_data: {} }) - .then((response) => { - console.log("Created session for PayPal", response.data); - if (!response.data.order?.transaction_id) { - throw new Error("No transaction ID received from server"); - } - return response.data.order.transaction_id; - }) - .catch((error) => { - console.log("Error creating session for PayPal", error); - throw new Error(`Could not create PayPal order: ${error.message}`); - }); - } catch (error) { - console.error(error); - throw new Error("Could not render PayPal Buttons"); - } + function createOrder(): Promise<string> { + return WebshopService.Checkout.processCheckout({ additional_data: {} }) + .then((response) => { + console.log("Created session for PayPal", response.data); + if (!response.data.order?.transaction_id) { + throw new Error("No transaction ID received from server"); + } + return response.data.order.transaction_id; + }) + .catch((error) => { + console.log("Error creating session for PayPal", error); + throw new Error(`Could not create PayPal order: ${error.message}`); + }); }As per coding guidelines.
⛔ Skipped due to learnings
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadLearnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-205 Timestamp: 2025-09-28T09:04:05.578Z Learning: In Vue3 code, the preference between async/await and promise chaining depends on context: async/await is very much preferred in services, while in other locations it depends on the specific use case.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3683 File: app/Actions/Shop/CheckoutService.php:50-68 Timestamp: 2025-09-13T13:58:16.970Z Learning: In the Shop system, Order models are always created via OrderService::createOrder() which automatically assigns a UUID to the transaction_id field during creation (line 42: 'transaction_id' => Str::uuid()). Therefore, transaction_id is never null or empty when orders reach the CheckoutService for payment processing.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3683 File: app/Actions/Shop/CheckoutService.php:50-68 Timestamp: 2025-09-13T13:58:16.970Z Learning: In the Shop system, Order models are always created via OrderService::createOrder() which automatically assigns a UUID to the transaction_id field during creation. Therefore, transaction_id is never null or empty when orders reach the CheckoutService for payment processing.resources/js/stores/OrderManagement.ts (3)
78-86: Replaceawaitwith.then()chain.The
awaitcall on line 84 violates the coding guideline: "Do not use await async calls in Vue3; use .then() instead".🔎 Refactor to use .then() chain
- async forget(): Promise<void> { + forget(): Promise<void> { // Guard for SE if (useLycheeStateStore().is_pro_enabled !== true) { return Promise.resolve(); } this.reset(); - await WebshopService.Order.forget(); - return Promise.resolve(); + return WebshopService.Order.forget(); },As per coding guidelines.
⛔ Skipped due to learnings
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadLearnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-205 Timestamp: 2025-09-28T09:04:05.578Z Learning: In Vue3 code, the preference between async/await and promise chaining depends on context: async/await is very much preferred in services, while in other locations it depends on the specific use case.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.
69-77: Replaceawaitwith.then()chain.The
awaitcalls on lines 75-76 violate the coding guideline: "Do not use await async calls in Vue3; use .then() instead".🔎 Refactor to use .then() chain
- async clear(): Promise<void> { + clear(): Promise<void> { // Guard for SE if (useLycheeStateStore().is_pro_enabled !== true) { return Promise.resolve(); } this.reset(); - await WebshopService.Order.clearBasket(); - return this.load(); + return WebshopService.Order.clearBasket().then(() => { + return this.load(); + }); },As per coding guidelines.
⛔ Skipped due to learnings
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadLearnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-205 Timestamp: 2025-09-28T09:04:05.578Z Learning: In Vue3 code, the preference between async/await and promise chaining depends on context: async/await is very much preferred in services, while in other locations it depends on the specific use case.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/stores/NsfwConsentedState.ts:3-5 Timestamp: 2025-09-28T08:39:34.280Z Learning: In Lychee codebase, all Pinia store files follow the pattern of declaring the type alias before the store definition (e.g., `export type StoreType = ReturnType<typeof useStore>; export const useStore = defineStore(...)`). This pattern compiles successfully with TypeScript 5.9 and vue-tsc.
34-48: Replaceawaitwith.then()chain.The
await this.load()on line 42 violates the coding guideline: "Do not use await async calls in Vue3; use .then() instead".🔎 Refactor to use .then() chain
- async addPhoto(photoData: AddPhoto): Promise<void> { + addPhoto(photoData: AddPhoto): Promise<void> { // Guard for SE if (useLycheeStateStore().is_pro_enabled !== true) { return Promise.resolve(); } // First load the order if not yet done if (this.order === undefined) { - await this.load(); + return this.load().then(() => { + return WebshopService.Order.addPhotoToBasket(photoData).then((response) => { + this.order = response.data; + }); + }); } return WebshopService.Order.addPhotoToBasket(photoData).then((response) => { this.order = response.data; }); },As per coding guidelines.
⛔ Skipped due to learnings
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-204 Timestamp: 2025-09-28T12:43:29.852Z Learning: The photoStore.load() method in resources/js/stores/PhotoState.ts already handles undefined photoId cases internally with a short circuit exit, so conditional checks before calling photoStore.load() are unnecessary.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/stores/NsfwConsentedState.ts:3-5 Timestamp: 2025-09-28T08:39:34.280Z Learning: In Lychee codebase, all Pinia store files follow the pattern of declaring the type alias before the store definition (e.g., `export type StoreType = ReturnType<typeof useStore>; export const useStore = defineStore(...)`). This pattern compiles successfully with TypeScript 5.9 and vue-tsc.Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadLearnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3683 File: app/Actions/Shop/OrderService.php:65-73 Timestamp: 2025-09-16T21:56:01.607Z Learning: The validation for album-photo membership in OrderService::addPhotoToOrder() is implemented within PurchasableService::getEffectivePurchasableForPhoto() using a whereHas('albums') constraint that ensures the photo belongs to the specified album_id before applying pricing logic.resources/js/composables/checkout/useMollie.ts (1)
68-91: Replaceawaitwith.then()chain.Line 72 uses
await mollie.value.createToken()which violates the coding guideline: "Do not use await async calls in Vue3; use .then() instead".🔎 Refactor to use .then() chain
- async function processMolliePayment( + function processMolliePayment( handleSuccess: (response: AxiosResponse<App.Http.Resources.Shop.CheckoutResource>) => void, handleError: (error: AxiosError) => void, ) { - const { token, error } = await mollie.value.createToken(); - if (error) { - // Something wrong happened while creating the token. Handle this situation gracefully. - toast.add({ - severity: "error", - summary: trans("toasts.error"), - detail: trans("Something went wrong with Mollie."), - life: 5000, - }); - return; - } - - WebshopService.Checkout.processCheckout({ - additional_data: { - cardToken: token, - }, - }) - .then(handleSuccess) - .catch(handleError); + mollie.value.createToken().then(({ token, error }) => { + if (error) { + // Something wrong happened while creating the token. Handle this situation gracefully. + toast.add({ + severity: "error", + summary: trans("toasts.error"), + detail: trans("Something went wrong with Mollie."), + life: 5000, + }); + return; + } + + WebshopService.Checkout.processCheckout({ + additional_data: { + cardToken: token, + }, + }) + .then(handleSuccess) + .catch(handleError); + }); }As per coding guidelines.
⛔ Skipped due to learnings
Learnt from: CR Repo: LycheeOrg/Lychee PR: 0 File: .github/copilot-instructions.md:0-0 Timestamp: 2025-11-25T21:26:03.890Z Learning: Applies to **/*.vue : Do not use await async calls in Vue3; use .then() insteadLearnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3810 File: app/Actions/Shop/CheckoutService.php:70-72 Timestamp: 2025-11-17T11:36:52.888Z Learning: For Mollie and Stripe payment providers in the CheckoutService, the payment flow uses redirects rather than POST callbacks. When the user completes payment, they are redirected back to Lychee with query parameters in the URL (not POST data). The purchase parameters stored in the session are used with completePurchase() to verify the payment, and any necessary callback data comes from the query parameters in the redirect URL, which Omnipay handles automatically.resources/js/composables/checkout/useStepTwo.ts (1)
1-13: Imports and module-level state look good.The imports are correctly organized, and the module-level refs for shared state are intentional per project architecture. The use of
functionsyntax aligns with coding guidelines.resources/js/views/webshop/CheckoutPage.vue (2)
1-138: Template structure is well-organized with proper LTR/RTL handling.The template correctly handles offline vs online checkout flows, uses PrimeVue components appropriately, and includes proper accessibility through the Stepper component. The conditional rendering for LTR/RTL button icons is a nice touch.
139-186: Composables and store setup look correct.The imports follow the proper patterns, using PrimeVue components and Vue 3 composition API. The use of
storeToRefsfor reactive store access is correct.resources/js/views/webshop/OrderDownload.vue (3)
1-151: Template structure is comprehensive and well-designed.The template handles multiple states (loading, no access, order display) gracefully. The conditional rendering for edit mode and the item list with download functionality are well-implemented. The use of PrimeVue components follows project patterns.
192-204: Loading state handling is correct.The
loadOrderfunction now properly setsloading.value = trueat the start and handles both success and error cases, addressing the previous review feedback.
216-226: Download function correctly includes security attributes.The
rel="noopener noreferrer"attribute has been added to prevent reverse tabnabbing, addressing the previous security concern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
resources/js/stores/LycheeState.ts (1)
181-187: Critical: Resetis_loadingin error handler to prevent infinite busy-wait loop.The error handler does not set
is_loading = false. IfInitService.fetchInitData()fails,is_loadingremains true indefinitely. Any subsequent call toload()will enter the busy-wait loop at lines 102-104 and never exit, creating an infinite loop.🔎 Proposed fix
.catch((error) => { + this.is_loading = false; // In this specific case, even though it has been possibly disabled, we really need to see the error. this.is_debug_enabled = true; const event = new CustomEvent("error", { detail: error.response.data }); window.dispatchEvent(event); });
🧹 Nitpick comments (3)
resources/js/stores/LycheeState.ts (1)
102-107: Consider caching the loading promise instead of busy-waiting.The current implementation polls every 100ms, which wastes CPU cycles and has no timeout protection. A more efficient and robust pattern is to cache the loading promise and return it directly for concurrent calls.
🔎 Proposed refactor
Add a private property to cache the promise:
export const useLycheeStateStore = defineStore("lychee-store", { state: () => ({ // flag to fetch data is_init: false, is_loading: false, + _loadingPromise: null as Promise<void> | null,Then refactor the load method:
async load(): Promise<void> { // Check if already initialized if (this.is_init) { return Promise.resolve(); } // semaphore to avoid multiple calls if (this.is_loading) { - while (this.is_loading) { - await new Promise((resolve) => setTimeout(resolve, 100)); - } - - return Promise.resolve(); + return this._loadingPromise || Promise.resolve(); } this.is_loading = true; + this._loadingPromise = InitService.fetchInitData() - return InitService.fetchInitData() .then((response) => { this.is_init = true; this.is_loading = false; + this._loadingPromise = null; // ... rest of the code }) .catch((error) => { this.is_loading = false; + this._loadingPromise = null; // ... rest of the error handling }); + return this._loadingPromise; },resources/js/composables/checkout/usePaypal.ts (1)
71-89: Consider improving error logging consistency.The error handling works but has minor inconsistencies:
- Line 82 uses
console.logfor errors (line 86 usesconsole.error)- Line 87 throws a generic message "Could not render PayPal Buttons" that doesn't reflect the createOrder context
🔎 Suggested improvements
async function createOrder(): Promise<string> { try { return await WebshopService.Checkout.processCheckout({ additional_data: {} }) .then((response) => { console.log("Created session for PayPal", response.data); if (!response.data.order?.transaction_id) { throw new Error("No transaction ID received from server"); } return response.data.order.transaction_id; }) .catch((error) => { - console.log("Error creating session for PayPal", error); + console.error("Error creating session for PayPal", error); throw new Error(`Could not create PayPal order: ${error.message}`); }); } catch (error) { console.error(error); - throw new Error("Could not render PayPal Buttons"); + throw error instanceof Error ? error : new Error("Could not create PayPal order"); } }resources/js/composables/checkout/useStepTwo.ts (1)
107-116: Consider adding fallback error handling for non-400 statuses.The function currently only handles 400 (validation) errors. Other errors (5xx, network errors, timeouts) are silently ignored, which could leave users confused when payment fails without feedback.
🔎 Suggested enhancement
function handleError(error: AxiosError) { if (error.response?.status === 400) { toast.add({ severity: "error", summary: trans("webshop.useStepTwo.badRequest"), detail: trans("webshop.useStepTwo.invalidInput"), life: 5000, }); + } else { + // Handle network errors, 5xx, and other failures + toast.add({ + severity: "error", + summary: trans("webshop.useStepTwo.error"), + detail: trans("webshop.useStepTwo.genericError"), + life: 5000, + }); + console.error("Payment processing error:", error); } }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
resources/js/components/webshop/CancelledFailed.vue(1 hunks)resources/js/composables/checkout/usePaypal.ts(1 hunks)resources/js/composables/checkout/useStepTwo.ts(1 hunks)resources/js/stores/LycheeState.ts(1 hunks)resources/js/stores/ShopManagement.ts(1 hunks)resources/js/views/webshop/CheckoutPage.vue(1 hunks)resources/js/views/webshop/OrderDownload.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- resources/js/stores/ShopManagement.ts
- resources/js/views/webshop/OrderDownload.vue
- resources/js/views/webshop/CheckoutPage.vue
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function functionName() {} syntax instead of const function = () => {}
Files:
resources/js/stores/LycheeState.tsresources/js/components/webshop/CancelledFailed.vueresources/js/composables/checkout/usePaypal.tsresources/js/composables/checkout/useStepTwo.ts
**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.vue: Use TypeScript in composition API for Vue3 and use PrimeVue for UI components
Do not use await async calls in Vue3; use .then() instead
In Vue3 components, the order should be: , then <script lang="ts">, then <style>Files:
resources/js/components/webshop/CancelledFailed.vue🧠 Learnings (10)
📓 Common learnings
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/cz/gallery.php:210-210 Timestamp: 2025-08-27T08:48:27.520Z Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.📚 Learning: 2025-09-28T12:43:29.852Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/views/gallery-panels/Album.vue:200-204 Timestamp: 2025-09-28T12:43:29.852Z Learning: The photoStore.load() method in resources/js/stores/PhotoState.ts already handles undefined photoId cases internally with a short circuit exit, so conditional checks before calling photoStore.load() are unnecessary.Applied to files:
resources/js/stores/LycheeState.ts📚 Learning: 2025-09-28T08:39:34.280Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/stores/NsfwConsentedState.ts:3-5 Timestamp: 2025-09-28T08:39:34.280Z Learning: In Lychee codebase, all Pinia store files follow the pattern of declaring the type alias before the store definition (e.g., `export type StoreType = ReturnType<typeof useStore>; export const useStore = defineStore(...)`). This pattern compiles successfully with TypeScript 5.9 and vue-tsc.Applied to files:
resources/js/stores/LycheeState.ts📚 Learning: 2025-11-30T17:19:00.773Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Applied to files:
resources/js/components/webshop/CancelledFailed.vueresources/js/composables/checkout/usePaypal.tsresources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-09-28T08:27:31.767Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:27-31 Timestamp: 2025-09-28T08:27:31.767Z Learning: The maintainer ildyria has indicated that error handling for rotate functions in photoActions.ts should be ignored and not flagged as an issue.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-09-28T08:27:38.332Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:39-43 Timestamp: 2025-09-28T08:27:38.332Z Learning: The user ildyria (repository maintainer) prefers to skip error handling for the rotate photo functions (rotatePhotoCW and rotatePhotoCCW) in resources/js/composables/album/photoActions.ts.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-22T06:11:18.329Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-27T08:48:45.672Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/es/gallery.php:210-210 Timestamp: 2025-08-27T08:48:45.672Z Learning: The project maintainer ildyria has indicated that language localization consistency is not a priority ("Lang = don't care"), meaning English text in non-English language files is acceptable and should not be flagged as an issue.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-16T14:00:53.808Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3504 File: resources/js/composables/selections/selections.ts:145-147 Timestamp: 2025-08-16T14:00:53.808Z Learning: In the Lychee codebase, the maintainer ildyria has indicated that bounds checking for array access in selectables.albums.value[idx] within the albumClick function in resources/js/composables/selections/selections.ts is not necessary, suggesting there are adequate safeguards elsewhere in the code or the access pattern is guaranteed to be safe.Applied to files:
resources/js/composables/checkout/useStepTwo.ts📚 Learning: 2025-08-18T10:19:04.946Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3626 File: database/migrations/2025_06_07_144157_photo_tags_to_table.php:87-105 Timestamp: 2025-08-18T10:19:04.946Z Learning: In the Lychee photo management system, the migration `2025_06_07_144157_photo_tags_to_table.php` runs on data that only contains comma-separated tag names in tag_albums.show_tags - OR/AND expressions do not exist at this migration time, so handling them is unnecessary.Applied to files:
resources/js/composables/checkout/useStepTwo.ts🧬 Code graph analysis (2)
resources/js/composables/checkout/usePaypal.ts (2)
resources/js/lychee.d.ts (1)
CheckoutOptionResource(899-911)app/Actions/Shop/OrderService.php (1)
createOrder(92-102)resources/js/composables/checkout/useStepTwo.ts (6)
resources/js/lychee.d.ts (2)
OmnipayProviderType(106-106)CheckoutResource(912-919)resources/js/stores/OrderManagement.ts (1)
OrderManagementStateStore(5-5)resources/js/composables/checkout/useDummy.ts (1)
useDummy(14-74)resources/js/composables/checkout/useMollie.ts (1)
useMollie(30-99)resources/js/services/webshop-service.ts (1)
CardDetails(37-42)app/Actions/Shop/CheckoutService.php (1)
processPayment(58-154)⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: 2️⃣ JS front-end / Node 20
🔇 Additional comments (3)
resources/js/components/webshop/CancelledFailed.vue (1)
22-28: LGTM!The script setup correctly uses the composition API with TypeScript, properly imports and consumes the OrderManagement store, and maintains reactivity through
storeToRefs.resources/js/composables/checkout/usePaypal.ts (2)
22-69: Good error handling with user-facing toasts.The
mountPaypalfunction properly validates configuration and provides user-friendly error messages via toast notifications. The error handling for SDK loading and button rendering is well-structured.Note: Ensure the
waitForElementtimeout issue (flagged separately) is addressed to prevent this function from hanging if the container doesn't render.
115-124: Good defensive coding with fallback URL.The cancellation handler includes a sensible fallback (
redirect_url ?? "/") to ensure users can navigate away even if the server response is incomplete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
resources/js/composables/checkout/useStepTwo.ts (1)
112-121: Add fallback error handling for non-400 status codes.
handleErroronly handles 400 errors, leaving all other failures (5xx server errors, network timeouts, etc.) without user feedback. This can cause silent failures and poor UX.🔎 Proposed fix
function handleError(error: AxiosError) { if (error.response?.status === 400) { toast.add({ severity: "error", summary: trans("webshop.useStepTwo.badRequest"), detail: trans("webshop.useStepTwo.invalidInput"), life: 5000, }); + } else { + toast.add({ + severity: "error", + summary: trans("webshop.useStepTwo.error"), + detail: trans("webshop.useStepTwo.genericError"), + life: 5000, + }); } }
🧹 Nitpick comments (1)
resources/js/composables/checkout/useStepTwo.ts (1)
54-56: Consider adding user feedback for session creation errors.While logging to console is acceptable for debugging, adding a toast notification for session creation failures would improve user experience and maintain consistency with other error handling in this composable.
🔎 Suggested improvement
.catch((error) => { console.error("Error creating session:", error); + toast.add({ + severity: "error", + summary: trans("webshop.useStepTwo.error"), + detail: trans("webshop.useStepTwo.sessionCreationFailed"), + life: 5000, + }); });
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
resources/js/components/webshop/CancelledFailed.vue(1 hunks)resources/js/composables/checkout/useMollie.ts(1 hunks)resources/js/composables/checkout/usePaypal.ts(1 hunks)resources/js/composables/checkout/useStepTwo.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- resources/js/composables/checkout/usePaypal.ts
- resources/js/components/webshop/CancelledFailed.vue
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function functionName() {} syntax instead of const function = () => {}
Files:
resources/js/composables/checkout/useMollie.tsresources/js/composables/checkout/useStepTwo.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3641
File: lang/no/settings.php:9-9
Timestamp: 2025-08-22T06:11:18.329Z
Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3637
File: lang/nl/renamer.php:10-94
Timestamp: 2025-08-20T20:35:04.474Z
Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3654
File: lang/cz/gallery.php:210-210
Timestamp: 2025-08-27T08:48:27.520Z
Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3837
File: resources/js/composables/checkout/useStepTwo.ts:59-70
Timestamp: 2025-12-20T00:23:54.712Z
Learning: In the Lychee webshop checkout flow (resources/js/composables/checkout/useStepTwo.ts), PayPal uses a button-based integration pattern where the PayPal JS SDK handles the entire payment flow through mounted buttons with createOrder and onApprove handlers. The processPayment() function is only called for providers requiring explicit processing (Mollie, Dummy/Stripe), not for PayPal.
📚 Learning: 2025-12-20T00:23:54.712Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3837
File: resources/js/composables/checkout/useStepTwo.ts:59-70
Timestamp: 2025-12-20T00:23:54.712Z
Learning: In checkout composables under resources/js/composables/checkout, ensure PayPal uses the button-driven integration (PayPal JS SDK renders mounted buttons and handles createOrder/onApprove). Do not call processPayment for PayPal; only call it for explicit processors (Mollie, Dummy/Stripe). This pattern should apply to similar checkout provider implementations across the codebase.
Applied to files:
resources/js/composables/checkout/useMollie.tsresources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-11-30T17:19:00.773Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3837
File: resources/js/composables/checkout/useStepTwo.ts:8-16
Timestamp: 2025-11-30T17:19:00.773Z
Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.
Applied to files:
resources/js/composables/checkout/useMollie.tsresources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-09-28T08:27:31.767Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3721
File: resources/js/composables/album/photoActions.ts:27-31
Timestamp: 2025-09-28T08:27:31.767Z
Learning: The maintainer ildyria has indicated that error handling for rotate functions in photoActions.ts should be ignored and not flagged as an issue.
Applied to files:
resources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-09-28T08:27:38.332Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3721
File: resources/js/composables/album/photoActions.ts:39-43
Timestamp: 2025-09-28T08:27:38.332Z
Learning: The user ildyria (repository maintainer) prefers to skip error handling for the rotate photo functions (rotatePhotoCW and rotatePhotoCCW) in resources/js/composables/album/photoActions.ts.
Applied to files:
resources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-08-22T06:11:18.329Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3641
File: lang/no/settings.php:9-9
Timestamp: 2025-08-22T06:11:18.329Z
Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.
Applied to files:
resources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-08-27T08:48:45.672Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3654
File: lang/es/gallery.php:210-210
Timestamp: 2025-08-27T08:48:45.672Z
Learning: The project maintainer ildyria has indicated that language localization consistency is not a priority ("Lang = don't care"), meaning English text in non-English language files is acceptable and should not be flagged as an issue.
Applied to files:
resources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-08-16T14:00:53.808Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3504
File: resources/js/composables/selections/selections.ts:145-147
Timestamp: 2025-08-16T14:00:53.808Z
Learning: In the Lychee codebase, the maintainer ildyria has indicated that bounds checking for array access in selectables.albums.value[idx] within the albumClick function in resources/js/composables/selections/selections.ts is not necessary, suggesting there are adequate safeguards elsewhere in the code or the access pattern is guaranteed to be safe.
Applied to files:
resources/js/composables/checkout/useStepTwo.ts
📚 Learning: 2025-08-18T10:19:04.946Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3626
File: database/migrations/2025_06_07_144157_photo_tags_to_table.php:87-105
Timestamp: 2025-08-18T10:19:04.946Z
Learning: In the Lychee photo management system, the migration `2025_06_07_144157_photo_tags_to_table.php` runs on data that only contains comma-separated tag names in tag_albums.show_tags - OR/AND expressions do not exist at this migration time, so handling them is unnecessary.
Applied to files:
resources/js/composables/checkout/useStepTwo.ts
🧬 Code graph analysis (1)
resources/js/composables/checkout/useMollie.ts (1)
resources/js/lychee.d.ts (2)
CheckoutOptionResource(899-911)CheckoutResource(912-919)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: 3️⃣ PHP dist / 8.3 - mariadb
- GitHub Check: 3️⃣ PHP dist / 8.4 - sqlite
- GitHub Check: 3️⃣ PHP dist / 8.4 - mariadb
- GitHub Check: 2️⃣ PHP tests / 8.4 - mariadb -- Install
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Unit
- GitHub Check: 2️⃣ PHP tests / 8.4 - sqlite -- Install
- GitHub Check: 2️⃣ PHP tests / 8.4 - postgresql -- Install
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Webshop
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Install
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Unit
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Install
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Unit
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Webshop
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Webshop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
resources/js/stores/LycheeState.ts (2)
101-107: Consider adding a timeout to the busy-wait loop.The polling loop has no maximum iterations or timeout. If
is_loadingnever becomesfalse(e.g., due to an unhandled promise rejection or network timeout that never settles), this will loop indefinitely.Additionally,
return Promise.resolve()is redundant in async functions—you can simply usereturn.🔎 Proposed refactor with timeout protection
// semaphore to avoid multiple calls if (this.is_loading) { + const maxWaitMs = 30000; // 30 second timeout + let waited = 0; while (this.is_loading) { + if (waited >= maxWaitMs) { + throw new Error("Timeout waiting for initialization"); + } await new Promise((resolve) => setTimeout(resolve, 100)); + waited += 100; } - return Promise.resolve(); + return; }
96-98: Simplify redundantPromise.resolve().Since
load()is now async,return Promise.resolve()can be simplified to justreturn.🔎 Proposed fix
if (this.is_init) { - return Promise.resolve(); + return; }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
resources/js/stores/LycheeState.ts(2 hunks)resources/js/views/webshop/OrderDownload.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- resources/js/views/webshop/OrderDownload.vue
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function functionName() {} syntax instead of const function = () => {}
Files:
resources/js/stores/LycheeState.ts
🧠 Learnings (3)
📓 Common learnings
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3641
File: lang/no/settings.php:9-9
Timestamp: 2025-08-22T06:11:18.329Z
Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3637
File: lang/nl/renamer.php:10-94
Timestamp: 2025-08-20T20:35:04.474Z
Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3654
File: lang/cz/gallery.php:210-210
Timestamp: 2025-08-27T08:48:27.520Z
Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3837
File: resources/js/composables/checkout/useStepTwo.ts:59-70
Timestamp: 2025-12-20T00:23:54.712Z
Learning: In the Lychee webshop checkout flow (resources/js/composables/checkout/useStepTwo.ts), PayPal uses a button-based integration pattern where the PayPal JS SDK handles the entire payment flow through mounted buttons with createOrder and onApprove handlers. The processPayment() function is only called for providers requiring explicit processing (Mollie, Dummy/Stripe), not for PayPal.
📚 Learning: 2025-09-28T12:43:29.852Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3721
File: resources/js/views/gallery-panels/Album.vue:200-204
Timestamp: 2025-09-28T12:43:29.852Z
Learning: The photoStore.load() method in resources/js/stores/PhotoState.ts already handles undefined photoId cases internally with a short circuit exit, so conditional checks before calling photoStore.load() are unnecessary.
Applied to files:
resources/js/stores/LycheeState.ts
📚 Learning: 2025-09-28T08:39:34.280Z
Learnt from: ildyria
Repo: LycheeOrg/Lychee PR: 3721
File: resources/js/stores/NsfwConsentedState.ts:3-5
Timestamp: 2025-09-28T08:39:34.280Z
Learning: In Lychee codebase, all Pinia store files follow the pattern of declaring the type alias before the store definition (e.g., `export type StoreType = ReturnType<typeof useStore>; export const useStore = defineStore(...)`). This pattern compiles successfully with TypeScript 5.9 and vue-tsc.
Applied to files:
resources/js/stores/LycheeState.ts
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Install
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Feature_v2
🔇 Additional comments (1)
resources/js/stores/LycheeState.ts (1)
181-188: Good addition ofis_loadingreset in error handler.Resetting
is_loadingin the catch block ensures that concurrent callers waiting in the busy-wait loop will properly exit rather than hanging indefinitely when an error occurs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
resources/js/views/webshop/OrderDownload.vue (1)
206-210: Remove unnecessaryasynckeyword.The
load()function is markedasyncbut doesn't useawaitanywhere—it just returns the promise fromInitService.fetchGlobalRights().then(...)directly. Theasynckeyword adds no value here and can be removed:-async function load(): Promise<void> { +function load(): Promise<void> { return InitService.fetchGlobalRights().then((data) => { initData.value = data.data; }); }This aligns with the project guideline to use
.then()chains rather than async/await in Vue 3 code.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (65)
lang/ar/gallery.phplang/ar/maintenance.phplang/ar/webshop.phplang/cz/gallery.phplang/cz/maintenance.phplang/cz/webshop.phplang/de/gallery.phplang/de/maintenance.phplang/de/webshop.phplang/el/gallery.phplang/el/maintenance.phplang/el/webshop.phplang/en/gallery.phplang/en/maintenance.phplang/en/webshop.phplang/es/gallery.phplang/es/maintenance.phplang/es/webshop.phplang/fa/gallery.phplang/fa/maintenance.phplang/fa/webshop.phplang/fr/gallery.phplang/fr/maintenance.phplang/fr/webshop.phplang/hu/gallery.phplang/hu/maintenance.phplang/hu/webshop.phplang/it/gallery.phplang/it/maintenance.phplang/it/webshop.phplang/ja/gallery.phplang/ja/maintenance.phplang/ja/webshop.phplang/nl/gallery.phplang/nl/maintenance.phplang/nl/webshop.phplang/no/gallery.phplang/no/maintenance.phplang/no/webshop.phplang/pl/gallery.phplang/pl/maintenance.phplang/pl/webshop.phplang/pt/gallery.phplang/pt/maintenance.phplang/pt/webshop.phplang/ru/gallery.phplang/ru/maintenance.phplang/ru/webshop.phplang/sk/gallery.phplang/sk/maintenance.phplang/sk/webshop.phplang/sv/gallery.phplang/sv/maintenance.phplang/sv/webshop.phplang/vi/gallery.phplang/vi/maintenance.phplang/vi/webshop.phplang/zh_CN/gallery.phplang/zh_CN/maintenance.phplang/zh_CN/webshop.phplang/zh_TW/gallery.phplang/zh_TW/maintenance.phplang/zh_TW/webshop.phpresources/js/composables/checkout/useMollie.tsresources/js/views/webshop/OrderDownload.vue
✅ Files skipped from review due to trivial changes (3)
- lang/de/webshop.php
- lang/fa/webshop.php
- lang/en/gallery.php
🧰 Additional context used
📓 Path-based instructions (4)
**/*.php
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.php: Any new PHP file should contain the license header and have a single blank line after the opening PHP tag
Variable names should be in snake_case in PHP
Apply the PSR-4 coding standard in PHP
Use in_array() with true as the third parameter in PHP
Only use booleans in if statements, not integers or strings
Use strict comparison (===) instead of loose comparison (==)
Avoid code duplication in both if and else statements
Do not use empty() in PHP
Use the moneyphp/money library for handling monetary values in PHP
Never use floats or doubles to represent monetary values; use integers representing the smallest currency unit (e.g., cents for USD)
**/*.php: Write or extend executable specifications (unit, behaviour, or scenario tests) ahead of implementation, confirm they fail, and then drive code to green before refactoring. List the expected success, validation, and failure branches and add thin failing tests for each path.
For PHP code, adhere to conventions: license headers in new files, strict comparison (===), no empty(), in_array() with third parameter true, snake_case variables, PSR-4 standard, test base classes (AbstractTestCase for Unit, BaseApiWithDataTest for Feature_v2).
Always run phpunit tests. If a test remains red, disable it with a TODO, note the reason, and capture the follow-up in the relevant plan.
Spotless now uses Palantir Java Format 2.78.0 with a 120-character wrap; configure IDE formatters to match before pushing code changes.
Keep each increment's control flow flat by delegating validation/normalisation into tiny pure helpers that return simple enums or result records, then compose them instead of introducing inline branching that inflates the branch count per change.
When introducing new helpers/utilities or editing files prone to style violations (records, DTOs, generated adapters), run the narrowest applicable lint target (for example phpstan) before the full pipeline. Note the command in the related plan/task.
For PHP changes, ru...
Files:
lang/en/maintenance.phplang/sk/maintenance.phplang/it/gallery.phplang/hu/gallery.phplang/ja/gallery.phplang/sk/gallery.phplang/fr/maintenance.phplang/es/gallery.phplang/no/maintenance.phplang/cz/maintenance.phplang/ru/maintenance.phplang/zh_TW/maintenance.phplang/de/maintenance.phplang/el/webshop.phplang/ar/gallery.phplang/hu/maintenance.phplang/nl/maintenance.phplang/it/maintenance.phplang/zh_CN/webshop.phplang/it/webshop.phplang/no/gallery.phplang/cz/gallery.phplang/en/webshop.phplang/ja/webshop.phplang/es/maintenance.phplang/vi/gallery.phplang/pl/gallery.phplang/ar/maintenance.phplang/sv/maintenance.phplang/zh_CN/maintenance.phplang/ja/maintenance.phplang/pt/maintenance.phplang/zh_CN/gallery.phplang/pl/webshop.phplang/sv/gallery.phplang/hu/webshop.phplang/pl/maintenance.phplang/sv/webshop.phplang/zh_TW/webshop.phplang/pt/gallery.phplang/cz/webshop.phplang/fr/webshop.phplang/ar/webshop.phplang/nl/webshop.phplang/ru/gallery.phplang/fr/gallery.phplang/sk/webshop.phplang/pt/webshop.phplang/ru/webshop.phplang/vi/webshop.phplang/nl/gallery.phplang/el/gallery.phplang/fa/maintenance.phplang/no/webshop.phplang/fa/gallery.phplang/zh_TW/gallery.phplang/de/gallery.phplang/es/webshop.phplang/el/maintenance.phplang/vi/maintenance.php
**/*.{vue,ts,js}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{vue,ts,js}: For Vue3/TypeScript frontend code, follow coding conventions defined in docs/specs/3-reference/coding-conventions.md for style, naming, and testing practices.
For frontend changes, run npm run check to ensure all frontend tests pass before committing.
Files:
resources/js/composables/checkout/useMollie.tsresources/js/views/webshop/OrderDownload.vue
**/*.{vue,ts,js,css}
📄 CodeRabbit inference engine (AGENTS.md)
For frontend changes, run npm run format to apply frontend code formatting with Prettier before committing.
Files:
resources/js/composables/checkout/useMollie.tsresources/js/views/webshop/OrderDownload.vue
**/*.vue
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.vue: Use TypeScript in composition API for Vue3 and use PrimeVue for UI components
Do not use await async calls in Vue3; use .then() instead
Do not use const function = () => {} syntax; use function functionName() {} instead in Vue3
In Vue3 components, the structure should be first, then <script lang="ts">, then <style>Files:
resources/js/views/webshop/OrderDownload.vue🧠 Learnings (10)
📓 Common learnings
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/cz/gallery.php:210-210 Timestamp: 2025-08-27T08:48:27.520Z Learning: For this Lychee project, the maintainer prefers to keep language strings in English across all locale files rather than translating them to local languages.📚 Learning: 2025-12-19T21:01:32.168Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3838 File: lang/pl/webshop.php:1-2 Timestamp: 2025-12-19T21:01:32.168Z Learning: In the Lychee repository, PHP files under the lang/ directory (and its subdirectories) do not require the standard license header. This is an exception to the general PHP license header rule. Ensure all non-lang PHP files continue to include the license header.Applied to files:
lang/en/maintenance.phplang/sk/maintenance.phplang/it/gallery.phplang/hu/gallery.phplang/ja/gallery.phplang/sk/gallery.phplang/fr/maintenance.phplang/es/gallery.phplang/no/maintenance.phplang/cz/maintenance.phplang/ru/maintenance.phplang/zh_TW/maintenance.phplang/de/maintenance.phplang/el/webshop.phplang/ar/gallery.phplang/hu/maintenance.phplang/nl/maintenance.phplang/it/maintenance.phplang/zh_CN/webshop.phplang/it/webshop.phplang/no/gallery.phplang/cz/gallery.phplang/en/webshop.phplang/ja/webshop.phplang/es/maintenance.phplang/vi/gallery.phplang/pl/gallery.phplang/ar/maintenance.phplang/sv/maintenance.phplang/zh_CN/maintenance.phplang/ja/maintenance.phplang/pt/maintenance.phplang/zh_CN/gallery.phplang/pl/webshop.phplang/sv/gallery.phplang/hu/webshop.phplang/pl/maintenance.phplang/sv/webshop.phplang/zh_TW/webshop.phplang/pt/gallery.phplang/cz/webshop.phplang/fr/webshop.phplang/ar/webshop.phplang/nl/webshop.phplang/ru/gallery.phplang/fr/gallery.phplang/sk/webshop.phplang/pt/webshop.phplang/ru/webshop.phplang/vi/webshop.phplang/nl/gallery.phplang/el/gallery.phplang/fa/maintenance.phplang/no/webshop.phplang/fa/gallery.phplang/zh_TW/gallery.phplang/de/gallery.phplang/es/webshop.phplang/el/maintenance.phplang/vi/maintenance.php📚 Learning: 2025-12-19T21:01:45.910Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3838 File: lang/ar/webshop.php:1-2 Timestamp: 2025-12-19T21:01:45.910Z Learning: Do not require license headers for language translation files under the lang/ directory (e.g., lang/ar/webshop.php). These resource files are exempt from header checks; apply header enforcement to other PHP source files in the repo.Applied to files:
lang/en/maintenance.phplang/sk/maintenance.phplang/it/gallery.phplang/hu/gallery.phplang/ja/gallery.phplang/sk/gallery.phplang/fr/maintenance.phplang/es/gallery.phplang/no/maintenance.phplang/cz/maintenance.phplang/ru/maintenance.phplang/zh_TW/maintenance.phplang/de/maintenance.phplang/el/webshop.phplang/ar/gallery.phplang/hu/maintenance.phplang/nl/maintenance.phplang/it/maintenance.phplang/zh_CN/webshop.phplang/it/webshop.phplang/no/gallery.phplang/cz/gallery.phplang/en/webshop.phplang/ja/webshop.phplang/es/maintenance.phplang/vi/gallery.phplang/pl/gallery.phplang/ar/maintenance.phplang/sv/maintenance.phplang/zh_CN/maintenance.phplang/ja/maintenance.phplang/pt/maintenance.phplang/zh_CN/gallery.phplang/pl/webshop.phplang/sv/gallery.phplang/hu/webshop.phplang/pl/maintenance.phplang/sv/webshop.phplang/zh_TW/webshop.phplang/pt/gallery.phplang/cz/webshop.phplang/fr/webshop.phplang/ar/webshop.phplang/nl/webshop.phplang/ru/gallery.phplang/fr/gallery.phplang/sk/webshop.phplang/pt/webshop.phplang/ru/webshop.phplang/vi/webshop.phplang/nl/gallery.phplang/el/gallery.phplang/fa/maintenance.phplang/no/webshop.phplang/fa/gallery.phplang/zh_TW/gallery.phplang/de/gallery.phplang/es/webshop.phplang/el/maintenance.phplang/vi/maintenance.php📚 Learning: 2025-08-22T06:11:18.329Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3641 File: lang/no/settings.php:9-9 Timestamp: 2025-08-22T06:11:18.329Z Learning: For lang/* translation files in the Lychee project: only review PHP-related issues (syntax, structure, etc.), not translation content, grammar, or language-related nitpicks. The maintainer ildyria has explicitly requested this approach.Applied to files:
lang/sk/maintenance.phplang/el/webshop.phplang/it/maintenance.phplang/en/webshop.phplang/pl/webshop.phplang/ru/webshop.phplang/fa/maintenance.phpresources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-20T20:35:04.474Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3637 File: lang/nl/renamer.php:10-94 Timestamp: 2025-08-20T20:35:04.474Z Learning: In Lychee, translation files are initially created with English strings as placeholders, and actual translations are handled through Weblate (a web-based translation management system). This means finding English text in non-English locale files (like lang/nl/, lang/de/, etc.) is expected and part of their translation workflow, not an issue to flag.Applied to files:
lang/el/webshop.phpresources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-27T08:48:32.956Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/pl/gallery.php:210-210 Timestamp: 2025-08-27T08:48:32.956Z Learning: The user ildyria does not prioritize strict localization consistency for new menu items in language files, as indicated by their "Lang = don't care" response when suggested to translate 'Import from Server' to Polish in lang/pl/gallery.php.Applied to files:
lang/cz/gallery.phplang/pl/webshop.phplang/pl/maintenance.phplang/ru/gallery.phpresources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-12-20T00:23:54.712Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:59-70 Timestamp: 2025-12-20T00:23:54.712Z Learning: In checkout composables under resources/js/composables/checkout, ensure PayPal uses the button-driven integration (PayPal JS SDK renders mounted buttons and handles createOrder/onApprove). Do not call processPayment for PayPal; only call it for explicit processors (Mollie, Dummy/Stripe). This pattern should apply to similar checkout provider implementations across the codebase.Applied to files:
resources/js/composables/checkout/useMollie.ts📚 Learning: 2025-11-30T17:19:00.773Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3837 File: resources/js/composables/checkout/useStepTwo.ts:8-16 Timestamp: 2025-11-30T17:19:00.773Z Learning: In the Lychee project's checkout composables (resources/js/composables/checkout/), module-level refs that cause state sharing across component instances are intentional architectural choices, not issues to flag.Applied to files:
resources/js/composables/checkout/useMollie.tsresources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-08-27T08:48:45.672Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3654 File: lang/es/gallery.php:210-210 Timestamp: 2025-08-27T08:48:45.672Z Learning: The project maintainer ildyria has indicated that language localization consistency is not a priority ("Lang = don't care"), meaning English text in non-English language files is acceptable and should not be flagged as an issue.Applied to files:
resources/js/views/webshop/OrderDownload.vue📚 Learning: 2025-09-28T08:27:31.767Z
Learnt from: ildyria Repo: LycheeOrg/Lychee PR: 3721 File: resources/js/composables/album/photoActions.ts:27-31 Timestamp: 2025-09-28T08:27:31.767Z Learning: The maintainer ildyria has indicated that error handling for rotate functions in photoActions.ts should be ignored and not flagged as an issue.Applied to files:
resources/js/views/webshop/OrderDownload.vue⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: 3️⃣ PHP dist / 8.3 - sqlite
- GitHub Check: 3️⃣ PHP dist / 8.3 - postgresql
- GitHub Check: 3️⃣ PHP dist / 8.4 - sqlite
- GitHub Check: 3️⃣ PHP dist / 8.4 - postgresql
- GitHub Check: 3️⃣ PHP dist / 8.3 - mariadb
- GitHub Check: 3️⃣ PHP dist / 8.4 - mariadb
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Webshop
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Unit
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Feature_v2
- GitHub Check: 2️⃣ PHP tests / 8.3 - sqlite -- Unit
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Webshop
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- ImageProcessing
- GitHub Check: 2️⃣ PHP tests / 8.3 - mariadb -- Unit
- GitHub Check: 2️⃣ PHP tests / 8.3 - postgresql -- Webshop
🔇 Additional comments (58)
lang/it/maintenance.php (1)
78-87: LGTM!The PHP syntax and array structure are correct. The new translation entries follow the same pattern as existing entries in the file, with consistent use of HTML tags in descriptions and sprintf-style placeholders.
lang/fa/gallery.php (1)
80-80: LGTM!The addition of the shop tab translation key is correctly structured and follows the expected PHP array syntax. The English placeholder value is consistent with the project's translation workflow.
lang/hu/gallery.php (1)
80-80: LGTM!The new shop tab entry follows the correct PHP syntax and matches the pattern of other tab entries in the array.
lang/ru/webshop.php (1)
1-236: LGTM!The file structure is correct: proper PHP opening tag with a blank line, well-formed nested associative array, and consistent key-value formatting throughout. The structure matches other locale files in the webshop module. Based on learnings, English placeholder strings are expected for the Weblate translation workflow, and no license header is required for
lang/files.lang/pl/gallery.php (1)
80-80: LGTM!The new translation key for the Shop Management tab is correctly structured and properly positioned within the
album.tabsarray. The PHP syntax is valid and follows the existing pattern.lang/fa/maintenance.php (1)
76-85: LGTM!The new translation blocks follow the correct PHP array structure and are consistent with the existing patterns in the file. The English text is expected as placeholders per the project's translation workflow.
lang/cz/gallery.php (1)
80-80: LGTM!The PHP syntax and array structure are correct. The English text in the Czech locale file is expected per the project's translation workflow, where English placeholders are initially used and later translated via Weblate.
lang/de/gallery.php (1)
79-79: LGTM!The new translation key for the Shop Management tab is correctly structured and properly placed within the
album.tabsarray. PHP syntax is valid.lang/ar/gallery.php (1)
80-80: LGTM!The new 'shop' translation key is properly structured and follows the correct PHP array syntax. The placement within the tabs array is appropriate and consistent with the file's formatting.
lang/vi/gallery.php (1)
80-80: LGTM! Translation key addition is properly structured.The new
shoptranslation key is correctly added to thealbum.tabsarray with proper PHP syntax and formatting. The English placeholder text is expected per the project's translation workflow.lang/sv/webshop.php (1)
1-236: LGTM! PHP structure and syntax are correct.The file follows proper PHP syntax with correct array structure. The English strings are expected placeholders per the project's translation workflow using Weblate.
lang/fr/maintenance.php (1)
77-86: LGTM!The PHP syntax and structure are correct. The new translation blocks follow the existing pattern in the file, with proper array nesting, consistent key structure, and appropriate trailing commas.
lang/cz/maintenance.php (1)
77-86: LGTM!The new translation blocks for order maintenance are properly structured and follow the existing patterns in the file. The PHP syntax is correct, and the array structure is consistent with other entries.
lang/zh_TW/webshop.php (1)
1-236: LGTM! Translation file structure is correct.The PHP syntax and structure are valid. Per project conventions, language files under
lang/do not require license headers, and English placeholder strings are expected in locale files (translations are managed via Weblate). Based on learnings, no language-specific content review is needed.lang/no/webshop.php (1)
1-236: LGTM! Translation file structure is correct.The PHP syntax and structure are valid. The file correctly follows the project's conventions for translation files: proper opening tag with blank line, well-formed nested associative array, and correct exemption from license header requirement for lang/ directory files.
Note: The English strings are expected per the project's translation workflow (Weblate handles actual translations).
lang/zh_CN/webshop.php (1)
1-236: LGTM! PHP structure is correct.The translation file follows proper PHP syntax with a correctly formatted associative array structure. The file appropriately omits the license header per the lang/ directory exemption.
lang/nl/webshop.php (1)
1-236: LGTM! File structure is correct.The file follows the proper PHP structure with the opening tag, a single blank line, and a well-formed return statement. The syntax is valid, and the nested array structure is properly formatted. English strings in this Dutch locale file are expected as part of the Weblate translation workflow.
lang/vi/webshop.php (1)
1-236: LGTM! File structure is correct.The translation file follows the proper PHP structure with a blank line after the opening tag, correct array syntax throughout, and no PHP-related issues. The file correctly omits the license header as it's under the
lang/directory. The English content is expected per the project's translation workflow managed through Weblate.lang/pl/maintenance.php (1)
78-87: LGTM!The new maintenance keys for order management follow the correct PHP array structure and syntax. The English placeholder text is consistent with the project's translation workflow, where strings are initially added in English and later translated via Weblate.
Based on learnings, translation files in this repository are expected to contain English placeholders initially.
lang/ja/webshop.php (1)
1-236: LGTM! Translation file structure is correct.The file follows the correct structure for a Laravel translation file with proper PHP syntax, valid array structure, and correct opening tag format. No license header is required for lang/ files, and English placeholder strings in non-English locale files are expected per the project's Weblate translation workflow.
lang/pt/webshop.php (1)
1-236: LGTM!The PHP structure and syntax are correct. The file properly returns a well-organized translation array with no syntax errors, proper quote handling, and correct placeholder usage for sprintf formatting.
lang/hu/webshop.php (1)
1-236: LGTM!The file structure is correct, with proper PHP syntax and a well-formatted associative array. The presence of English strings in this Hungarian locale file is expected, as translations are managed through Weblate per the project's workflow.
lang/no/gallery.php (1)
80-80: LGTM!The new shop tab entry is properly structured and follows the existing format. The English text is expected as a placeholder per the project's translation workflow.
lang/ru/gallery.php (1)
79-79: LGTM!The new shop tab entry is properly structured and consistent with the existing translation array format.
lang/zh_CN/gallery.php (1)
80-80: LGTM!The new shop tab entry is correctly formatted and follows the established pattern in the file.
lang/vi/maintenance.php (1)
78-87: LGTM!The two new maintenance blocks are properly structured with correct PHP syntax. The use of HTML tags and sprintf placeholders is consistent with existing patterns in the file.
lang/pt/gallery.php (1)
80-80: LGTM!The new shop tab entry is properly formatted and consistent with the existing translation structure.
lang/es/gallery.php (1)
80-80: LGTM!The new shop tab entry is correctly structured and follows the established format.
lang/it/gallery.php (1)
80-80: LGTM!The new shop tab entry is properly formatted and consistent with the existing array structure.
lang/sk/gallery.php (1)
80-80: LGTM!The new shop tab entry is correctly formatted and follows the established pattern in the translation file.
lang/zh_TW/gallery.php (1)
80-80: LGTM!The Shop Management tab translation entry is correctly structured and integrates properly into the existing array.
lang/en/maintenance.php (1)
76-85: LGTM!The two new maintenance blocks (old-orders and fulfill-orders) follow the established pattern and structure of existing maintenance entries in the file.
lang/ja/gallery.php (1)
80-80: LGTM!The Shop Management tab entry is properly added to the album tabs array with correct PHP syntax.
lang/fr/gallery.php (1)
80-80: LGTM!The shop tab entry is correctly structured and consistent with the pattern used across all locale files in this PR.
lang/el/gallery.php (1)
80-80: LGTM!The Shop Management tab translation is correctly added with proper PHP array syntax.
lang/es/maintenance.php (1)
76-85: LGTM!The two new maintenance blocks are correctly structured and follow the same pattern as the English version, consistent with the project's translation workflow.
lang/sv/gallery.php (1)
80-80: LGTM!The shop tab entry is properly integrated into the album tabs array with correct syntax.
lang/nl/gallery.php (1)
80-80: LGTM!The Shop Management tab entry is correctly added to the album tabs array, completing the consistent localization structure across all locale files.
lang/hu/maintenance.php (1)
78-87: LGTM! Translation entries follow the correct structure.The new maintenance translation entries are properly structured, use correct PHP array syntax, and follow the same pattern as existing maintenance blocks in the file.
lang/nl/maintenance.php (1)
76-85: LGTM! Translation structure is correct.The new maintenance entries follow the correct PHP array structure and are consistent with the existing maintenance blocks. English placeholders are expected per the project's Weblate workflow.
lang/sk/maintenance.php (1)
78-87: LGTM! Properly structured translation entries.The added maintenance translation entries use correct PHP syntax and follow the established pattern for maintenance blocks in this file.
lang/no/maintenance.php (1)
76-85: LGTM! Translation entries are correctly structured.The new maintenance entries follow proper PHP array syntax and are consistent with the structure of existing maintenance blocks.
lang/ru/maintenance.php (1)
76-85: LGTM! Maintenance entries follow the correct structure.The added translation entries use proper PHP array syntax and maintain consistency with the existing maintenance block structure in the file.
lang/sv/maintenance.php (1)
78-87: LGTM! Correctly structured translation additions.The new maintenance translation entries follow proper PHP syntax and are consistent with the existing pattern used for maintenance blocks in this file.
lang/el/maintenance.php (1)
78-87: LGTM! Translation structure is correct.The added maintenance entries use proper PHP array syntax and follow the established structure for maintenance blocks in the file.
lang/zh_TW/maintenance.php (1)
78-87: LGTM! Properly structured maintenance entries.The new translation entries follow correct PHP array syntax and maintain consistency with the existing maintenance block structure in the file.
lang/ar/maintenance.php (1)
76-85: LGTM!The new translation blocks for
old-ordersandfulfill-ordersare properly structured with consistent array syntax. English strings in the Arabic locale file are expected as placeholders for the Weblate translation workflow.Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/cz/webshop.php (1)
1-236: LGTM!The new Czech webshop translation file is properly structured with valid PHP syntax. The nested associative array follows consistent patterns, and the English placeholder strings are expected as part of the Weblate translation workflow.
Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/el/webshop.php (1)
1-236: LGTM!The new Greek webshop translation file has proper PHP syntax and consistent array structure. English placeholder strings are expected as part of the Weblate translation workflow.
Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/de/maintenance.php (1)
76-85: LGTM!The new translation blocks for
old-ordersandfulfill-ordersare properly structured with consistent array syntax. English strings in the German locale file are expected as placeholders for the Weblate translation workflow.Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/pt/maintenance.php (1)
78-87: LGTM!The new translation blocks for
old-ordersandfulfill-ordersare properly structured with consistent array syntax. English strings in the Portuguese locale file are expected as placeholders for the Weblate translation workflow.Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/pl/webshop.php (1)
1-236: LGTM!The new Polish webshop translation file has proper PHP syntax and consistent array structure. English placeholder strings are expected as part of the Weblate translation workflow.
Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/sk/webshop.php (1)
1-236: LGTM!The new Slovak webshop translation file has proper PHP syntax and consistent array structure. English placeholder strings are expected as part of the Weblate translation workflow.
Based on learnings, only PHP syntax and structure are reviewed for translation files.
lang/es/webshop.php (1)
1-236: LGTM!The new Spanish webshop translation file has proper PHP syntax and consistent array structure. English placeholder strings are expected as part of the Weblate translation workflow.
Based on learnings, only PHP syntax and structure are reviewed for translation files.
resources/js/views/webshop/OrderDownload.vue (4)
1-152: Template structure and component usage look good.The template follows Vue 3 and PrimeVue conventions correctly:
- Proper conditional rendering for loading/undefined/loaded states
- Correct use of PrimeVue components (Toolbar, Panel, ProgressSpinner, Button, InputText)
- Translation keys used throughout with
$t()andsprintf- RouterLink navigation and permission-based conditional rendering implemented correctly
153-186: Imports and reactive state setup are correct.All imports are properly structured, props are correctly typed with TypeScript generics, and reactive state uses appropriate
ref()andstoreToRefs()patterns for Vue 3 composition API.
188-204: Helper functions are well-structured and handle errors correctly.All functions use the correct
functionsyntax (not arrow functions), past issues have been addressed:
downloadItem()includesrel="noopener noreferrer"for securitycopyToClipboard()has feature detection and error handling with.catch()loadOrder()properly setsloading.value = trueat the startupdateItemLink()correctly handles add/update/remove logic for the items arrayAlso applies to: 212-226, 228-260, 262-279
281-303:markAsDelivered()and lifecycle hooks are correctly implemented.The function properly handles both success and error cases:
- Success path clears
itemsToUpdateand reloads the order- Error path logs to console and displays a user-facing error toast
onMounted()correctly triggers data loadingPast review comments have been addressed.
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.