Skip to content

Commit 4035fa1

Browse files
sktbrdclaude
andcommitted
fix(stake): lock copy reads from last stake; stake form above milestones in dialog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 0e3e61e commit 4035fa1

3 files changed

Lines changed: 106 additions & 106 deletions

File tree

messages/en/stake.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@
117117
"viaMorpho": "yield via Morpho · stable",
118118
"viaMorpheus": "yield via Morpheus · in MOR",
119119
"estNote": "≈{rate}% APR estimate — swings with the MOR price and pool size.",
120-
"mainnetWarn": "Principal unlocks after a 7-day lock.",
120+
"mainnetWarn": "Principal unlocks 7 days after your last stake.",
121121
"estYearLabel": "Estimated value / year",
122122
"estYearNote": "Paid in MOR on Arbitrum — a live estimate, not a guarantee.",
123123
"approving": "approving…",
124124
"staking": "staking on mainnet…",
125125
"stakedMorTitle": "Staked with {name} on Morpheus",
126-
"stakedMorDesc": "Earning MOR on Arbitrum — your principal unlocks after 7 days.",
126+
"stakedMorDesc": "Earning MOR on Arbitrum — your principal unlocks 7 days after your last stake.",
127127
"yourPosition": "Your position",
128128
"principal": "principal",
129129
"yield": "yield",
@@ -233,8 +233,8 @@
233233
"rateHelpLabel": "About the {asset} rate on {venue}",
234234
"rateHelp": {
235235
"morphoUsdc": "Annual rate, paid in USDC. No lock: withdraw whenever you want.",
236-
"morpheusSteth": "Estimated annual rate, paid in MOR. Your stETH unlocks 7 days after you stake.",
237-
"morpheusUsdc": "Estimated annual rate, paid in MOR. Your USDC unlocks 7 days after you stake."
236+
"morpheusSteth": "Estimated annual rate, paid in MOR. Your stETH unlocks 7 days after your last stake.",
237+
"morpheusUsdc": "Estimated annual rate, paid in MOR. Your USDC unlocks 7 days after your last stake."
238238
},
239239
"ratesLoading": "loading rates…",
240240
"ratesNa": "n/a",

messages/pt-br/stake.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@
117117
"viaMorpho": "rendimento via Morpho · estável",
118118
"viaMorpheus": "rendimento via Morpheus · em MOR",
119119
"estNote": "≈{rate}% APR estimado — varia com o preço do MOR e o tamanho do pool.",
120-
"mainnetWarn": "O principal destrava após um lock de 7 dias.",
120+
"mainnetWarn": "O principal destrava 7 dias depois do último stake.",
121121
"estYearLabel": "Valor estimado / ano",
122122
"estYearNote": "Pago em MOR na Arbitrum — estimativa ao vivo, não é garantia.",
123123
"approving": "aprovando…",
124124
"staking": "stakeando na mainnet…",
125125
"stakedMorTitle": "Stake com {name} na Morpheus",
126-
"stakedMorDesc": "Rendendo MOR na Arbitrum — o principal destrava após 7 dias.",
126+
"stakedMorDesc": "Rendendo MOR na Arbitrum — o principal destrava 7 dias depois do último stake.",
127127
"yourPosition": "Sua posição",
128128
"principal": "principal",
129129
"yield": "rendimento",
@@ -233,8 +233,8 @@
233233
"rateHelpLabel": "Sobre a taxa de {asset} na {venue}",
234234
"rateHelp": {
235235
"morphoUsdc": "Taxa anual, paga em USDC. Sem lock: saque quando quiser.",
236-
"morpheusSteth": "Taxa anual estimada, paga em MOR. Seu stETH libera 7 dias depois do stake.",
237-
"morpheusUsdc": "Taxa anual estimada, paga em MOR. Seu USDC libera 7 dias depois do stake."
236+
"morpheusSteth": "Taxa anual estimada, paga em MOR. Seu stETH libera 7 dias depois do último stake.",
237+
"morpheusUsdc": "Taxa anual estimada, paga em MOR. Seu USDC libera 7 dias depois do último stake."
238238
},
239239
"ratesLoading": "carregando as taxas…",
240240
"ratesNa": "n/d",

src/components/stake/GnarsStakeDialog.tsx

Lines changed: 98 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -147,104 +147,6 @@ export function GnarsStakeDialog({ open, onOpenChange }: Props) {
147147
<p className="mt-2 text-sm text-muted-foreground">{t("dialog.desc")}</p>
148148
</div>
149149

150-
{/* Milestones hero */}
151-
<section className="rounded-2xl border border-emerald-500/25 bg-gradient-to-br from-emerald-500/[0.08] via-emerald-500/[0.02] to-transparent p-5 sm:p-6">
152-
<div className="flex flex-wrap items-end justify-between gap-3">
153-
<div>
154-
<div className="text-[11px] font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400">
155-
{t("dialog.milestonesLabel")}
156-
</div>
157-
<div className="mt-1 flex items-baseline gap-1.5">
158-
<CountUp
159-
value={totalStaked}
160-
decimals={0}
161-
className="text-4xl font-black tabular-nums"
162-
/>
163-
<span className="text-sm font-medium text-muted-foreground">
164-
/ {fmt(SUBNET_GOAL_MOR, locale, 0)} MOR
165-
</span>
166-
</div>
167-
</div>
168-
<span className="rounded-full bg-emerald-500/15 px-3 py-1 text-xs font-semibold text-emerald-600 dark:text-emerald-300">
169-
{t("dialog.progressToEvent", { pct: pctLabel, n: SUBNET_GOAL_MOR })}
170-
</span>
171-
</div>
172-
173-
{/* Progress bar with milestone ticks */}
174-
<div className="relative mt-5 pb-1 sm:pb-7">
175-
<div className="h-4 w-full rounded-full bg-emerald-500/10 ring-1 ring-emerald-500/20">
176-
<div
177-
className="h-4 rounded-full bg-gradient-to-r from-emerald-600 via-emerald-400 to-[#2be58b] shadow-[0_0_16px_rgba(43,229,139,.6)] transition-all duration-700"
178-
style={{ width: `${pct}%` }}
179-
/>
180-
</div>
181-
{MOR_TICKS.map((m) => {
182-
const left = Math.min(100, (m.amountMor / SUBNET_GOAL_MOR) * 100);
183-
const done = totalStaked >= m.amountMor;
184-
return (
185-
<div
186-
key={m.id}
187-
className="pointer-events-none absolute top-0 flex -translate-x-1/2 flex-col items-center"
188-
style={{ left: `${left}%` }}
189-
>
190-
<span
191-
className={cn(
192-
"h-4 w-1 rounded-full",
193-
done
194-
? "bg-emerald-600 shadow-[0_0_6px_rgba(43,229,139,.8)] dark:bg-[#2be58b]"
195-
: "bg-emerald-500/25",
196-
)}
197-
aria-hidden
198-
/>
199-
<span
200-
className={cn(
201-
"mt-1.5 hidden text-[10px] font-semibold tabular-nums sm:block",
202-
done ? "text-foreground" : "text-muted-foreground",
203-
)}
204-
>
205-
{shortMor(m.amountMor)}
206-
</span>
207-
</div>
208-
);
209-
})}
210-
</div>
211-
212-
{/* Milestone checklist */}
213-
<ol className="mt-5 grid gap-2 sm:grid-cols-2">
214-
{SUBNET_MILESTONES.map((m) => {
215-
const done = isMilestoneDone(m, totalStaked);
216-
return (
217-
<li key={m.id} className="flex items-start gap-2.5">
218-
<span
219-
className={cn(
220-
"mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full",
221-
done
222-
? "bg-emerald-500 text-white"
223-
: "border border-border text-muted-foreground",
224-
)}
225-
>
226-
{done ? <Check className="h-3.5 w-3.5" /> : <Lock className="h-3 w-3" />}
227-
</span>
228-
<span
229-
className={cn(
230-
"text-sm leading-snug",
231-
done ? "font-semibold text-foreground" : "text-muted-foreground",
232-
)}
233-
>
234-
{t("milestoneRow", { n: m.amountMor, what: t("milestones." + m.id) })}{" "}
235-
{/* Same committed/proposed label the page ladder carries.
236-
Dropping it here would make the dialog read as six firm
237-
promises while the section behind it says five are not. */}
238-
<span className="text-[10px] font-semibold tracking-wide whitespace-nowrap text-muted-foreground uppercase">
239-
· {t("firmness." + m.firmness)}
240-
</span>
241-
</span>
242-
</li>
243-
);
244-
})}
245-
</ol>
246-
</section>
247-
248150
{/* Stake form */}
249151
<section className="rounded-2xl border border-border/60 bg-muted/20 p-5 sm:p-6">
250152
<div className="grid grid-cols-2 gap-3">
@@ -343,6 +245,104 @@ export function GnarsStakeDialog({ open, onOpenChange }: Props) {
343245
</p>
344246
</section>
345247

248+
{/* Milestones hero */}
249+
<section className="rounded-2xl border border-emerald-500/25 bg-gradient-to-br from-emerald-500/[0.08] via-emerald-500/[0.02] to-transparent p-5 sm:p-6">
250+
<div className="flex flex-wrap items-end justify-between gap-3">
251+
<div>
252+
<div className="text-[11px] font-bold uppercase tracking-wider text-emerald-600 dark:text-emerald-400">
253+
{t("dialog.milestonesLabel")}
254+
</div>
255+
<div className="mt-1 flex items-baseline gap-1.5">
256+
<CountUp
257+
value={totalStaked}
258+
decimals={0}
259+
className="text-4xl font-black tabular-nums"
260+
/>
261+
<span className="text-sm font-medium text-muted-foreground">
262+
/ {fmt(SUBNET_GOAL_MOR, locale, 0)} MOR
263+
</span>
264+
</div>
265+
</div>
266+
<span className="rounded-full bg-emerald-500/15 px-3 py-1 text-xs font-semibold text-emerald-600 dark:text-emerald-300">
267+
{t("dialog.progressToEvent", { pct: pctLabel, n: SUBNET_GOAL_MOR })}
268+
</span>
269+
</div>
270+
271+
{/* Progress bar with milestone ticks */}
272+
<div className="relative mt-5 pb-1 sm:pb-7">
273+
<div className="h-4 w-full rounded-full bg-emerald-500/10 ring-1 ring-emerald-500/20">
274+
<div
275+
className="h-4 rounded-full bg-gradient-to-r from-emerald-600 via-emerald-400 to-[#2be58b] shadow-[0_0_16px_rgba(43,229,139,.6)] transition-all duration-700"
276+
style={{ width: `${pct}%` }}
277+
/>
278+
</div>
279+
{MOR_TICKS.map((m) => {
280+
const left = Math.min(100, (m.amountMor / SUBNET_GOAL_MOR) * 100);
281+
const done = totalStaked >= m.amountMor;
282+
return (
283+
<div
284+
key={m.id}
285+
className="pointer-events-none absolute top-0 flex -translate-x-1/2 flex-col items-center"
286+
style={{ left: `${left}%` }}
287+
>
288+
<span
289+
className={cn(
290+
"h-4 w-1 rounded-full",
291+
done
292+
? "bg-emerald-600 shadow-[0_0_6px_rgba(43,229,139,.8)] dark:bg-[#2be58b]"
293+
: "bg-emerald-500/25",
294+
)}
295+
aria-hidden
296+
/>
297+
<span
298+
className={cn(
299+
"mt-1.5 hidden text-[10px] font-semibold tabular-nums sm:block",
300+
done ? "text-foreground" : "text-muted-foreground",
301+
)}
302+
>
303+
{shortMor(m.amountMor)}
304+
</span>
305+
</div>
306+
);
307+
})}
308+
</div>
309+
310+
{/* Milestone checklist */}
311+
<ol className="mt-5 grid gap-2 sm:grid-cols-2">
312+
{SUBNET_MILESTONES.map((m) => {
313+
const done = isMilestoneDone(m, totalStaked);
314+
return (
315+
<li key={m.id} className="flex items-start gap-2.5">
316+
<span
317+
className={cn(
318+
"mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full",
319+
done
320+
? "bg-emerald-500 text-white"
321+
: "border border-border text-muted-foreground",
322+
)}
323+
>
324+
{done ? <Check className="h-3.5 w-3.5" /> : <Lock className="h-3 w-3" />}
325+
</span>
326+
<span
327+
className={cn(
328+
"text-sm leading-snug",
329+
done ? "font-semibold text-foreground" : "text-muted-foreground",
330+
)}
331+
>
332+
{t("milestoneRow", { n: m.amountMor, what: t("milestones." + m.id) })}{" "}
333+
{/* Same committed/proposed label the page ladder carries.
334+
Dropping it here would make the dialog read as six firm
335+
promises while the section behind it says five are not. */}
336+
<span className="text-[10px] font-semibold tracking-wide whitespace-nowrap text-muted-foreground uppercase">
337+
· {t("firmness." + m.firmness)}
338+
</span>
339+
</span>
340+
</li>
341+
);
342+
})}
343+
</ol>
344+
</section>
345+
346346
{/* Position / withdraw */}
347347
{position && position.staked > 0 && (
348348
<section className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-border/60 bg-background/40 p-4 sm:p-5">

0 commit comments

Comments
 (0)