BigBlocks

Cloud Backup Prompt

Dialog prompting users to set up encrypted cloud backup with password strength validation and confirmation

Installation

bunx shadcn@latest add https://registry.bigblocks.dev/r/cloud-backup-prompt.json

Usage

The block is agnostic about how encryption and upload are performed. You provide an onSave callback that receives the chosen password and handles the rest.

import { useState } from "react"
import { CloudBackupPrompt } from "@/components/blocks/cloud-backup-prompt"
 
export default function App() {
  const [open, setOpen] = useState(true)
 
  return (
    <CloudBackupPrompt
      open={open}
      onOpenChange={setOpen}
      onSave={async (password) => {
        const backup = localStorage.getItem("encrypted-backup")
        if (!backup) throw new Error("No backup found")
        await uploadBackup(backup, password)
      }}
      onRemindLater={() => console.log("Remind later")}
      onSuccess={() => console.log("Backup saved")}
    />
  )
}

Features

  • Password strength meter with visual feedback (Weak, Fair, Good, Strong)
  • Confirm password field with mismatch validation
  • End-to-end encryption explainer with feature icons
  • Success state confirming backup is enabled
  • "Remind Me Later" option for deferred setup
  • Auto-focus on password field when dialog opens

Props

CloudBackupPrompt

PropTypeDefaultDescription
openbooleanWhether the dialog is open (required)
onOpenChange(open: boolean) => voidCalled when the dialog open state changes (required)
onSave(password: string) => Promise<void>Callback that performs the encryption and upload (required)
onRemindLater() => voidCalled when "Remind Me Later" is clicked
onSuccess() => voidCalled on successful save
onError(error: Error) => voidCalled on error
minPasswordLengthnumber8Minimum password length
classNamestringOptional CSS class for the dialog content

Hook

useCloudBackup can be used independently for a custom backup UI.

import { useCloudBackup } from "@/components/blocks/cloud-backup-prompt"
 
function CustomBackupForm() {
  const hook = useCloudBackup({
    onSave: async (password) => {
      await encryptAndUpload(password)
    },
    minPasswordLength: 10,
  })
 
  return (
    <form onSubmit={(e) => { e.preventDefault(); hook.save() }}>
      <input
        type="password"
        value={hook.password}
        onChange={(e) => hook.setPassword(e.target.value)}
      />
      <input
        type="password"
        value={hook.confirmPassword}
        onChange={(e) => hook.setConfirmPassword(e.target.value)}
      />
      <p>Strength: {hook.validation.strengthLabel}</p>
      <button disabled={!hook.validation.isValid || hook.status === "saving"}>
        {hook.status === "saving" ? "Saving..." : "Save Backup"}
      </button>
    </form>
  )
}