shadcn.io is not affiliated with official shadcn/ui
Push Approval Number Matching Login Block for Radix UI
An approval step for a freight dashboard: choose Push, Text or Call, send the request and match the number on screen with two demo buttons that play the phone, with a 60-second timer, a wrong-number cancel and an expiry.
Installation
Overview
Let people approve a sign-in on their phone, and make them match a number to do it, with this push approval login block for React with Radix UI. It models the number-matching approval that push-based services such as Duo Security popularised, built on the product's own authenticator with no vendor branding. It's the approval step of a Freightby sign-in, a freight dashboard: the page's side rails run the full height and one band crosses it, holding a centred column. A Toggle Group picks Push, Text or Call; a status box shows what will happen, and pressing Send starts a 60-second Timer and shows a large number to match. Two outline buttons labelled "Demo:" play the phone, one with the matching number and one with a wrong one. The matching one signs in, the wrong one cancels the request, and letting the timer run out expires it; either way the button offers to send again. It's built from Toggle Group, Timer, Button, Shine Button and Guides, with a CSS entrance only. For sign-ins that approve on a second device.
FAQ
What is real here, and what is the demo phone?
Nothing is sent. The two buttons labelled "Demo:" stand in for the person's phone and are the only way to answer, and the numbers are fixed (47 and 12 for Push, 83 and 29 for Text, 6 and 2 for Call). In a product your server makes the number, shows it to the browser that asked, and offers the phone that number among two others; it accepts only the matching tap, once, and ties the request to the sign-in attempt that started it.
Why match a number instead of tapping Approve?
A plain Approve button can be worn down: an attacker with a stolen password sends request after request until a tired person taps yes. With number matching the person has to read a number off the screen they are actually signing in on, so a request they didn't start has no number to match.
How does the 60-second timer work?
It starts when Send is pressed, not when the page loads, and shows the time remaining under the number. When it reaches zero the request expires: the status box says so and the button reads "Send again", which starts a new request with a new timer. With reduced motion the ticking digits are hidden and a sentence says the request expires in 60 seconds.
What are the three outcomes?
A matching answer signs in and shows who approved it and the number matched. A wrong number cancels the request: "That was not the number.", and the button reads "Send again". No answer expires it. Choosing a different method while a request waits cancels it too, with a polite message, so two requests are never live at once.
Why are the demo buttons never disabled?
A disabled button gives a keyboard user nothing to learn from. Before a request exists the Demo buttons stay pressable and look quiet; pressing one says "Send a request first." and moves focus to the Send button. The Send button does the same while a request waits: it stays in place, quiet, and pressing it says it is waiting.