Skip to content

Navigating to the app admin page inconsistent (not awaiting till page loads properly? ) #950

Open
@ninode97

Description

@ninode97

Problem

I am experiencing some re-rendering issues and unsure what could be causing this.

When I visit settings page (It load shops configuration from server), not sure why it for a moment of time renders previously active page, and then immediately it renders the page it should... (Attaching video below).

Screen.Recording.2025-01-31.at.11.37.15.mov

The settings page:

export const loader = async ({ request }: LoaderFunctionArgs) => {
  const data = await authenticate.admin(request);
  const config = await prisma.config.findFirst({
    where: {
      shop: data.session.shop,
    },
  });
  return {
    brandColor: config?.brandColor,
    iconColor: config?.iconColor,
    icon: config?.icon,
  };
};

export const action = async ({ request }: ActionFunctionArgs) => {
  const formData = await request.clone().formData();
  const { session } = await authenticate.admin(request);
  const brandColor = formData.get("brandColor") as string;
  const iconColor = formData.get("iconColor") as string;
  const icon = formData.get("icon") as string;

  try {
    const config = await prisma.config.findFirst({
      where: { shop: session.shop },
    });
    if (!config) {
      throw new Error(`Config not found....`);
    }
    await prisma.config.update({
      where: { id: config.id },
      data: {
        brandColor,
        iconColor,
        icon,
      },
    });
    const result = {
      success: true,
      message: "Settings saved!",
    };
    return result;
  } catch (error) {
    const result = {
      success: false,
      message: "Error saving settings.",
    };
    console.error(result.message, error);
    return result;
  }
};

export default function SettingsPage() {
  const fetcher = useFetcher<typeof action>();

  useEffect(() => {
    if (fetcher.state !== "idle" || !fetcher.data) return;

    shopify.toast.show(fetcher.data.message, {
      duration: 2500,
      isError: !fetcher.data.success,
    });
  }, [fetcher.data, fetcher.state]);

  const settingsData = useLoaderData<typeof loader>();

  const [brandColor, setBrandColor] = useState<string>(
    settingsData.brandColor || "#111",
  );
  const [iconColor, setIconColor] = useState<string>(
    settingsData.iconColor || "#111",
  );
  const [iconStyle, setIconStyle] = useState<AvailableIcons>(
    (settingsData.icon as AvailableIcons) || "star2",
  );
  const wasChanged = useMemo(() => {
    return (
      settingsData.brandColor !== brandColor ||
      iconColor !== settingsData.iconColor ||
      iconStyle !== settingsData.icon
    );
  }, [
    brandColor,
    iconColor,
    iconStyle,
    settingsData.brandColor,
    settingsData.icon,
    settingsData.iconColor,
  ]);

  const handleClick = async () => {
    if (fetcher.state === "submitting") return;
    fetcher.submit(
      { icon: iconStyle, iconColor, brandColor }, // Data to send
      { method: "post" }, // Default is the current route's action
    );
  };

  return (
    <Suspense fallback="Loading...">
      <Page>
        <TitleBar title="Settings" />
        <Layout>
          <Layout.Section>
            <Card>
              <Text variant="headingSm" as="h2">
                Theme Settings
              </Text>
              <div className="mb-5"></div>
              <FormLayout>
                <Box
                  borderColor="border"
                  borderWidth="0165"
                  padding="150"
                  borderRadius="300"
                >
                  <InlineGrid gap="400" columns={3}>
                    <PopoverColorPicker
                      hexColor={brandColor}
                      setHexColor={setBrandColor}
                      label="Branding Color"
                    />
                    <PopoverColorPicker
                      hexColor={iconColor}
                      setHexColor={setIconColor}
                      label="Icon Color"
                    />
                  </InlineGrid>

                  <InlineGrid gap="100" columns={3}>
                    <PopoverReviewIconPicker
                      label={"Icon Style"}
                      icon={iconStyle}
                      setIcon={setIconStyle}
                      fill={iconColor}
                    />
                  </InlineGrid>
                </Box>
              </FormLayout>
            </Card>
            <PageActions
              primaryAction={{
                content: "Save",
                loading: fetcher.state === "submitting",
                disabled: !wasChanged,
                onAction: handleClick,
              }}
            />
          </Layout.Section>
        </Layout>
      </Page>
    </Suspense>
  );
}

What could be causing such behaviour for Settings Page ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions