mirror of
https://github.com/ManInDark/HabitTrove.git
synced 2026-01-21 06:34:30 +01:00
max coin limit (#140)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## Version 0.2.13
|
## Version 0.2.15
|
||||||
|
|
||||||
|
### Improved
|
||||||
|
|
||||||
|
* max coins set to 9999, to prevent js large number precision issue (#137)
|
||||||
|
|
||||||
|
## Version 0.2.14
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import data from '@emoji-mart/data'
|
|||||||
import Picker from '@emoji-mart/react'
|
import Picker from '@emoji-mart/react'
|
||||||
import { Habit, SafeUser } from '@/lib/types'
|
import { Habit, SafeUser } from '@/lib/types'
|
||||||
import { convertHumanReadableFrequencyToMachineReadable, convertMachineReadableFrequencyToHumanReadable, d2s, d2t, serializeRRule } from '@/lib/utils'
|
import { convertHumanReadableFrequencyToMachineReadable, convertMachineReadableFrequencyToHumanReadable, d2s, d2t, serializeRRule } from '@/lib/utils'
|
||||||
import { INITIAL_DUE, INITIAL_RECURRENCE_RULE, QUICK_DATES, RECURRENCE_RULE_MAP } from '@/lib/constants'
|
import { INITIAL_DUE, INITIAL_RECURRENCE_RULE, QUICK_DATES, RECURRENCE_RULE_MAP, MAX_COIN_LIMIT } from '@/lib/constants'
|
||||||
import * as chrono from 'chrono-node';
|
import * as chrono from 'chrono-node';
|
||||||
import { DateTime } from 'luxon'
|
import { DateTime } from 'luxon'
|
||||||
import {
|
import {
|
||||||
@@ -291,14 +291,18 @@ export default function AddEditHabitModal({ onClose, onSave, habit, isTask }: Ad
|
|||||||
id="coinReward"
|
id="coinReward"
|
||||||
type="number"
|
type="number"
|
||||||
value={coinReward}
|
value={coinReward}
|
||||||
onChange={(e) => setCoinReward(parseInt(e.target.value === "" ? "0" : e.target.value))}
|
onChange={(e) => {
|
||||||
|
const value = parseInt(e.target.value === "" ? "0" : e.target.value)
|
||||||
|
setCoinReward(Math.min(value, MAX_COIN_LIMIT))
|
||||||
|
}}
|
||||||
min={0}
|
min={0}
|
||||||
|
max={MAX_COIN_LIMIT}
|
||||||
required
|
required
|
||||||
className="w-20 text-center border-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
className="w-20 text-center border-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setCoinReward(prev => prev + 1)}
|
onClick={() => setCoinReward(prev => Math.min(prev + 1, MAX_COIN_LIMIT))}
|
||||||
className="px-3 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 transition-colors"
|
className="px-3 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 transition-colors"
|
||||||
>
|
>
|
||||||
+
|
+
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { SmilePlus, Info } from 'lucide-react'
|
|||||||
import data from '@emoji-mart/data'
|
import data from '@emoji-mart/data'
|
||||||
import Picker from '@emoji-mart/react'
|
import Picker from '@emoji-mart/react'
|
||||||
import { WishlistItemType } from '@/lib/types'
|
import { WishlistItemType } from '@/lib/types'
|
||||||
|
import { MAX_COIN_LIMIT } from '@/lib/constants'
|
||||||
|
|
||||||
interface AddEditWishlistItemModalProps {
|
interface AddEditWishlistItemModalProps {
|
||||||
isOpen: boolean
|
isOpen: boolean
|
||||||
@@ -68,6 +69,8 @@ export default function AddEditWishlistItemModal({
|
|||||||
}
|
}
|
||||||
if (coinCost < 1) {
|
if (coinCost < 1) {
|
||||||
newErrors.coinCost = t('errorCoinCostMin')
|
newErrors.coinCost = t('errorCoinCostMin')
|
||||||
|
} else if (coinCost > MAX_COIN_LIMIT) {
|
||||||
|
newErrors.coinCost = t('errorCoinCostMax', { max: MAX_COIN_LIMIT })
|
||||||
}
|
}
|
||||||
if (targetCompletions !== undefined && targetCompletions < 1) {
|
if (targetCompletions !== undefined && targetCompletions < 1) {
|
||||||
newErrors.targetCompletions = t('errorTargetCompletionsMin')
|
newErrors.targetCompletions = t('errorTargetCompletionsMin')
|
||||||
@@ -192,14 +195,18 @@ export default function AddEditWishlistItemModal({
|
|||||||
id="coinReward"
|
id="coinReward"
|
||||||
type="number"
|
type="number"
|
||||||
value={coinCost}
|
value={coinCost}
|
||||||
onChange={(e) => setCoinCost(parseInt(e.target.value === "" ? "0" : e.target.value))}
|
onChange={(e) => {
|
||||||
|
const value = parseInt(e.target.value === "" ? "0" : e.target.value)
|
||||||
|
setCoinCost(Math.min(value, MAX_COIN_LIMIT))
|
||||||
|
}}
|
||||||
min={0}
|
min={0}
|
||||||
|
max={MAX_COIN_LIMIT}
|
||||||
required
|
required
|
||||||
className="w-20 text-center border-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
className="w-20 text-center border-0 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setCoinCost(prev => prev + 1)}
|
onClick={() => setCoinCost(prev => Math.min(prev + 1, MAX_COIN_LIMIT))}
|
||||||
className="px-3 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 transition-colors"
|
className="px-3 py-2 bg-gray-100 hover:bg-gray-200 dark:bg-gray-800 dark:hover:bg-gray-700 transition-colors"
|
||||||
>
|
>
|
||||||
+
|
+
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import Link from 'next/link'
|
|||||||
import { useAtom } from 'jotai'
|
import { useAtom } from 'jotai'
|
||||||
import { useTranslations } from 'next-intl'
|
import { useTranslations } from 'next-intl'
|
||||||
import { useCoins } from '@/hooks/useCoins'
|
import { useCoins } from '@/hooks/useCoins'
|
||||||
|
import { MAX_COIN_LIMIT } from '@/lib/constants'
|
||||||
import { TransactionNoteEditor } from './TransactionNoteEditor'
|
import { TransactionNoteEditor } from './TransactionNoteEditor'
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
import { TransactionType } from '@/lib/types'
|
import { TransactionType } from '@/lib/types'
|
||||||
@@ -138,7 +139,11 @@ export default function CoinsManager() {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
className="h-10 w-10 text-lg"
|
className="h-10 w-10 text-lg"
|
||||||
onClick={() => setAmount(prev => (Number(prev) - 1).toString())}
|
onClick={() => setAmount(prev => {
|
||||||
|
const current = Number(prev);
|
||||||
|
const next = current - 1;
|
||||||
|
return (Math.abs(next) > MAX_COIN_LIMIT ? (next < 0 ? -MAX_COIN_LIMIT : MAX_COIN_LIMIT) : next).toString();
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
-
|
-
|
||||||
</Button>
|
</Button>
|
||||||
@@ -146,7 +151,22 @@ export default function CoinsManager() {
|
|||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
value={amount}
|
value={amount}
|
||||||
onChange={(e) => setAmount(e.target.value)}
|
onChange={(e) => {
|
||||||
|
const rawValue = e.target.value;
|
||||||
|
if (rawValue === '' || rawValue === '-') {
|
||||||
|
setAmount(rawValue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let numericValue = Number(rawValue); // Changed const to let
|
||||||
|
if (isNaN(numericValue)) return; // Or handle error
|
||||||
|
|
||||||
|
if (Math.abs(numericValue) > MAX_COIN_LIMIT) {
|
||||||
|
numericValue = numericValue < 0 ? -MAX_COIN_LIMIT : MAX_COIN_LIMIT;
|
||||||
|
}
|
||||||
|
setAmount(numericValue.toString());
|
||||||
|
}}
|
||||||
|
min={-MAX_COIN_LIMIT}
|
||||||
|
max={MAX_COIN_LIMIT}
|
||||||
className="text-center text-xl font-medium h-12"
|
className="text-center text-xl font-medium h-12"
|
||||||
/>
|
/>
|
||||||
<div className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground">
|
<div className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground">
|
||||||
@@ -157,7 +177,11 @@ export default function CoinsManager() {
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="icon"
|
size="icon"
|
||||||
className="h-10 w-10 text-lg"
|
className="h-10 w-10 text-lg"
|
||||||
onClick={() => setAmount(prev => (Number(prev) + 1).toString())}
|
onClick={() => setAmount(prev => {
|
||||||
|
const current = Number(prev);
|
||||||
|
const next = current + 1;
|
||||||
|
return (Math.abs(next) > MAX_COIN_LIMIT ? (next < 0 ? -MAX_COIN_LIMIT : MAX_COIN_LIMIT) : next).toString();
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
+
|
+
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { addCoins, removeCoins, saveCoinsData } from '@/app/actions/data'
|
|||||||
import { CoinsData, User } from '@/lib/types'
|
import { CoinsData, User } from '@/lib/types'
|
||||||
import { toast } from '@/hooks/use-toast'
|
import { toast } from '@/hooks/use-toast'
|
||||||
import { useHelpers } from '@/lib/client-helpers'
|
import { useHelpers } from '@/lib/client-helpers'
|
||||||
|
import { MAX_COIN_LIMIT } from '@/lib/constants'
|
||||||
|
|
||||||
function handlePermissionCheck(
|
function handlePermissionCheck(
|
||||||
user: User | undefined,
|
user: User | undefined,
|
||||||
@@ -77,6 +78,13 @@ export function useCoins(options?: { selectedUser?: string }) {
|
|||||||
})
|
})
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
if (amount > MAX_COIN_LIMIT) {
|
||||||
|
toast({
|
||||||
|
title: t("invalidAmountTitle"),
|
||||||
|
description: t("maxAmountExceededDescription", { max: MAX_COIN_LIMIT })
|
||||||
|
})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const data = await addCoins({
|
const data = await addCoins({
|
||||||
amount,
|
amount,
|
||||||
@@ -100,6 +108,13 @@ export function useCoins(options?: { selectedUser?: string }) {
|
|||||||
})
|
})
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
if (numAmount > MAX_COIN_LIMIT) {
|
||||||
|
toast({
|
||||||
|
title: t("invalidAmountTitle"),
|
||||||
|
description: t("maxAmountExceededDescription", { max: MAX_COIN_LIMIT })
|
||||||
|
})
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const data = await removeCoins({
|
const data = await removeCoins({
|
||||||
amount: numAmount,
|
amount: numAmount,
|
||||||
|
|||||||
@@ -30,3 +30,5 @@ export const QUICK_DATES = [
|
|||||||
{ label: 'Saturday', value: 'this saturday' },
|
{ label: 'Saturday', value: 'this saturday' },
|
||||||
{ label: 'Sunday', value: 'this sunday' },
|
{ label: 'Sunday', value: 'this sunday' },
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
|
export const MAX_COIN_LIMIT = 9999
|
||||||
@@ -406,16 +406,17 @@
|
|||||||
"notEnoughCoinsTitle": "Nicht genug Münzen",
|
"notEnoughCoinsTitle": "Nicht genug Münzen",
|
||||||
"notEnoughCoinsDescription": "Sie benötigen {coinsNeeded} Münzen mehr, um diese Belohnung einzulösen."
|
"notEnoughCoinsDescription": "Sie benötigen {coinsNeeded} Münzen mehr, um diese Belohnung einzulösen."
|
||||||
},
|
},
|
||||||
|
"Warning": {
|
||||||
|
"areYouSure": "Sind Sie sicher?",
|
||||||
|
"cancel": "Abbrechen"
|
||||||
|
},
|
||||||
"useCoins": {
|
"useCoins": {
|
||||||
"invalidAmountTitle": "Ungültiger Betrag",
|
"invalidAmountTitle": "Ungültiger Betrag",
|
||||||
"invalidAmountDescription": "Bitte geben Sie eine gültige positive Zahl ein",
|
"invalidAmountDescription": "Bitte geben Sie eine gültige positive Zahl ein",
|
||||||
"successTitle": "Erfolg",
|
"successTitle": "Erfolg",
|
||||||
"addedCoinsDescription": "{amount} Münzen hinzugefügt",
|
"transactionNotFoundDescription": "Transaktion nicht gefunden",
|
||||||
"removedCoinsDescription": "{amount} Münzen entfernt",
|
"maxAmountExceededDescription": "Der Betrag darf {max} nicht überschreiten.",
|
||||||
"transactionNotFoundDescription": "Transaktion nicht gefunden"
|
"transactionNotFoundDescription": "Transaktion nicht gefunden",
|
||||||
},
|
"maxAmountExceededDescription": "Der Betrag darf {max} nicht überschreiten."
|
||||||
"Warning": {
|
|
||||||
"areYouSure": "Sind Sie sicher?",
|
|
||||||
"cancel": "Abbrechen"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,9 +410,10 @@
|
|||||||
"invalidAmountTitle": "Invalid amount",
|
"invalidAmountTitle": "Invalid amount",
|
||||||
"invalidAmountDescription": "Please enter a valid positive number",
|
"invalidAmountDescription": "Please enter a valid positive number",
|
||||||
"successTitle": "Success",
|
"successTitle": "Success",
|
||||||
"addedCoinsDescription": "Added {amount} coins",
|
"transactionNotFoundDescription": "Transaction not found",
|
||||||
"removedCoinsDescription": "Removed {amount} coins",
|
"maxAmountExceededDescription": "The amount cannot exceed {max}.",
|
||||||
"transactionNotFoundDescription": "Transaction not found"
|
"transactionNotFoundDescription": "Transaction not found",
|
||||||
|
"maxAmountExceededDescription": "The amount cannot exceed {max}."
|
||||||
},
|
},
|
||||||
"Warning": {
|
"Warning": {
|
||||||
"areYouSure": "Are you sure?",
|
"areYouSure": "Are you sure?",
|
||||||
|
|||||||
@@ -406,16 +406,17 @@
|
|||||||
"notEnoughCoinsTitle": "No hay suficientes monedas",
|
"notEnoughCoinsTitle": "No hay suficientes monedas",
|
||||||
"notEnoughCoinsDescription": "Necesitas {coinsNeeded} monedas más para canjear esta recompensa."
|
"notEnoughCoinsDescription": "Necesitas {coinsNeeded} monedas más para canjear esta recompensa."
|
||||||
},
|
},
|
||||||
|
"Warning": {
|
||||||
|
"areYouSure": "¿Estás seguro?",
|
||||||
|
"cancel": "Cancelar"
|
||||||
|
},
|
||||||
"useCoins": {
|
"useCoins": {
|
||||||
"invalidAmountTitle": "Cantidad inválida",
|
"invalidAmountTitle": "Cantidad inválida",
|
||||||
"invalidAmountDescription": "Por favor ingresa un número positivo válido",
|
"invalidAmountDescription": "Por favor ingresa un número positivo válido",
|
||||||
"successTitle": "Éxito",
|
"successTitle": "Éxito",
|
||||||
"addedCoinsDescription": "Añadidas {amount} monedas",
|
"transactionNotFoundDescription": "Transacción no encontrada",
|
||||||
"removedCoinsDescription": "Quitadas {amount} monedas",
|
"maxAmountExceededDescription": "La cantidad no puede exceder {max}.",
|
||||||
"transactionNotFoundDescription": "Transacción no encontrada"
|
"transactionNotFoundDescription": "Transacción no encontrada",
|
||||||
},
|
"maxAmountExceededDescription": "La cantidad no puede exceder {max}."
|
||||||
"Warning": {
|
|
||||||
"areYouSure": "¿Estás seguro?",
|
|
||||||
"cancel": "Cancelar"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,16 +406,17 @@
|
|||||||
"notEnoughCoinsTitle": "Pas assez de pièces",
|
"notEnoughCoinsTitle": "Pas assez de pièces",
|
||||||
"notEnoughCoinsDescription": "Il vous manque {coinsNeeded} pièces pour échanger cette récompense."
|
"notEnoughCoinsDescription": "Il vous manque {coinsNeeded} pièces pour échanger cette récompense."
|
||||||
},
|
},
|
||||||
|
"Warning": {
|
||||||
|
"areYouSure": "Êtes-vous sûr ?",
|
||||||
|
"cancel": "Annuler"
|
||||||
|
},
|
||||||
"useCoins": {
|
"useCoins": {
|
||||||
"invalidAmountTitle": "Montant invalide",
|
"invalidAmountTitle": "Montant invalide",
|
||||||
"invalidAmountDescription": "Veuillez entrer un nombre positif valide",
|
"invalidAmountDescription": "Veuillez entrer un nombre positif valide",
|
||||||
"successTitle": "Succès",
|
"successTitle": "Succès",
|
||||||
"addedCoinsDescription": "Ajouté {amount} pièces",
|
"transactionNotFoundDescription": "Transaction non trouvée",
|
||||||
"removedCoinsDescription": "Retiré {amount} pièces",
|
"maxAmountExceededDescription": "Le montant ne peut pas dépasser {max}.",
|
||||||
"transactionNotFoundDescription": "Transaction non trouvée"
|
"transactionNotFoundDescription": "Transaction non trouvée",
|
||||||
},
|
"maxAmountExceededDescription": "Le montant ne peut pas dépasser {max}."
|
||||||
"Warning": {
|
|
||||||
"areYouSure": "Êtes-vous sûr ?",
|
|
||||||
"cancel": "Annuler"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,16 +406,17 @@
|
|||||||
"notEnoughCoinsTitle": "コインが不足しています",
|
"notEnoughCoinsTitle": "コインが不足しています",
|
||||||
"notEnoughCoinsDescription": "この報酬を使用するにはあと{coinsNeeded}コイン必要です。"
|
"notEnoughCoinsDescription": "この報酬を使用するにはあと{coinsNeeded}コイン必要です。"
|
||||||
},
|
},
|
||||||
|
"Warning": {
|
||||||
|
"areYouSure": "本当によろしいですか?",
|
||||||
|
"cancel": "キャンセル"
|
||||||
|
},
|
||||||
"useCoins": {
|
"useCoins": {
|
||||||
"invalidAmountTitle": "無効な値です",
|
"invalidAmountTitle": "無効な値です",
|
||||||
"invalidAmountDescription": "有効な正の数を入力してください",
|
"invalidAmountDescription": "有効な正の数を入力してください",
|
||||||
"successTitle": "成功しました",
|
"successTitle": "成功しました",
|
||||||
"addedCoinsDescription": "{amount}コインを追加しました",
|
"transactionNotFoundDescription": "取引が見つかりません",
|
||||||
"removedCoinsDescription": "{amount}コインを削除しました",
|
"maxAmountExceededDescription": "金額は{max}を超えることはできません。",
|
||||||
"transactionNotFoundDescription": "取引が見つかりません"
|
"transactionNotFoundDescription": "取引が見つかりません",
|
||||||
},
|
"maxAmountExceededDescription": "金額は{max}を超えることはできません。"
|
||||||
"Warning": {
|
|
||||||
"areYouSure": "本当によろしいですか?",
|
|
||||||
"cancel": "キャンセル"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,16 +406,17 @@
|
|||||||
"notEnoughCoinsTitle": "Недостаточно монет",
|
"notEnoughCoinsTitle": "Недостаточно монет",
|
||||||
"notEnoughCoinsDescription": "Вам нужно еще {coinsNeeded} монет, чтобы получить эту награду."
|
"notEnoughCoinsDescription": "Вам нужно еще {coinsNeeded} монет, чтобы получить эту награду."
|
||||||
},
|
},
|
||||||
|
"Warning": {
|
||||||
|
"areYouSure": "Вы уверены?",
|
||||||
|
"cancel": "Отмена"
|
||||||
|
},
|
||||||
"useCoins": {
|
"useCoins": {
|
||||||
"invalidAmountTitle": "Неверная сумма",
|
"invalidAmountTitle": "Неверная сумма",
|
||||||
"invalidAmountDescription": "Пожалуйста, введите положительное число",
|
"invalidAmountDescription": "Пожалуйста, введите положительное число",
|
||||||
"successTitle": "Успех",
|
"successTitle": "Успех",
|
||||||
"addedCoinsDescription": "Добавлено {amount} монет",
|
"transactionNotFoundDescription": "Транзакция не найдена",
|
||||||
"removedCoinsDescription": "Удалено {amount} монет",
|
"maxAmountExceededDescription": "Сумма не может превышать {max}.",
|
||||||
"transactionNotFoundDescription": "Транзакция не найдена"
|
"transactionNotFoundDescription": "Транзакция не найдена",
|
||||||
},
|
"maxAmountExceededDescription": "Сумма не может превышать {max}."
|
||||||
"Warning": {
|
|
||||||
"areYouSure": "Вы уверены?",
|
|
||||||
"cancel": "Отмена"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,16 +406,17 @@
|
|||||||
"notEnoughCoinsTitle": "金币不足",
|
"notEnoughCoinsTitle": "金币不足",
|
||||||
"notEnoughCoinsDescription": "您还需要{coinsNeeded}金币才能兑换此奖励。"
|
"notEnoughCoinsDescription": "您还需要{coinsNeeded}金币才能兑换此奖励。"
|
||||||
},
|
},
|
||||||
|
"Warning": {
|
||||||
|
"areYouSure": "您确定吗?",
|
||||||
|
"cancel": "取消"
|
||||||
|
},
|
||||||
"useCoins": {
|
"useCoins": {
|
||||||
"invalidAmountTitle": "无效金额",
|
"invalidAmountTitle": "无效金额",
|
||||||
"invalidAmountDescription": "请输入有效的正数",
|
"invalidAmountDescription": "请输入有效的正数",
|
||||||
"successTitle": "成功",
|
"successTitle": "成功",
|
||||||
"addedCoinsDescription": "添加了{amount}金币",
|
"transactionNotFoundDescription": "未找到交易记录",
|
||||||
"removedCoinsDescription": "移除了{amount}金币",
|
"maxAmountExceededDescription": "金额不能超过 {max}。",
|
||||||
"transactionNotFoundDescription": "未找到交易记录"
|
"transactionNotFoundDescription": "未找到交易记录",
|
||||||
},
|
"maxAmountExceededDescription": "金额不能超过 {max}。"
|
||||||
"Warning": {
|
|
||||||
"areYouSure": "您确定吗?",
|
|
||||||
"cancel": "取消"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "habittrove",
|
"name": "habittrove",
|
||||||
"version": "0.2.14",
|
"version": "0.2.15",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbopack",
|
"dev": "next dev --turbopack",
|
||||||
|
|||||||
Reference in New Issue
Block a user