mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-08 04:15:43 +00:00
fix: support widget peak and onboarding wizard responsivness
This commit is contained in:
@@ -883,6 +883,9 @@ export function AppLayout({
|
|||||||
<AppShell.Main
|
<AppShell.Main
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "##f8fafc",
|
backgroundColor: "##f8fafc",
|
||||||
|
// Extra bottom clearance so the fixed support-chat FAB never
|
||||||
|
// overlaps page content, even at the bottom of a scrolled page.
|
||||||
|
paddingBottom: 112,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Title,
|
Title,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
|
import { useMediaQuery } from "@mantine/hooks";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
ArrowRight,
|
ArrowRight,
|
||||||
@@ -127,6 +128,7 @@ export default function OnboardingWizardDialog({
|
|||||||
}: OnboardingWizardDialogProps) {
|
}: OnboardingWizardDialogProps) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { user, company, onboardingStep, onboardingCompleted } = useAuth();
|
const { user, company, onboardingStep, onboardingCompleted } = useAuth();
|
||||||
|
const isMobile = useMediaQuery("(max-width: 48em)");
|
||||||
|
|
||||||
const existingProfiles = company?.company?.companyProfiles ?? [];
|
const existingProfiles = company?.company?.companyProfiles ?? [];
|
||||||
const companyAlreadyStarted = Boolean(company?.company?.id);
|
const companyAlreadyStarted = Boolean(company?.company?.id);
|
||||||
@@ -409,7 +411,9 @@ export default function OnboardingWizardDialog({
|
|||||||
ceiling = Math.min(ceiling, FORM_STEPS.indexOf("documents"));
|
ceiling = Math.min(ceiling, FORM_STEPS.indexOf("documents"));
|
||||||
if (poaIncomplete) ceiling = Math.min(ceiling, FORM_STEPS.indexOf("poa"));
|
if (poaIncomplete) ceiling = Math.min(ceiling, FORM_STEPS.indexOf("poa"));
|
||||||
const effectiveResumeStep: FormStep =
|
const effectiveResumeStep: FormStep =
|
||||||
FORM_STEPS[Math.min(Math.max(FORM_STEPS.indexOf(resumeFormStep), 0), ceiling)];
|
FORM_STEPS[
|
||||||
|
Math.min(Math.max(FORM_STEPS.indexOf(resumeFormStep), 0), ceiling)
|
||||||
|
];
|
||||||
|
|
||||||
const formProps = {
|
const formProps = {
|
||||||
documentSettingCode: resolvedDocumentSettingCode,
|
documentSettingCode: resolvedDocumentSettingCode,
|
||||||
@@ -450,9 +454,10 @@ export default function OnboardingWizardDialog({
|
|||||||
withCloseButton={!completed}
|
withCloseButton={!completed}
|
||||||
closeOnClickOutside={false}
|
closeOnClickOutside={false}
|
||||||
closeOnEscape={!completed}
|
closeOnEscape={!completed}
|
||||||
|
fullScreen={isMobile}
|
||||||
size={1440}
|
size={1440}
|
||||||
radius="lg"
|
radius="lg"
|
||||||
padding="xl"
|
padding={isMobile ? "md" : "xl"}
|
||||||
centered
|
centered
|
||||||
keepMounted
|
keepMounted
|
||||||
scrollAreaComponent={ScrollArea.Autosize}
|
scrollAreaComponent={ScrollArea.Autosize}
|
||||||
@@ -464,6 +469,9 @@ export default function OnboardingWizardDialog({
|
|||||||
title: {
|
title: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
|
body: isMobile
|
||||||
|
? { paddingBottom: "calc(100px + env(safe-area-inset-bottom))" }
|
||||||
|
: undefined,
|
||||||
}}
|
}}
|
||||||
title={
|
title={
|
||||||
completed ? null : (
|
completed ? null : (
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function SupportWidget() {
|
|||||||
if (!isAuthenticated) return null;
|
if (!isAuthenticated) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Affix position={{ bottom: 24, right: 24 }} zIndex={300}>
|
<Affix position={{ bottom: 24, right: 24 }} zIndex={300} className="group">
|
||||||
<Transition mounted={open} transition="pop-bottom-right" duration={200}>
|
<Transition mounted={open} transition="pop-bottom-right" duration={200}>
|
||||||
{(styles) => (
|
{(styles) => (
|
||||||
<div style={styles} className="mb-3">
|
<div style={styles} className="mb-3">
|
||||||
@@ -53,40 +53,44 @@ export function SupportWidget() {
|
|||||||
<Transition mounted={!open} transition="pop" duration={150}>
|
<Transition mounted={!open} transition="pop" duration={150}>
|
||||||
{(styles) => (
|
{(styles) => (
|
||||||
<div style={styles} className="flex justify-end">
|
<div style={styles} className="flex justify-end">
|
||||||
<Indicator
|
{/* Icon+label stay recognizable at rest, just tucked down a bit;
|
||||||
label={unread > 9 ? "9+" : unread}
|
lifts fully into place on hover/focus. */}
|
||||||
size={20}
|
<div className="translate-y-[60%] transition-transform duration-300 ease-out group-hover:translate-y-0 focus-within:translate-y-0 motion-reduce:translate-y-0">
|
||||||
offset={8}
|
<Indicator
|
||||||
color="red"
|
label={unread > 9 ? "9+" : unread}
|
||||||
disabled={unread === 0}
|
size={20}
|
||||||
processing
|
offset={8}
|
||||||
withBorder
|
color="red"
|
||||||
>
|
disabled={unread === 0}
|
||||||
<button
|
processing
|
||||||
type="button"
|
withBorder
|
||||||
aria-label="Open support chat"
|
|
||||||
onClick={() => setOpen(true)}
|
|
||||||
className="group relative flex cursor-pointer items-center gap-2.5 rounded-full bg-linear-135 from-edr-primary-dark to-edr-primary py-2 pr-2 pl-2 text-white shadow-[0_10px_28px_rgba(13,92,44,0.4)] transition-transform duration-150 hover:-translate-y-0.5 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-edr-primary active:translate-y-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 sm:pr-5"
|
|
||||||
>
|
>
|
||||||
{/* Faint breathing ring; the unread badge already pulses, so stand down then. */}
|
<button
|
||||||
{unread === 0 && (
|
type="button"
|
||||||
<span className="pointer-events-none absolute -inset-1 animate-pulse rounded-full ring-2 ring-edr-primary/50 motion-reduce:animate-none" />
|
aria-label="Open support chat"
|
||||||
)}
|
onClick={() => setOpen(true)}
|
||||||
|
className="group relative flex cursor-pointer items-center gap-2.5 rounded-full bg-linear-135 from-edr-primary-dark to-edr-primary py-2 pr-2 pl-2 text-white shadow-[0_10px_28px_rgba(13,92,44,0.4)] transition-transform duration-150 hover:-translate-y-0.5 focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-edr-primary active:translate-y-0 motion-reduce:transition-none motion-reduce:hover:translate-y-0 sm:pr-5"
|
||||||
|
>
|
||||||
|
{/* Faint breathing ring; the unread badge already pulses, so stand down then. */}
|
||||||
|
{unread === 0 && (
|
||||||
|
<span className="pointer-events-none absolute -inset-1 animate-pulse rounded-full ring-2 ring-edr-primary/50 motion-reduce:animate-none" />
|
||||||
|
)}
|
||||||
|
|
||||||
<span className="relative grid size-[42px] shrink-0 place-items-center rounded-full bg-white/20">
|
<span className="relative grid size-[42px] shrink-0 place-items-center rounded-full bg-white/20">
|
||||||
<Headset size={22} />
|
<Headset size={22} />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span className="relative hidden text-left leading-tight sm:block">
|
<span className="relative hidden text-left leading-tight sm:block">
|
||||||
<span className="block text-sm font-semibold whitespace-nowrap">
|
<span className="block text-sm font-semibold whitespace-nowrap">
|
||||||
👋 Need help?
|
👋 Need help?
|
||||||
|
</span>
|
||||||
|
<span className="block text-[11px] whitespace-nowrap opacity-85">
|
||||||
|
Chat with our team
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span className="block text-[11px] whitespace-nowrap opacity-85">
|
</button>
|
||||||
Chat with our team
|
</Indicator>
|
||||||
</span>
|
</div>
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</Indicator>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Transition>
|
</Transition>
|
||||||
|
|||||||
Reference in New Issue
Block a user