feat(referrals): add referral attribution and daily login rewards
- Track referral attribution at registration via ?ref code with same-IP and duplicate-pair guards - Add daily login rewards with streak tracking, claim flow and sendCurrency payout backed by RCON with DB fallback - Add admin pages for referral settings and the daily reward schedule - Add migration 0033 with tables, seed schedule, settings and ACL grants - Add admin.referrals.* and admin.dailyrewards.* permission slugs - Localize new copy in en, nl and it
This commit is contained in:
1 parent
463bc2cb47
commit
c3ff497050
30 files changed
+2028
-11
No files matched your search
+83
-1
@@ -1050,7 +1050,8 @@
|
||||
"usernameRequired": "Username is required.",
|
||||
"emailRequired": "Email is required.",
|
||||
"passwordRequired": "Password is required.",
|
||||
"passwordsDontMatch": "Passwords do not match."
|
||||
"passwordsDontMatch": "Passwords do not match.",
|
||||
"invitedBy": "Invited by {username}"
|
||||
},
|
||||
"forgot": {
|
||||
"title": "Reset password",
|
||||
@@ -1143,6 +1144,8 @@
|
||||
"transactions": "Transactions",
|
||||
"vouchers": "Vouchers",
|
||||
"subscriptions": "Subscriptions",
|
||||
"referrals": "Referrals",
|
||||
"dailyRewards": "Daily rewards",
|
||||
"rareValues": "Rare values",
|
||||
"badges": "Badges",
|
||||
"achievements": "Achievements",
|
||||
@@ -3197,6 +3200,64 @@
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
},
|
||||
"referrals": {
|
||||
"title": "Referrals",
|
||||
"subtitle": "Invitation system",
|
||||
"referralsToday": "Referrals today",
|
||||
"referralsTotal": "Total referrals",
|
||||
"invitedTotal": "Invitations counted",
|
||||
"claims": "Rewards claimed",
|
||||
"settings": "Reward settings",
|
||||
"needed": "Referrals needed",
|
||||
"rewardAmount": "Reward amount",
|
||||
"rewardCurrency": "Reward currency",
|
||||
"blockSameIp": "Reject referrals sharing the inviter's current IP",
|
||||
"save": "Save settings",
|
||||
"saving": "Saving…",
|
||||
"saved": "Referral settings saved.",
|
||||
"saveError": "Referral settings could not be saved.",
|
||||
"recent": "Recent referrals",
|
||||
"unavailable": "Referral data is temporarily unavailable.",
|
||||
"empty": "No referrals yet.",
|
||||
"inviter": "Inviter",
|
||||
"invitee": "Invited user",
|
||||
"ip": "IP",
|
||||
"date": "Date"
|
||||
},
|
||||
"dailyRewards": {
|
||||
"title": "Daily login rewards",
|
||||
"subtitle": "Daily login reward schedule",
|
||||
"enabled": "Feature status",
|
||||
"yes": "Enabled",
|
||||
"no": "Disabled",
|
||||
"scheduleDays": "Schedule days",
|
||||
"claimsToday": "Claims today",
|
||||
"claimsTotal": "Total claims",
|
||||
"status": "Feature status",
|
||||
"statusHint": "When disabled, the reward card is hidden and new claims are rejected.",
|
||||
"disable": "Disable",
|
||||
"enable": "Enable",
|
||||
"schedule": "Reward schedule",
|
||||
"day": "Day {day}",
|
||||
"reward": "Reward",
|
||||
"amount": "Amount",
|
||||
"actions": "Actions",
|
||||
"addDay": "Day",
|
||||
"add": "Add day",
|
||||
"save": "Save",
|
||||
"saving": "Saving…",
|
||||
"saved": "Reward schedule saved.",
|
||||
"cancel": "Cancel",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete",
|
||||
"created": "Reward day added.",
|
||||
"updated": "Reward day updated.",
|
||||
"deleted": "Reward day removed.",
|
||||
"saveError": "Reward day could not be saved.",
|
||||
"deleteError": "Reward day could not be removed.",
|
||||
"confirmDeleteTitle": "Remove reward day",
|
||||
"confirmDeleteBody": "This reward day will no longer be granted. Past claims stay recorded."
|
||||
},
|
||||
"subscriptions": {
|
||||
"title": "Subscriptions",
|
||||
"subtitle": "Active recurring subscriptions",
|
||||
@@ -4056,6 +4117,8 @@
|
||||
"vouchers": "Vouchers",
|
||||
"subscriptions": "Subscriptions",
|
||||
"calendar": "Calendar",
|
||||
"referrals": "Referrals",
|
||||
"dailyRewards": "Daily rewards",
|
||||
"history": "History",
|
||||
"moderationTab": "Moderation",
|
||||
"monitoring": "Monitoring",
|
||||
@@ -6277,6 +6340,7 @@
|
||||
"login": "Sign in",
|
||||
"never": "Never",
|
||||
"claimed": "Reward claimed successfully!",
|
||||
"dailyClaimed": "Daily reward claimed — see you tomorrow!",
|
||||
"welcome": "Your space on {hotel}",
|
||||
"noMotto": "No motto yet",
|
||||
"registered": "Registered: {date}",
|
||||
@@ -6329,6 +6393,23 @@
|
||||
"ratelimit": "Too many attempts. Wait a moment and try again.",
|
||||
"error": "The reward could not be claimed. Please try again."
|
||||
},
|
||||
"dailyErrors": {
|
||||
"already_claimed": "You already claimed today's daily reward.",
|
||||
"disabled": "Daily rewards are currently disabled.",
|
||||
"bad_config": "The daily reward schedule is not configured correctly. Contact the staff.",
|
||||
"ratelimit": "Too many attempts. Wait a moment and try again.",
|
||||
"error": "The daily reward could not be claimed. Please try again."
|
||||
},
|
||||
"dailyRewardTitle": "Daily rewards",
|
||||
"dailyRewardHint": "Log in every day and claim your reward — streaks grow until the big days.",
|
||||
"dailyRewardDay": "Day {day}",
|
||||
"dailyRewardStreak": "{count, plural, one {Streak: # day} other {Streak: # days}}",
|
||||
"dailyRewardNextClaim": "Next claim: {amount} {currency}",
|
||||
"dailyRewardTomorrow": "Tomorrow: {amount} {currency}",
|
||||
"dailyRewardClaim": "Claim daily reward",
|
||||
"dailyRewardClaimedToday": "Claimed today — come back tomorrow for the next reward.",
|
||||
"dailyRewardDisabled": "Daily rewards are currently disabled. You can still explore the hotel.",
|
||||
"dailyRewardUnavailable": "The daily reward schedule could not be loaded. Please try again.",
|
||||
"messagesCaughtUp": "No unread messages",
|
||||
"messagesUnavailable": "Open your inbox to check",
|
||||
"eventTitle": "On the calendar",
|
||||
@@ -6345,6 +6426,7 @@
|
||||
"friends": "{count, plural, one {# friend request to review} other {# friend requests to review}}",
|
||||
"event": "Your next registered event: {title} · {date}",
|
||||
"reward": "Your referral reward is ready to claim",
|
||||
"dailyReward": "Your daily reward is ready to claim",
|
||||
"empty": "You're all caught up. No actions waiting.",
|
||||
"unavailable": "Some actions could not be checked. Available actions are shown above.",
|
||||
"retry": "Try again",
|
||||
|
||||
Reference in new issue
Block a user