feat(loyalty): make logo URL mandatory on program edit forms
Some checks failed
CI / ruff (push) Successful in 10s
CI / pytest (push) Failing after 49m23s
CI / validate (push) Successful in 26s
CI / dependency-scanning (push) Successful in 30s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped

Logo URL is required by Google Wallet API for LoyaltyClass creation.
Added validation across all three program edit screens (admin, merchant, store)
with a helpful hint explaining the requirement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 20:08:38 +01:00
parent 8c8975239a
commit 29d942322d
6 changed files with 11 additions and 3 deletions

View File

@@ -224,6 +224,7 @@ R2_BACKUP_BUCKET=orion-backups
# Get Issuer ID from https://pay.google.com/business/console # Get Issuer ID from https://pay.google.com/business/console
# LOYALTY_GOOGLE_ISSUER_ID=3388000000012345678 # LOYALTY_GOOGLE_ISSUER_ID=3388000000012345678
# LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON=/path/to/service-account.json # LOYALTY_GOOGLE_SERVICE_ACCOUNT_JSON=/path/to/service-account.json
# LOYALTY_DEFAULT_LOGO_URL=https://yourdomain.com/path/to/default-logo.png
# Apple Wallet integration (requires Apple Developer account) # Apple Wallet integration (requires Apple Developer account)
# LOYALTY_APPLE_PASS_TYPE_ID=pass.com.example.loyalty # LOYALTY_APPLE_PASS_TYPE_ID=pass.com.example.loyalty

View File

@@ -100,6 +100,7 @@ function adminLoyaltyProgramEdit() {
try { try {
const payload = this.buildPayload(); const payload = this.buildPayload();
if (!payload) { this.saving = false; return; }
if (this.isNewProgram) { if (this.isNewProgram) {
const response = await apiClient.post( const response = await apiClient.post(

View File

@@ -52,6 +52,7 @@ function merchantLoyaltySettings() {
try { try {
const payload = this.buildPayload(); const payload = this.buildPayload();
if (!payload) { this.saving = false; return; }
if (this.isNewProgram) { if (this.isNewProgram) {
await apiClient.post('/merchants/loyalty/program', payload); await apiClient.post('/merchants/loyalty/program', payload);

View File

@@ -98,7 +98,10 @@ function createProgramFormMixin() {
if (!payload.minimum_purchase_cents) payload.minimum_purchase_cents = null; if (!payload.minimum_purchase_cents) payload.minimum_purchase_cents = null;
if (!payload.card_name) payload.card_name = null; if (!payload.card_name) payload.card_name = null;
if (!payload.card_secondary_color) payload.card_secondary_color = null; if (!payload.card_secondary_color) payload.card_secondary_color = null;
if (!payload.logo_url) payload.logo_url = null; if (!payload.logo_url) {
this.error = 'Logo URL is required for wallet integration.';
return null;
}
if (!payload.hero_image_url) payload.hero_image_url = null; if (!payload.hero_image_url) payload.hero_image_url = null;
if (!payload.terms_text) payload.terms_text = null; if (!payload.terms_text) payload.terms_text = null;
if (!payload.privacy_url) payload.privacy_url = null; if (!payload.privacy_url) payload.privacy_url = null;

View File

@@ -82,6 +82,7 @@ function loyaltySettings() {
try { try {
const payload = this.buildPayload(); const payload = this.buildPayload();
if (!payload) { this.saving = false; return; }
let response; let response;
if (this.isNewProgram) { if (this.isNewProgram) {

View File

@@ -226,9 +226,10 @@
</div> </div>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Logo URL</label> <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Logo URL <span class="text-red-500">*</span></label>
<input type="url" x-model="settings.logo_url" maxlength="500" placeholder="https://..." <input type="url" x-model="settings.logo_url" maxlength="500" placeholder="https://..." required
class="w-full px-4 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:border-purple-400 focus:outline-none dark:bg-gray-700 dark:text-gray-300"> class="w-full px-4 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg focus:border-purple-400 focus:outline-none dark:bg-gray-700 dark:text-gray-300">
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Required for Google Wallet integration. Must be a publicly accessible image URL (PNG or JPG).</p>
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Hero Image URL</label> <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Hero Image URL</label>