diff --git a/src/pages/dashboard.tsx b/src/pages/dashboard.tsx
new file mode 100644
index 0000000..4d91226
--- /dev/null
+++ b/src/pages/dashboard.tsx
@@ -0,0 +1,267 @@
+import { useAppBridge } from "@saleor/app-sdk/app-bridge";
+import {
+ Box,
+ Text,
+ Button,
+ Chip,
+ Divider,
+ List,
+ ListItem,
+ ListItemText,
+ CircularProgress,
+ Alert,
+ Accordion,
+ AccordionSummary,
+ AccordionDetails,
+} from "@saleor/macaw-ui";
+import { NextPage } from "next";
+import { useEffect, useState } from "react";
+
+interface WebhookStatus {
+ name: string;
+ event: string;
+ active: boolean;
+ targetUrl: string;
+}
+
+interface AppInfo {
+ name: string;
+ version: string;
+ id: string;
+}
+
+const DashboardPage: NextPage = () => {
+ const { appBridgeState } = useAppBridge();
+ const [mounted, setMounted] = useState(false);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ setMounted(true);
+ // Simulate loading app data
+ setTimeout(() => setLoading(false), 1000);
+ }, []);
+
+ const webhooks: WebhookStatus[] = [
+ {
+ name: "Order Created",
+ event: "ORDER_CREATED",
+ active: true,
+ targetUrl: "N8N Workflow",
+ },
+ {
+ name: "Order Fulfilled",
+ event: "ORDER_FULFILLED",
+ active: true,
+ targetUrl: "N8N Workflow",
+ },
+ {
+ name: "Order Cancelled",
+ event: "ORDER_CANCELLED",
+ active: true,
+ targetUrl: "N8N Workflow",
+ },
+ ];
+
+ const appInfo: AppInfo = {
+ name: "Core Extensions",
+ version: "1.0.0",
+ id: "saleor-core-extensions",
+ };
+
+ if (!mounted) {
+ return (
+
+
+
+ );
+ }
+
+ if (loading) {
+ return (
+
+
+
+ Loading dashboard...
+
+
+ );
+ }
+
+ return (
+
+ {/* Header */}
+
+
+ Core Extensions Dashboard
+
+
+ Email automation for ManoonOils
+
+
+
+ {/* Connection Status */}
+
+
+ Connection Status
+
+ {appBridgeState?.ready ? (
+
+
+
+ Connected
+
+ Connected to Saleor Dashboard
+
+
+ ) : (
+
+
+
+ Standalone
+
+ Running outside Saleor Dashboard
+
+
+ )}
+
+
+
+
+ {/* Webhooks Section */}
+
+
+ Webhooks Configuration
+
+
+ Active webhooks forwarding to N8N
+
+
+
+ {webhooks.map((webhook) => (
+
+
+
+
+
+ {webhook.targetUrl}
+
+
+ {webhook.active ? "Active" : "Inactive"}
+
+
+
+
+ ))}
+
+
+
+
+
+ {/* Email Configuration */}
+
+
+ Email Configuration
+
+
+
+
+ Customer Emails
+
+
+
+
+ From:
+ support@mail.manoonoils.com
+
+
+ Provider:
+ Resend
+
+
+ Templates:
+ Order Confirmation, Order Shipped, Order Cancelled
+
+
+
+
+
+
+
+ Admin Notifications
+
+
+
+
+ Recipients:
+ me@hytham.me, tamara@hytham.me
+
+
+ Subject:
+ New Order! 🎉 #{orderNumber}
+
+
+ Trigger:
+ All order events
+
+
+
+
+
+
+
+
+ {/* App Info */}
+
+
+ App Information
+
+
+
+ Name:
+ {appInfo.name}
+
+
+ Version:
+ {appInfo.version}
+
+
+ ID:
+ {appInfo.id}
+
+
+
+
+
+
+ {/* Actions */}
+
+
+
+
+
+ );
+};
+
+export default DashboardPage;
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 35f60b4..6e1ef60 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,206 +1,96 @@
-import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
-import { Box, Button, Input, Text } from "@saleor/macaw-ui";
+import { useAppBridge } from "@saleor/app-sdk/app-bridge";
+import { Box, Text, Button, CircularProgress } from "@saleor/macaw-ui";
import { NextPage } from "next";
-import Link from "next/link";
-import { MouseEventHandler, useEffect, useState } from "react";
+import { useEffect, useState } from "react";
+import { useRouter } from "next/router";
-const AddToSaleorForm = () => (
- {
- event.preventDefault();
-
- const saleorUrl = new FormData(event.currentTarget as HTMLFormElement).get("saleor-url");
- const manifestUrl = new URL("/api/manifest", window.location.origin);
- const redirectUrl = new URL(
- `/dashboard/apps/install?manifestUrl=${manifestUrl}`,
- saleorUrl as string
- ).href;
-
- window.open(redirectUrl, "_blank");
- }}
- >
-
-
-
-);
-
-/**
- * This is page publicly accessible from your app.
- * You should probably remove it.
- */
const IndexPage: NextPage = () => {
- const { appBridgeState, appBridge } = useAppBridge();
+ const { appBridgeState } = useAppBridge();
+ const router = useRouter();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
- const handleLinkClick: MouseEventHandler = (e) => {
- /**
- * In iframe, link can't be opened in new tab, so Dashboard must be a proxy
- */
+ useEffect(() => {
+ // If inside Saleor Dashboard, redirect to dashboard
if (appBridgeState?.ready) {
- e.preventDefault();
-
- appBridge?.dispatch(
- actions.Redirect({
- newContext: true,
- to: e.currentTarget.href,
- })
- );
+ router.push("/dashboard");
}
+ }, [appBridgeState?.ready, router]);
- /**
- * Otherwise, assume app is accessed outside of Dashboard, so href attribute on will work
- */
- };
+ if (!mounted) {
+ return (
+
+
+
+ );
+ }
- const isLocalHost = global.location.href.includes("localhost");
+ // If inside Saleor Dashboard, show loading while redirecting
+ if (appBridgeState?.ready) {
+ return (
+
+
+
+ );
+ }
+ // Standalone landing page
return (
-
- Welcome to Saleor App Template (Next.js) 🚀
-
- Saleor App Template is a minimalistic boilerplate that provides a working example of a
- Saleor app.
+
+
+ Core Extensions
- {appBridgeState?.ready && mounted && (
-
-
-
- )}
-
-
- Explore the App Template by visiting:
+
+ Email automation for ManoonOils
-
- -
-
/src/pages/api/manifest - the{" "}
-
- App Manifest
-
- .
-
- -
-
/src/pages/api/webhooks/order-created - an example ORDER_CREATED{" "}
- webhook handler.
-
- -
-
/graphql - the pre-defined GraphQL queries.
-
- -
-
/generated/graphql.ts - the code generated for those queries by{" "}
-
- GraphQL Code Generator
-
- .
-
-
-
- Resources
-
-
+
+
+ This app connects Saleor to N8N for automated email workflows using Resend.
+
- {mounted && !isLocalHost && !appBridgeState?.ready && (
- <>
-
- Install this app in your Dashboard and get extra powers!
-
-
- >
- )}
+
+
+
+
+
+
);
};