diff --git a/docs/screenshots/reorganized-flow/12-payment.png b/docs/screenshots/reorganized-flow/12-payment.png new file mode 100644 index 0000000..56731b1 Binary files /dev/null and b/docs/screenshots/reorganized-flow/12-payment.png differ diff --git a/docs/screenshots/reorganized-flow/13-review.png b/docs/screenshots/reorganized-flow/13-review.png new file mode 100644 index 0000000..9c6e4e1 Binary files /dev/null and b/docs/screenshots/reorganized-flow/13-review.png differ diff --git a/docs/screenshots/reorganized-flow/14-confirmation.png b/docs/screenshots/reorganized-flow/14-confirmation.png new file mode 100644 index 0000000..2088f3e Binary files /dev/null and b/docs/screenshots/reorganized-flow/14-confirmation.png differ diff --git a/efile_app/efile/api/auth_views.py b/efile_app/efile/api/auth_views.py index fef01fa..0bbb8cb 100644 --- a/efile_app/efile/api/auth_views.py +++ b/efile_app/efile/api/auth_views.py @@ -262,6 +262,49 @@ def payment_accounts(request): except Exception as e: return AuthAPIViews.error_response(f"Error: {str(e)}") + @staticmethod + @require_http_methods(["GET"]) + def payment_account_types(request): + """List the court's payment account types (e.g. "CC", "WV") with names. + + A payment account only carries its type *code*, not a human-readable + name, so the frontend needs this list to label account types other + than the ones it special-cases (card, waiver). + """ + try: + jurisdiction = get_jurisdiction_from_request(request) + tyler_token = get_tyler_token(request, jurisdiction) + api_key = getattr(settings, "SUFFOLK_EFILE_API_KEY", None) + + headers = { + "Content-Type": "application/json", + "User-Agent": f"{jurisdiction.title()}-eFile-Client/1.0", + "X-API-Key": api_key if api_key else "", + } + if tyler_token: + headers[f"tyler-token-{jurisdiction}"] = tyler_token + + url = f"{settings.EFSP_URL}/jurisdictions/{jurisdiction}/payments/types" + logger.debug("GET %s header keys=%s", url, list(headers.keys())) + api_response = requests.get(url, headers=headers, timeout=10) + + if api_response.status_code == 200: + return AuthAPIViews.success_response(api_response.json()) + elif api_response.status_code == 401: + return AuthAPIViews.success_response([]) + else: + return AuthAPIViews.error_response( + f"Payment account types API returned status {api_response.status_code}: {api_response.text[:200]}", + api_response.status_code, + ) + + except Timeout: + return AuthAPIViews.error_response("Payment account types API request timed out", 408) + except RequestException as e: + return AuthAPIViews.error_response(f"Could not connect to payment account types API: {str(e)}", 503) + except Exception as e: + return AuthAPIViews.error_response(f"Error: {str(e)}") + # Individual view functions for URL mapping user_login = AuthAPIViews.user_login @@ -269,4 +312,5 @@ def payment_accounts(request): user_profile = AuthAPIViews.user_profile external_profile = AuthAPIViews.external_profile payment_accounts = AuthAPIViews.payment_accounts +payment_account_types = AuthAPIViews.payment_account_types tyler_token = AuthAPIViews.tyler_token diff --git a/efile_app/efile/api/urls.py b/efile_app/efile/api/urls.py index 1fbf375..d7157f1 100644 --- a/efile_app/efile/api/urls.py +++ b/efile_app/efile/api/urls.py @@ -6,6 +6,7 @@ from .auth_views import ( external_profile, + payment_account_types, payment_accounts, tyler_token, user_login, @@ -62,6 +63,7 @@ path("auth/tyler-token/", tyler_token, name="tyler_token"), # Payment API endpoints path("payment-accounts/", payment_accounts, name="payment_accounts"), + path("payment-account-types/", payment_account_types, name="payment_account_types"), path("payment-fees/", payment_fees, name="payment_fees"), # Filing API endpoints path("filings/", get_filings, name="get_filings"), diff --git a/efile_app/efile/migrations/0007_complete_workflow_migration.py b/efile_app/efile/migrations/0007_complete_workflow_migration.py new file mode 100644 index 0000000..c8372c7 --- /dev/null +++ b/efile_app/efile/migrations/0007_complete_workflow_migration.py @@ -0,0 +1,54 @@ +from django.db import migrations, models + + +STEP_MAPPINGS = { + "options": "filing_path", + "upload_first": "upload_documents", + "case_information": "extraction_review", + "documents": "organize_documents", +} + + +def migrate_saved_workflow_positions(apps, schema_editor): + FilingDraft = apps.get_model("efile", "FilingDraft") + for old_step, new_step in STEP_MAPPINGS.items(): + FilingDraft.objects.filter(current_step=old_step).update(current_step=new_step) + FilingDraft.objects.exclude(workflow_version=2).update(workflow_version=2) + + +class Migration(migrations.Migration): + dependencies = [("efile", "0006_filingparty_party_type_name")] + + operations = [ + migrations.RunPython(migrate_saved_workflow_positions, migrations.RunPython.noop), + migrations.AlterField( + model_name="filingdraft", + name="current_step", + field=models.CharField( + choices=[ + ("options", "Options"), + ("filing_path", "Filing"), + ("upload_documents", "Upload documents"), + ("extraction_review", "Confirm filing"), + ("case_lookup", "Find your case"), + ("case_confirmation", "Confirm your case"), + ("document_checklist", "Check documents"), + ("organize_documents", "Organize documents"), + ("your_information", "Your information"), + ("parties", "People in this filing"), + ("party_details", "Person details"), + ("case_questions", "Case questions"), + ("payment", "Fees"), + ("review", "Review"), + ("confirmation", "Confirmation"), + ], + default="options", + max_length=64, + ), + ), + migrations.AlterField( + model_name="filingdraft", + name="workflow_version", + field=models.PositiveSmallIntegerField(default=2), + ), + ] diff --git a/efile_app/efile/migrations/0008_merge_document_prep_and_people_migrations.py b/efile_app/efile/migrations/0008_merge_document_prep_and_people_migrations.py new file mode 100644 index 0000000..28525dc --- /dev/null +++ b/efile_app/efile/migrations/0008_merge_document_prep_and_people_migrations.py @@ -0,0 +1,14 @@ +# Generated by Django 5.2.5 on 2026-08-11 00:21 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('efile', '0006_filingdocument_requested_optional_services'), + ('efile', '0007_complete_workflow_migration'), + ] + + operations = [ + ] diff --git a/efile_app/efile/migrations/0009_filingdraft_payment_type_and_quoted_fees.py b/efile_app/efile/migrations/0009_filingdraft_payment_type_and_quoted_fees.py new file mode 100644 index 0000000..75c3b67 --- /dev/null +++ b/efile_app/efile/migrations/0009_filingdraft_payment_type_and_quoted_fees.py @@ -0,0 +1,23 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [("efile", "0008_merge_document_prep_and_people_migrations")] + + operations = [ + migrations.AddField( + model_name="filingdraft", + name="selected_payment_account_type", + field=models.CharField(max_length=50, blank=True), + ), + migrations.AddField( + model_name="filingdraft", + name="quoted_fee_total", + field=models.CharField(max_length=50, blank=True), + ), + migrations.AddField( + model_name="filingdraft", + name="quoted_fee_breakdown", + field=models.JSONField(default=list, blank=True), + ), + ] diff --git a/efile_app/efile/migrations/0010_merge_amount_in_controversy_and_payment_migrations.py b/efile_app/efile/migrations/0010_merge_amount_in_controversy_and_payment_migrations.py new file mode 100644 index 0000000..46522d4 --- /dev/null +++ b/efile_app/efile/migrations/0010_merge_amount_in_controversy_and_payment_migrations.py @@ -0,0 +1,14 @@ +# Generated by Django 5.2.5 on 2026-08-11 12:19 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('efile', '0007_amount_in_controversy'), + ('efile', '0009_filingdraft_payment_type_and_quoted_fees'), + ] + + operations = [ + ] diff --git a/efile_app/efile/models.py b/efile_app/efile/models.py index 0cbc9e8..7ae2422 100644 --- a/efile_app/efile/models.py +++ b/efile_app/efile/models.py @@ -54,7 +54,7 @@ class Status(models.TextChoices): choices=get_workflow_step_choices(), default=WorkflowStepKey.OPTIONS, ) - workflow_version = models.PositiveSmallIntegerField(default=1) + workflow_version = models.PositiveSmallIntegerField(default=2) existing_case = models.CharField( max_length=20, @@ -80,6 +80,13 @@ class Status(models.TextChoices): selected_payment_account_id = models.CharField(max_length=255, blank=True) selected_payment_account_name = models.CharField(max_length=255, blank=True) + # Tyler's paymentAccountTypeCode for the selected account (e.g. "WV" for a fee + # waiver). Drives whether Review shows a fee total or waiver messaging. + selected_payment_account_type = models.CharField(max_length=50, blank=True) + # The fee quote shown on the Payment step, carried forward so Review can + # display the same numbers instead of telling the filer to go look again. + quoted_fee_total = models.CharField(max_length=50, blank=True) + quoted_fee_breakdown = models.JSONField(default=list, blank=True) name_change_reason = models.TextField(blank=True) diff --git a/efile_app/efile/services/current_drafts.py b/efile_app/efile/services/current_drafts.py index a42120a..e2235d4 100644 --- a/efile_app/efile/services/current_drafts.py +++ b/efile_app/efile/services/current_drafts.py @@ -83,7 +83,7 @@ def create_current_draft( jurisdiction: str, *, current_step: WorkflowStepKey | str = WorkflowStepKey.OPTIONS, - workflow_version: int = 1, + workflow_version: int = 2, ) -> FilingDraft: draft = create_draft( user=_authenticated_user(request), @@ -109,7 +109,7 @@ def ensure_current_draft( request, jurisdiction, current_step=current_step or WorkflowStepKey.OPTIONS, - workflow_version=workflow_version or 1, + workflow_version=workflow_version or 2, ) if current_step is not None: set_current_step(draft, current_step) diff --git a/efile_app/efile/services/drafts.py b/efile_app/efile/services/drafts.py index 0840342..0382cb8 100644 --- a/efile_app/efile/services/drafts.py +++ b/efile_app/efile/services/drafts.py @@ -54,7 +54,7 @@ def create_draft( user, jurisdiction: str, current_step: WorkflowStepKey | str = WorkflowStepKey.OPTIONS, - workflow_version: int = 1, + workflow_version: int = 2, ) -> FilingDraft: """Create a durable draft owned by an authenticated user.""" diff --git a/efile_app/efile/static/css/common.css b/efile_app/efile/static/css/common.css index 3354d54..9f94544 100644 --- a/efile_app/efile/static/css/common.css +++ b/efile_app/efile/static/css/common.css @@ -1,10 +1,51 @@ +/* Single source of truth for color across every screen. + Anything user-facing should reference a token from this block rather than + its own hex value, so the app reads as one product instead of a set of + pages that each invented a slightly different blue. */ :root { + /* Brand blues. --better-blue is the one action color: primary buttons, + links, and accents all use it. */ --suffolk-blue: #1e3a5f; --better-blue: #2c5aa0; - --primary-btn-color: #007bff; + --brand-blue-hover: #24497f; + --brand-blue-active: #1e3a5f; + + /* Older pages theme their buttons through this name. Pointing it at the + brand blue keeps them in step with the rest of the app. */ + --primary-btn-color: var(--better-blue); + + /* Text tiers. Every value below clears WCAG AA (4.5:1) on white and on + both tinted surfaces defined here. */ + --text-heading: #1e3a5f; + --text-body: #48576c; + --text-muted: #616c82; + + /* Surfaces */ + --surface-subtle: #f6f9fd; + --surface-accent: #eef5ff; + --light-blue-background: #f8f9fa; + + /* Borders. --border-strong is for edges that outline a control; the + lighter two are decorative dividers. */ + --border-subtle: #e3e8ef; + --border-default: #dce3ec; + --border-accent: #cbdcf1; + --border-strong: #7d8ca3; + + /* Status */ --success: #28a745; + --success-text: #16703a; + --success-surface: #e5f6eb; + --success-border: #cde8d5; --failure: #dc3545; - --light-blue-background: #f8f9fa; + --danger-icon: #b23b3b; + --warning-surface: #fffaf0; + --warning-border: #ead8ad; + + /* Links follow the brand blue rather than Bootstrap's default indigo. */ + --bs-link-color: var(--better-blue); + --bs-link-hover-color: var(--brand-blue-hover); + --bs-link-color-rgb: 44, 90, 160; } body { @@ -26,4 +67,27 @@ h1 { h2 { color: var(--better-blue); font-weight: 500; +} + +/* One primary action color on every screen. Bootstrap themes buttons through + its own custom properties, so setting those keeps the hover, active, and + disabled states in step instead of repainting only the resting state. */ +.btn-primary { + --bs-btn-bg: var(--better-blue); + --bs-btn-border-color: var(--better-blue); + --bs-btn-hover-bg: var(--brand-blue-hover); + --bs-btn-hover-border-color: var(--brand-blue-hover); + --bs-btn-active-bg: var(--brand-blue-active); + --bs-btn-active-border-color: var(--brand-blue-active); + --bs-btn-disabled-bg: var(--better-blue); + --bs-btn-disabled-border-color: var(--better-blue); +} + +.btn-outline-primary { + --bs-btn-color: var(--better-blue); + --bs-btn-border-color: var(--better-blue); + --bs-btn-hover-bg: var(--better-blue); + --bs-btn-hover-border-color: var(--better-blue); + --bs-btn-active-bg: var(--brand-blue-active); + --bs-btn-active-border-color: var(--brand-blue-active); } \ No newline at end of file diff --git a/efile_app/efile/static/css/components/search-dropdown.css b/efile_app/efile/static/css/components/search-dropdown.css index b617459..d093612 100644 --- a/efile_app/efile/static/css/components/search-dropdown.css +++ b/efile_app/efile/static/css/components/search-dropdown.css @@ -13,7 +13,7 @@ .search-dropdown-input:focus { border-color: #86b7fe; outline: 0; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + box-shadow: 0 0 0 0.25rem rgba(44, 90, 160, 0.25); } .search-dropdown-input:disabled { @@ -93,7 +93,7 @@ .search-dropdown-selected:focus-within { border-color: #86b7fe; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); + box-shadow: 0 0 0 0.25rem rgba(44, 90, 160, 0.25); } .search-dropdown-selected .selected-text { diff --git a/efile_app/efile/static/css/confirmation.css b/efile_app/efile/static/css/confirmation.css index 08c76d9..0e1f627 100644 --- a/efile_app/efile/static/css/confirmation.css +++ b/efile_app/efile/static/css/confirmation.css @@ -1,37 +1,84 @@ -.confirmation-container { - max-width: 600px; - margin: 0 auto; - padding: 2rem; +.confirmation-workflow-card { text-align: center; } -.success-icon { - color: var(--success); - font-size: 4rem; - margin-bottom: 1rem; +.confirmation-workflow-card .workflow-lede { + margin-left: auto; + margin-right: auto; } -.success-message { - color: #155724; - font-size: 1.25rem; - margin-bottom: 2rem; +.confirmation-reference { + background: var(--surface-accent); + border: 1px solid var(--border-accent); + border-radius: 12px; + margin: 0 auto 1.25rem; + padding: 1rem; } -.btn-primary.custom-confirm { - background: var(--better-blue); - border-color: var(--better-blue); +.confirmation-reference span, +.confirmation-reference strong { + display: block; } -.btn-primary.custom-confirm:hover { - background: #1e3d6f; - border-color: #1e3d6f; +.confirmation-reference span { + color: var(--text-muted); + font-size: 0.8rem; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; } -@media (max-width: 576px) { - .confirmation-container { - padding: 1rem; - } +.confirmation-reference strong { + color: var(--better-blue); + font-size: 1.35rem; + margin-top: 0.25rem; +} + +.confirmation-summary { + border: 1px solid var(--border-default); + border-radius: 12px; + margin: 0; + text-align: left; +} + +.confirmation-summary>div { + display: flex; + justify-content: space-between; + padding: 0.75rem 1rem; +} + +.confirmation-summary>div+div { + border-top: 1px solid var(--border-subtle); +} + +.confirmation-summary dt { + color: var(--text-muted); +} + +.confirmation-summary dd { + color: var(--text-heading); + font-weight: 700; + margin: 0; +} + +.confirmation-next { + text-align: left; +} + +.confirmation-actions { + display: flex; + gap: 0.8rem; + justify-content: center; + margin-top: 1.5rem; +} + +.success-icon { + color: var(--success); + font-size: 4rem; + margin-bottom: 1rem; +} +@media (max-width: 700px) { .success-icon { font-size: 3rem; } diff --git a/efile_app/efile/static/css/expert_form.css b/efile_app/efile/static/css/expert_form.css index 7f73ee6..a0b5e14 100644 --- a/efile_app/efile/static/css/expert_form.css +++ b/efile_app/efile/static/css/expert_form.css @@ -44,7 +44,7 @@ .form-select:focus, .form-control:focus { border-color: var(--primary-btn-color); - box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); + box-shadow: 0 0 0 0.2rem rgba(44, 90, 160, 0.25); } .btn-outline-secondary { diff --git a/efile_app/efile/static/css/login.css b/efile_app/efile/static/css/login.css index 14068ea..bbe531b 100644 --- a/efile_app/efile/static/css/login.css +++ b/efile_app/efile/static/css/login.css @@ -68,8 +68,8 @@ } .form-control:focus { - border-color: #3b82f6; - box-shadow: 0 0 0 0.2rem rgba(59, 130, 246, 0.25); + border-color: var(--better-blue); + box-shadow: 0 0 0 0.2rem rgba(44, 90, 160, 0.25); } .btn-sign-in, @@ -103,7 +103,7 @@ .show-password:hover, .forgot-password:hover { - color: #3b82f6; + color: var(--better-blue); text-decoration: underline; } diff --git a/efile_app/efile/static/css/register.css b/efile_app/efile/static/css/register.css index e769047..bede412 100644 --- a/efile_app/efile/static/css/register.css +++ b/efile_app/efile/static/css/register.css @@ -115,8 +115,8 @@ .form-control:focus, .form-select:focus { - border-color: #3b82f6; - box-shadow: 0 0 0 0.2rem rgba(59, 130, 246, 0.25); + border-color: var(--better-blue); + box-shadow: 0 0 0 0.2rem rgba(44, 90, 160, 0.25); } .form-control::placeholder { @@ -175,7 +175,7 @@ } .password-toggle:hover { - color: #3b82f6; + color: var(--better-blue); } .phone-example { diff --git a/efile_app/efile/static/css/reorganized-flow.css b/efile_app/efile/static/css/reorganized-flow.css index 61e5d9f..c7b82c3 100644 --- a/efile_app/efile/static/css/reorganized-flow.css +++ b/efile_app/efile/static/css/reorganized-flow.css @@ -20,7 +20,7 @@ } .workflow-progress__item { - color: #687386; + color: var(--text-muted); flex: 1; font-size: 0.74rem; font-weight: 650; @@ -29,7 +29,7 @@ } .workflow-progress__item::before { - background: #d8dee8; + background: var(--border-subtle); content: ""; height: 2px; left: -50%; @@ -45,7 +45,7 @@ .workflow-progress__marker { align-items: center; background: #fff; - border: 2px solid #bcc5d2; + border: 2px solid var(--border-strong); border-radius: 50%; display: inline-flex; height: 32px; @@ -62,28 +62,28 @@ .workflow-progress__item--complete::before, .workflow-progress__item--current::before { - background: #2c5aa0; + background: var(--better-blue); } .workflow-progress__item--complete .workflow-progress__marker { - background: #2c5aa0; - border-color: #2c5aa0; + background: var(--better-blue); + border-color: var(--better-blue); color: #fff; } .workflow-progress__item--current { - color: #163f75; + color: var(--better-blue); } .workflow-progress__item--current .workflow-progress__marker { - border-color: #2c5aa0; + border-color: var(--better-blue); box-shadow: 0 0 0 4px rgb(44 90 160 / 14%); - color: #163f75; + color: var(--better-blue); } .workflow-card { background: #fff; - border: 1px solid #dce2ea; + border: 1px solid var(--border-default); border-radius: 16px; box-shadow: 0 12px 36px rgb(20 46 82 / 8%); margin: 0 auto; @@ -96,7 +96,7 @@ } .workflow-eyebrow { - color: #2c5aa0; + color: var(--better-blue); font-size: 0.82rem; font-weight: 750; letter-spacing: 0.08em; @@ -105,14 +105,13 @@ } .workflow-card h1 { - color: #172b46; font-size: clamp(1.8rem, 4vw, 2.5rem); letter-spacing: -0.025em; margin-bottom: 0.8rem; } .workflow-lede { - color: #536176; + color: var(--text-body); font-size: 1.05rem; line-height: 1.6; margin-bottom: 2rem; @@ -126,7 +125,7 @@ .choice-card { align-items: center; - border: 2px solid #d9e0e9; + border: 2px solid var(--border-default); border-radius: 12px; cursor: pointer; display: grid; @@ -137,8 +136,8 @@ } .choice-card:has(input:checked) { - background: #f0f6ff; - border-color: #2c5aa0; + background: var(--surface-accent); + border-color: var(--better-blue); box-shadow: 0 0 0 3px rgb(44 90 160 / 10%); } @@ -149,9 +148,9 @@ .choice-card__icon { align-items: center; - background: #eaf1fb; + background: var(--surface-accent); border-radius: 10px; - color: #2c5aa0; + color: var(--better-blue); display: flex; font-size: 1.15rem; height: 44px; @@ -165,17 +164,17 @@ } .choice-card strong { - color: #1d2f49; + color: var(--text-heading); margin-bottom: 0.2rem; } .choice-card small { - color: #647187; + color: var(--text-muted); } .workflow-actions { align-items: center; - border-top: 1px solid #e3e7ed; + border-top: 1px solid var(--border-subtle); display: flex; justify-content: space-between; margin-top: 2rem; @@ -189,7 +188,7 @@ } .requirements-strip { - background: #f5f7fa; + background: var(--surface-subtle); border-radius: 10px; display: flex; flex-wrap: wrap; @@ -199,19 +198,19 @@ } .requirements-strip span { - color: #48576c; + color: var(--text-body); font-size: 0.9rem; } .requirements-strip i { - color: #2c5aa0; + color: var(--better-blue); margin-right: 0.35rem; } .drop-zone { align-items: center; - background: #fbfcfe; - border: 2px dashed #9bacc2; + background: var(--surface-subtle); + border: 2px dashed var(--border-strong); border-radius: 14px; cursor: pointer; display: flex; @@ -225,8 +224,13 @@ .drop-zone--active, .drop-zone:hover { - background: #f0f6ff; - border-color: #2c5aa0; + background: var(--surface-accent); + border-color: var(--better-blue); +} + +.drop-zone:focus-within { + outline: 3px solid var(--better-blue); + outline-offset: 2px; } .drop-zone input { @@ -237,20 +241,20 @@ } .drop-zone__icon { - color: #2c5aa0; + color: var(--better-blue); font-size: 2.2rem; } .drop-zone span:last-child { - color: #687386; + color: var(--text-muted); font-size: 0.9rem; } .upload-state { align-items: center; - background: #eef5ff; + background: var(--surface-accent); border-radius: 10px; - color: #234d84; + color: var(--better-blue); display: grid; gap: 0.15rem 0.8rem; grid-template-columns: auto 1fr; @@ -259,7 +263,7 @@ } .upload-state span { - color: #526a88; + color: var(--text-body); font-size: 0.88rem; grid-column: 2; } @@ -276,7 +280,7 @@ } .document-list h2 { - color: #213957; + color: var(--text-heading); font-size: 1.15rem; font-weight: 700; margin: 0; @@ -284,7 +288,7 @@ .document-row { align-items: center; - border: 1px solid #dfe5ed; + border: 1px solid var(--border-default); border-radius: 10px; display: grid; gap: 0.8rem; @@ -294,7 +298,7 @@ } .document-row__icon { - color: #c53434; + color: var(--danger-icon); font-size: 1.4rem; } @@ -304,7 +308,7 @@ } .document-row__details small { - color: #687386; + color: var(--text-muted); } .status-pill { @@ -315,14 +319,19 @@ } .status-pill--ready { - background: #e5f6eb; - color: #16703a; + background: var(--success-surface); + color: var(--success-text); +} + +.status-pill--lead { + background: var(--surface-accent); + color: var(--better-blue); } .document-list__empty { - border: 1px solid #e1e6ed; + border: 1px solid var(--border-default); border-radius: 10px; - color: #788497; + color: var(--text-muted); padding: 1.5rem; text-align: center; } @@ -342,41 +351,41 @@ } .form-field>span { - color: #263c58; + color: var(--text-heading); display: block; font-weight: 700; margin-bottom: 0.35rem; } .form-field em { - color: #778397; + color: var(--text-muted); font-size: 0.8rem; font-style: normal; font-weight: 500; } .form-field small { - color: #758196; + color: var(--text-muted); display: block; margin-top: 0.3rem; } .review-field>span { - color: #263c58; + color: var(--text-heading); display: block; font-weight: 700; margin-bottom: 0.35rem; } .review-field em { - color: #778397; + color: var(--text-muted); font-size: 0.8rem; font-style: normal; font-weight: 500; } .review-field__hint { - color: #758196; + color: var(--text-muted); display: block; margin-top: 0.3rem; min-height: 1.1em; @@ -384,8 +393,8 @@ .review-field__display { align-items: center; - background: #f3faf5; - border: 1px solid #cde8d5; + background: var(--success-surface); + border: 1px solid var(--success-border); border-radius: 8px; display: flex; gap: 0.6rem; @@ -395,7 +404,7 @@ .review-field__found { align-items: center; - color: #16703a; + color: var(--success-text); display: flex; gap: 0.5rem; min-width: 0; @@ -406,7 +415,7 @@ } .review-field__found strong { - color: #1d2a3d; + color: var(--text-heading); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -420,8 +429,8 @@ } .path-confirmation { - background: #f7f9fc; - border: 1px solid #dfe5ed; + background: var(--surface-subtle); + border: 1px solid var(--border-default); border-radius: 12px; display: grid; gap: 0.7rem; @@ -430,7 +439,7 @@ } .path-confirmation legend { - color: #243a56; + color: var(--text-heading); float: none; font-size: 1rem; font-weight: 750; @@ -441,7 +450,7 @@ .path-confirmation>label { align-items: flex-start; background: #fff; - border: 1px solid #d8e0e9; + border: 1px solid var(--border-default); border-radius: 8px; display: flex; gap: 0.75rem; @@ -449,22 +458,22 @@ } .path-confirmation small { - color: #6d798d; + color: var(--text-muted); display: block; } .help-toggle { background: none; border: 0; - color: #2c5aa0; + color: var(--better-blue); font-weight: 650; justify-self: start; padding: 0.35rem 0; } .help-panel { - background: #fff8df; - border-left: 4px solid #e0ac2e; + background: var(--warning-surface); + border-left: 4px solid var(--warning-border); padding: 1rem; } @@ -479,9 +488,9 @@ .lookup-state { align-items: center; - background: #eef5ff; + background: var(--surface-accent); border-radius: 10px; - color: #234d84; + color: var(--better-blue); display: flex; gap: 0.8rem; margin-top: 1rem; @@ -494,7 +503,7 @@ } .lookup-state small { - color: #61748f; + color: var(--text-body); } .found-heading { @@ -505,9 +514,9 @@ .found-heading__icon { align-items: center; - background: #e2f5e9; + background: var(--success-surface); border-radius: 50%; - color: #18733d; + color: var(--success-text); display: flex; flex: 0 0 auto; height: 46px; @@ -517,7 +526,7 @@ } .case-summary { - border: 1px solid #dce3ec; + border: 1px solid var(--border-default); border-radius: 12px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); @@ -526,22 +535,22 @@ } .case-summary>div { - border-top: 1px solid #e3e8ef; + border-top: 1px solid var(--border-subtle); padding: 1rem 1.2rem; } .case-summary>div:nth-child(even):not(.case-summary__primary) { - border-left: 1px solid #e3e8ef; + border-left: 1px solid var(--border-subtle); } .case-summary__primary { - background: #f6f9fd; + background: var(--surface-subtle); border-top: 0 !important; grid-column: 1 / -1; } .case-summary dt { - color: #6b788c; + color: var(--text-muted); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.04em; @@ -550,7 +559,7 @@ } .case-summary dd { - color: #1c314d; + color: var(--text-heading); font-size: 1rem; font-weight: 650; margin: 0; @@ -565,21 +574,21 @@ } .confirmation-question strong { - color: #263c58; + color: var(--text-heading); font-size: 1.05rem; } .confirmation-question p { - color: #69768a; + color: var(--text-muted); margin: 0.25rem 0 0; } .checklist-guidance { align-items: flex-start; - background: #eef5ff; - border-left: 4px solid #3974ba; + background: var(--surface-accent); + border-left: 4px solid var(--better-blue); border-radius: 8px; - color: #294565; + color: var(--text-heading); display: flex; gap: 0.8rem; margin: 1.5rem 0; @@ -587,7 +596,7 @@ } .checklist-guidance i { - color: #3974ba; + color: var(--better-blue); margin-top: 0.2rem; } @@ -596,7 +605,7 @@ } .checklist-files { - border: 1px solid #dce3ec; + border: 1px solid var(--border-default); border-radius: 12px; overflow: hidden; } @@ -610,14 +619,14 @@ } .checklist-file+.checklist-file { - border-top: 1px solid #e4e9f0; + border-top: 1px solid var(--border-subtle); } .checklist-file__check { align-items: center; - background: #e2f5e9; + background: var(--success-surface); border-radius: 50%; - color: #18733d; + color: var(--success-text); display: flex; font-size: 0.7rem; height: 24px; @@ -626,28 +635,28 @@ } .checklist-file__icon { - color: #b23b3b; + color: var(--danger-icon); font-size: 1.35rem; } .checklist-file small, .checklist-confirmation small { - color: #6e7b8f; + color: var(--text-muted); display: block; } .add-missing-toggle { background: none; border: 0; - color: #2c5aa0; + color: var(--better-blue); font-weight: 700; margin: 1rem 0; padding: 0.4rem 0; } .missing-document-state { - background: #f7f9fc; - border: 1px dashed #bac7d6; + background: var(--surface-subtle); + border: 1px dashed var(--border-strong); border-radius: 10px; margin-bottom: 1.2rem; padding: 1.2rem; @@ -655,8 +664,8 @@ .checklist-confirmation { align-items: flex-start; - background: #fffaf0; - border: 1px solid #ead8ad; + background: var(--warning-surface); + border: 1px solid var(--warning-border); border-radius: 10px; display: flex; gap: 0.8rem; @@ -671,15 +680,15 @@ } .main-document-choice { - background: #f6f9fd; - border: 1px solid #dce3ec; + background: var(--surface-subtle); + border: 1px solid var(--border-default); border-radius: 12px; margin-top: 1.5rem; padding: 1rem; } .main-document-choice legend { - color: #263c58; + color: var(--text-heading); float: none; font-size: 1.05rem; font-weight: 750; @@ -688,24 +697,24 @@ } .main-document-choice>p { - color: #68768a; + color: var(--text-muted); margin: 0.25rem 0 0.8rem; } .main-document-choice small { - color: #6d798d; + color: var(--text-muted); display: block; } .organize-card { - border: 1px solid #dce3ec; + border: 1px solid var(--border-default); border-radius: 12px; overflow: hidden; } .organize-card__header { align-items: center; - background: #f6f9fd; + background: var(--surface-subtle); display: grid; gap: 0.8rem; grid-template-columns: auto 1fr auto; @@ -713,7 +722,7 @@ } .organize-card__icon { - color: #b23b3b; + color: var(--danger-icon); font-size: 1.4rem; } @@ -723,7 +732,7 @@ } .organize-card__position { - color: #66758a; + color: var(--text-muted); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.03em; @@ -743,12 +752,12 @@ } .certified-copy-details { - border-top: 1px solid #e3e8ef; + border-top: 1px solid var(--border-subtle); padding: 0.8rem 1rem 1rem; } .certified-copy-details summary { - color: #38567a; + color: var(--text-body); cursor: pointer; font-weight: 700; } @@ -760,11 +769,11 @@ } .optional-services-list small { - color: #758196; + color: var(--text-muted); } .optional-service-description { - color: #758196; + color: var(--text-muted); margin: -0.35rem 0 0.35rem 1.6rem; } @@ -777,7 +786,7 @@ } .compact-choice-field legend { - color: #263c58; + color: var(--text-heading); float: none; font-size: 1rem; font-weight: 700; @@ -792,8 +801,8 @@ .compact-choice-list label { align-items: center; - background: #f7f9fc; - border: 1px solid #dce3ec; + background: var(--surface-subtle); + border: 1px solid var(--border-default); border-radius: 8px; display: flex; gap: 0.65rem; @@ -805,20 +814,20 @@ } .people-section { - border-top: 1px solid #e3e8ef; + border-top: 1px solid var(--border-subtle); margin-top: 1.5rem; padding-top: 1.25rem; } .people-section h2, .party-roster h2 { - color: #263c58; + color: var(--text-heading); font-size: 1.05rem; margin-bottom: 1rem; } .people-section h2 em { - color: #778397; + color: var(--text-muted); font-size: 0.8rem; font-style: normal; font-weight: 500; @@ -840,8 +849,8 @@ .your-role-card { align-items: end; - background: #f6f9fd; - border: 1px solid #dce3ec; + background: var(--surface-subtle); + border: 1px solid var(--border-default); border-radius: 12px; display: grid; gap: 1rem; @@ -859,7 +868,7 @@ .your-role-card small, .party-row small { - color: #6d798d; + color: var(--text-muted); display: block; } @@ -878,9 +887,9 @@ .party-avatar { align-items: center; - background: #dfeaff; + background: var(--surface-accent); border-radius: 50%; - color: #285ea8; + color: var(--better-blue); display: flex; flex: 0 0 auto; height: 44px; @@ -908,7 +917,7 @@ } .party-row { - border: 1px solid #dce3ec; + border: 1px solid var(--border-default); border-radius: 10px; display: grid; grid-template-columns: auto 1fr auto auto auto; @@ -924,7 +933,7 @@ } .party-kind legend { - color: #263c58; + color: var(--text-heading); font-size: 0.9rem; font-weight: 700; grid-column: 1 / -1; @@ -933,8 +942,8 @@ } .party-kind label { - background: #f6f9fd; - border: 1px solid #dce3ec; + background: var(--surface-subtle); + border: 1px solid var(--border-default); border-radius: 8px; padding: 0.7rem 1rem; } @@ -946,13 +955,13 @@ } .question-card { - border: 1px solid #dce3ec; + border: 1px solid var(--border-default); border-radius: 12px; padding: 1.1rem; } .question-card legend { - color: #263c58; + color: var(--text-heading); float: none; font-size: 1rem; font-weight: 700; @@ -968,8 +977,8 @@ .question-options label { align-items: center; - background: #f6f9fd; - border: 1px solid #dce3ec; + background: var(--surface-subtle); + border: 1px solid var(--border-default); border-radius: 8px; display: flex; gap: 0.7rem; @@ -977,7 +986,7 @@ } .question-card__hint { - color: #758196; + color: var(--text-muted); font-size: 0.88rem; margin: -0.3rem 0 0.8rem; } diff --git a/efile_app/efile/static/css/review.css b/efile_app/efile/static/css/review.css index c36c520..842b280 100644 --- a/efile_app/efile/static/css/review.css +++ b/efile_app/efile/static/css/review.css @@ -1,338 +1,193 @@ -.review-container { - max-width: 600px; - margin: 0 auto; - padding: 1rem; -} - -.review-section { - background: var(--light-blue-background); - border-radius: 8px; - padding: 1.5rem; - margin-bottom: 1.5rem; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.review-section h3 { - color: var(--better-blue); - margin-bottom: 1rem; - font-size: 1.3rem; - font-weight: 600; -} - -.review-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.75rem 0; - border-bottom: 1px solid #e9ecef; -} - -.review-item input { - max-width: 400px; -} - -.review-item:last-child { - border-bottom: none; +.loading-spinner { + display: none; + text-align: center; + padding: 2rem; } -.review-label { - font-weight: 500; - color: #495057; - flex: 0 0 auto; +.payment-choice-field { + border: 0; + margin: 0; + padding: 0; } -.review-value { - flex: 1; - text-align: right; - color: #212529; - margin-left: 1rem; - word-break: break-word; +.payment-choice-field>legend, +.fee-summary h2 { + color: var(--text-heading); + float: none; + font-size: 1.05rem; + font-weight: 750; + margin-bottom: 0.8rem; + width: auto; } -.review-text { - overflow: hidden; - text-overflow: ellipsis; +.fee-summary { + background: var(--surface-accent); + border: 1px solid var(--border-accent); + border-radius: 12px; + margin-top: 1.25rem; + padding: 1.1rem; } -.review-item>.d-flex.align-items-center.w-100 { - justify-content: flex-end; - gap: 0.75rem; +.fee-summary ul { + margin: 0.75rem 0 0; } -.review-item input.form-control { - flex: 1 1 auto; - min-width: 0; +.review-workflow-card { + max-width: 980px; } -.review-item .edit-btn { - margin-left: 0.75rem; - flex: 0 0 auto; -} - -.edit-btn { - background: #45637d; - color: white; - border: none; - border-radius: 20px; - padding: 0.4rem 1rem; - font-size: 0.85rem; - text-decoration: none; - display: inline-block; - transition: background-color 0.3s; +.review-summary-grid { + display: grid; + gap: 1rem; + grid-template-columns: repeat(2, minmax(0, 1fr)); } -.edit-btn:hover { - background: #5a6268; - color: white; +.review-summary-card { + border: 1px solid var(--border-default); + border-radius: 12px; + padding: 1.1rem; } -.document-list { - background: white; - border: 1px solid #dee2e6; - border-radius: 6px; - padding: 1rem; - margin-top: 1rem; +.review-summary-card--wide { + grid-column: 1 / -1; } -.document-item { - display: flex; +.review-summary-card>header { align-items: center; - padding: 0.5rem 0; - border-bottom: 1px solid #e9ecef; -} - -.document-item:last-child { - border-bottom: none; -} - -.document-item i { - color: #dc3545; - margin-right: 0.5rem; - font-size: 1.2rem; + border-bottom: 1px solid var(--border-subtle); + display: flex; + justify-content: space-between; + margin-bottom: 0.9rem; + padding-bottom: 0.7rem; } -.document-name { - font-weight: 500; - width: 62%; - overflow: clip; +.review-summary-card h2 { + color: var(--text-heading); + font-size: 1.05rem; + margin: 0; } -.change-btn { - background: #6c757d; - color: white; - border: none; - border-radius: 20px; - padding: 0.3rem 0.8rem; - font-size: 0.8rem; - margin-left: auto; +.review-summary-card header a { + color: var(--better-blue); + font-size: 0.9rem; + font-weight: 700; } -.change-btn:hover { - background: #5a6268; - color: white; +.review-summary-card dl { + margin: 0; } -.action-buttons { - margin-top: 2rem; - display: flex; +.review-summary-card dl>div { + display: grid; gap: 1rem; - justify-content: center; -} - -.btn-continue { - background: var(--better-blue); - color: white; - border: none; - padding: 0.75rem 2rem; - border-radius: 6px; - font-weight: 600; - font-size: 1rem; -} - -.btn-continue:hover { - background: #1e3d6f; - color: white; + grid-template-columns: minmax(110px, 0.8fr) 1.5fr; + padding: 0.35rem 0; } -.btn-back { - background: #6c757d; - color: white; - border: none; - padding: 0.75rem 2rem; - border-radius: 6px; - font-weight: 600; - font-size: 1rem; -} - -.btn-back:hover { - background: #5a6268; - color: white; +.review-summary-card dt { + color: var(--text-muted); + font-size: 0.85rem; } -.payment-info { - background: #e3f2fd; - border: 1px solid #bbdefb; - border-radius: 6px; - padding: 1rem; - margin-top: 1rem; +.review-summary-card dd { + color: var(--text-heading); + font-weight: 650; + margin: 0; + text-align: right; } -.payment-item { - display: flex; - justify-content: space-between; +.review-document-list article { align-items: center; - padding: 0.25rem 0; -} - -.payment-total { - font-weight: bold; - font-size: 1.1rem; - border-top: 1px solid #90caf9; - padding-top: 0.5rem; - margin-top: 0.5rem; -} - -.loading-spinner { - display: none; - text-align: center; - padding: 2rem; -} - -.error-message { - display: none; - background: #f8d7da; - color: #721c24; - border: 1px solid #f5c6cb; - border-radius: 6px; - padding: 1rem; - margin-bottom: 1rem; + display: flex; + gap: 0.8rem; + padding: 0.65rem 0; } -.success-message { - display: none; - background: #d4edda; - color: #155724; - border: 1px solid #c3e6cb; - border-radius: 6px; - padding: 1rem; - margin-bottom: 1rem; +.review-document-list article+article { + border-top: 1px solid var(--border-subtle); } -/* Payment methods styles moved from review.html */ -.payment-methods-list { - border: 1px solid #e0e0e0; - border-radius: 8px; - overflow: hidden; - width: 100%; +.review-document-list i { + color: var(--danger-icon); + font-size: 1.3rem; } -.payment-method-item { - border-bottom: 1px solid #e0e0e0; - padding: 0; - width: 100%; - box-sizing: border-box; +.review-document-list strong, +.review-document-list small, +.review-party strong, +.review-party small { + display: block; } -.payment-method-item:last-child { - border-bottom: none; +.review-document-list small, +.review-party small { + color: var(--text-muted); } -.payment-method-item .form-check { - margin: 0; - padding: 16px 20px; - display: flex; - align-items: center; - gap: 16px; - width: 100%; - box-sizing: border-box; - min-height: 60px; +.review-person-name { + color: var(--text-heading); + font-weight: 700; + margin-bottom: 0.35rem; } -.payment-method-item .form-check-input { - margin: 0 !important; - margin-left: 0 !important; - margin-right: 0 !important; - flex: 0 0 20px; - width: 20px; - height: 20px; - position: static; +.review-document-tag { + background: var(--surface-accent); + border-radius: 999px; + color: var(--text-body); + display: inline-block; + font-size: 0.78rem; + font-weight: 650; + margin-top: 0.3rem; + padding: 0.15rem 0.55rem; } -.payment-method-details { - display: flex; - flex-direction: row; - align-items: center; - gap: 12px; - flex: 1 1 auto; - min-width: 0; - overflow: hidden; +.review-fee-breakdown { + color: var(--text-muted); + font-size: 0.85rem; + list-style: none; + margin: 0.3rem 0 0; + padding: 0; } -.payment-method-info { +.review-fee-breakdown li { display: flex; - align-items: center; - color: #666; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - gap: 8px; -} - -.payment-method-info i { - margin: 0; - width: 28px; - text-align: center; - color: var(--better-blue); - font-size: 1.1rem; -} - -.payment-method-name { - font-weight: 600; - color: var(--better-blue); - margin-bottom: 0; -} - -.payment-method-holder { - font-size: 0.9rem; - color: #888; + justify-content: space-between; + padding: 0.15rem 0; } -.payment-method-item:hover { - background-color: var(--light-blue-background); +.review-summary-card address { + color: var(--text-body); + line-height: 1.55; } -.no-payment-methods { - text-align: center; - padding: 2rem; +.review-party { + padding: 0.45rem 0; } -.add-payment-method { - text-align: center; +.review-party+.review-party { + border-top: 1px solid var(--border-subtle); } -/* Disclaimer section styling */ -.disclaimer-section { - background: #fff3cd; - border: 1px solid #ffeaa7; - border-radius: 6px; +.review-attestation { + background: var(--warning-surface); + border: 1px solid var(--warning-border); + border-radius: 10px; + margin-top: 1.5rem; padding: 1rem; - margin-top: 2rem; } -.disclaimer-section .form-check-label { - font-size: 0.95rem; - line-height: 1.4; - color: #856404; +.review-attestation label { + align-items: flex-start; + display: flex; + gap: 0.75rem; } -.disclaimer-section .form-check-input { - margin-top: 0.25rem; -} +@media (max-width: 700px) { + .review-summary-grid { + grid-template-columns: 1fr; + } -/* Disabled button styling */ -.btn-continue:disabled { - background: #6c757d !important; - border-color: #6c757d !important; - cursor: not-allowed; - opacity: 0.65; + .review-summary-card--wide { + grid-column: auto; + } } \ No newline at end of file diff --git a/efile_app/efile/static/css/upload.css b/efile_app/efile/static/css/upload.css index 6142255..ba6837e 100644 --- a/efile_app/efile/static/css/upload.css +++ b/efile_app/efile/static/css/upload.css @@ -307,7 +307,7 @@ } .btn-primary:hover { - background-color: #0056b3; + background-color: var(--brand-blue-hover); color: white; } diff --git a/efile_app/efile/static/js/extraction-review.js b/efile_app/efile/static/js/extraction-review.js index cad2c81..e6158ff 100644 --- a/efile_app/efile/static/js/extraction-review.js +++ b/efile_app/efile/static/js/extraction-review.js @@ -40,7 +40,12 @@ field.input = root.querySelector(".review-field__input"); field.valueEl = root.querySelector(".review-field__value"); field.hint = root.querySelector(".review-field__hint"); - root.querySelector(".review-field__edit").addEventListener("click", () => setMode(key, "edit")); + root.querySelector(".review-field__edit").addEventListener("click", () => { + setMode(key, "edit"); + // The Edit button lives inside the display panel that setMode just + // hid, so without this the click would strand focus on
. + field.select.focus(); + }); }); function setMode(key, mode) { @@ -126,8 +131,8 @@ await ADVANCE[key](); } else { field.hint.textContent = guesses[field.guessKey] ? - "We found a hint in your document, but couldn't match it to an exact choice below." : - "We couldn't find this in your document."; + "We found a hint in your document, but we could not match it to a choice below." : + "We could not find this in your document."; setMode(key, "edit"); } } diff --git a/efile_app/efile/static/js/filing-payload.js b/efile_app/efile/static/js/filing-payload.js index 2b81443..bbfe9ec 100644 --- a/efile_app/efile/static/js/filing-payload.js +++ b/efile_app/efile/static/js/filing-payload.js @@ -32,13 +32,56 @@ function componentCode(value) { } const FilingPayload = { + userDataFromCaseData(caseData) { + const filer = (caseData.filing_parties || []).find((party) => party.role === "filer") || {}; + const fullName = [filer.first_name, filer.middle_name, filer.last_name] + .filter(Boolean) + .join(" ") || [caseData.petitioner_first_name, caseData.petitioner_last_name].filter(Boolean).join(" "); + return { + fullName, + address: filer.address_line_1 || caseData.petitioner_address || "", + addressLine2: filer.address_line_2 || "", + city: filer.city || "", + state: filer.state || "", + zip: filer.zip_code || "", + email: filer.email || caseData.petitioner_email || "", + phone: filer.phone || caseData.petitioner_phone || "" + }; + }, + + partyFromDraft(party) { + return { + party_type: party.party_type, + name: { + first: party.first_name || party.organization_name || "", + middle: party.middle_name || "", + last: party.last_name || "", + suffix: party.suffix || "" + }, + address: { + address: party.address_line_1 || "", + unit: party.address_line_2 || "", + city: party.city || "", + state: party.state || "", + zip: party.zip_code || "", + country: party.country || "US" + }, + email: party.email || "", + phone_number: party.phone || "", + is_new: !party.external_party_id + }; + }, + buildEFilingData(userData, caseData, uploadData, paymentAccountID) { const nameParts = userData.fullName.split(" "); const firstName = nameParts[0] || ""; const lastName = nameParts.length > 1 ? nameParts[nameParts.length - 1] : ""; const middleName = nameParts.length > 2 ? nameParts.slice(1, -1).join(" ") : ""; - const partyType = caseData.determined_party_type || caseData.petitioner_party_type || caseData.party_type; + const durableParties = caseData.filing_parties || []; + const durableFiler = durableParties.find((party) => party.role === "filer"); + const partyType = durableFiler?.party_type || caseData.determined_party_type || + caseData.petitioner_party_type || caseData.party_type; if (!partyType) { throw new Error('Party type could not be determined. This is required for eFiling.'); @@ -102,9 +145,11 @@ const FilingPayload = { }); } - let other_parties = []; + let other_parties = durableParties + .filter((party) => party.role !== "filer" && party.party_type) + .map((party) => this.partyFromDraft(party)); - if (caseData.other_first_name && caseData.other_party_type) { + if (other_parties.length === 0 && caseData.other_first_name && caseData.other_party_type) { other_parties.push({ party_type: caseData.other_party_type, name: { @@ -137,6 +182,12 @@ const FilingPayload = { al_court_bundle: [], comments_to_clerk: "", tyler_payment_id: paymentAccountID, + // Only sent when a chosen filing type requires it (case_questions + // asks for it in that case); the EFSP rejects the filing outright + // if it's required and missing, so leave it out rather than send 0. + ...(caseData?.amount_in_controversy ? { + amount_in_controversy: caseData.amount_in_controversy + } : {}), lead_contact: { name: { first: firstName, @@ -199,11 +250,7 @@ const FilingPayload = { }, createDocumentBundle(doc, filingType, documentType, filingComponent, users, description, docDescription, cc_email) { - if (cc_email) { - courtesy_copies = [cc_email] - } else { - courtesy_copies = [] - } + const courtesy_copies = cc_email ? [cc_email] : []; return { proxy_enabled: true, filing_type: filingType, @@ -215,7 +262,7 @@ const FilingPayload = { filing_comment: "", courtesy_copies: courtesy_copies, preliminary_copies: [], - filing_parties: users.length === 1 ? ["users[0]"] : ["users[0]", "users[1]"], + filing_parties: users.map((_user, index) => `users[${index}]`), filing_action: "efile", tyler_merge_attachments: false, document_type: documentType, @@ -241,20 +288,25 @@ const FilingPayload = { handleFeesResponse(result) { if (result?.success) { - let htmlStr = ` - Total: $${result.api_response.feesCalculationAmount.value} - -{% translate "Check the details before adding this filing to the case." %}
+{% translate "Check the details before you add this filing to the case." %}
{% translate "Choosing Yes will attach your documents to this case." %}
+{% translate "If you choose Yes, we will attach your documents to this case." %}