From bcb0a6ddb22dab2515082c86603a9e7303a4715c Mon Sep 17 00:00:00 2001 From: aorlov Date: Wed, 24 Dec 2025 00:40:47 +0100 Subject: [PATCH] feat: enhance download functionality with loading state and API integration --- .github/workflows/deploy-demo.yml | 2 ++ demo/src/App.tsx | 6 ++++-- src/defaults/DownloadButton.tsx | 24 ++++++++++++++++++------ src/defaults/SubmitButton.tsx | 20 ++++++++++++-------- src/index.tsx | 23 ++++++++++++++++++++--- src/styles.css | 26 ++++++++++++++++++++++++++ src/types.ts | 1 + 7 files changed, 83 insertions(+), 19 deletions(-) diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index 3311a37..05178e3 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -42,6 +42,8 @@ jobs: cache: "pnpm" - name: Install and Build + env: + VITE_API_BASE_URL: https://esign-demo-proxy-server-191591660773.us-central1.run.app run: | pnpm install rm -rf dist diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 219d08f..1cb8418 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -11,6 +11,8 @@ import CustomSignature from './CustomSignature'; import 'superdoc/style.css'; import './App.css'; +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || ''; + const documentSource = 'https://storage.googleapis.com/public_static_hosting/public_demo_docs/service_agreement_updated.docx'; @@ -91,7 +93,7 @@ export function App() { console.log('Submit data:', data); try { - const response = await fetch('/v1/sign', { + const response = await fetch(`${API_BASE_URL}/v1/sign`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -132,7 +134,7 @@ export function App() { return; } - const response = await fetch('/v1/download', { + const response = await fetch(`${API_BASE_URL}/v1/download`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ diff --git a/src/defaults/DownloadButton.tsx b/src/defaults/DownloadButton.tsx index b1bb745..7b78a26 100644 --- a/src/defaults/DownloadButton.tsx +++ b/src/defaults/DownloadButton.tsx @@ -2,27 +2,39 @@ import React from 'react'; import type { DownloadButtonProps, DownloadConfig } from '../types'; export const createDownloadButton = (config?: DownloadConfig) => { - const Component: React.FC = ({ onClick, fileName, isDisabled }) => { + const Component: React.FC = ({ + onClick, + fileName, + isDisabled, + isDownloading, + }) => { const label = config?.label || 'Download'; + const disabled = isDisabled || isDownloading; return ( ); }; diff --git a/src/defaults/SubmitButton.tsx b/src/defaults/SubmitButton.tsx index ca30f00..b16b583 100644 --- a/src/defaults/SubmitButton.tsx +++ b/src/defaults/SubmitButton.tsx @@ -8,28 +8,32 @@ export const createSubmitButton = (config?: SubmitConfig) => { isDisabled, isSubmitting, }) => { - const getLabel = () => { - return config?.label || 'Submit'; - }; + const label = config?.label || 'Submit'; + const disabled = !isValid || isDisabled || isSubmitting; return ( ); }; diff --git a/src/index.tsx b/src/index.tsx index c9971c0..ebedddf 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -36,6 +36,7 @@ const SuperDocESign = forwardRef>(new Map()); const [isValid, setIsValid] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); + const [isDownloading, setIsDownloading] = useState(false); const [auditTrail, setAuditTrail] = useState([]); const [isReady, setIsReady] = useState(false); @@ -298,7 +299,9 @@ const SuperDocESign = forwardRef { - if (isDisabled) return; + if (isDisabled || isDownloading) return; + + setIsDownloading(true); const downloadData: Types.DownloadData = { eventId, @@ -313,8 +316,21 @@ const SuperDocESign = forwardRef { if (!isValid || isDisabled || isSubmitting) return; @@ -378,6 +394,7 @@ const SuperDocESign = forwardRef ); }; diff --git a/src/styles.css b/src/styles.css index 6bdf738..985f3e1 100644 --- a/src/styles.css +++ b/src/styles.css @@ -49,3 +49,29 @@ display: flex; gap: 10px; } + +/* Button loading state */ +.superdoc-esign-btn--loading { + position: relative; +} + +/* Spinner */ +.superdoc-esign-spinner { + width: 16px; + height: 16px; + border: 2px solid #d0d5dd; + border-top-color: #333; + border-radius: 50%; + animation: superdoc-esign-spin 0.8s linear infinite; +} + +.superdoc-esign-spinner--light { + border-color: rgba(255, 255, 255, 0.3); + border-top-color: #fff; +} + +@keyframes superdoc-esign-spin { + to { + transform: rotate(360deg); + } +} diff --git a/src/types.ts b/src/types.ts index 0b8b0bf..c69e1df 100644 --- a/src/types.ts +++ b/src/types.ts @@ -33,6 +33,7 @@ export interface DownloadButtonProps { onClick: () => void; fileName?: string; isDisabled: boolean; + isDownloading: boolean; } export interface SubmitButtonProps {