@alpaca-editor/core 1.0.3908 → 1.0.3912

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,6 +9,7 @@ import { ItemDescriptor } from "../editor/pageModel";
9
9
  import { Card } from "../components/ui/card";
10
10
  import { Logo, MagicEditIcon } from "../editor/ui/Icons";
11
11
  import { ActionButton } from "../components/ActionButton";
12
+ import { RecentPages } from "./RecentPages";
12
13
 
13
14
  export function OpenPage() {
14
15
  const savedHistory =
@@ -22,17 +23,8 @@ export function OpenPage() {
22
23
  ? JSON.parse(savedHistory)
23
24
  : [];
24
25
 
25
- const [history, setHistory] = useState<HistoryEntry[]>();
26
26
  const [isLoading, setIsLoading] = useState(false);
27
27
 
28
- useEffect(() => {
29
- const fetchItems = async () => {
30
- const pages = await editContext?.itemsRepository.getItems(recentPages);
31
- setHistory(pages);
32
- };
33
- fetchItems();
34
- }, [editContext?.itemsRepository]);
35
-
36
28
  useEffect(() => {
37
29
  if (recentPages.length > 0 && recentPages[0])
38
30
  setSelectedPage(recentPages[0]);
@@ -106,32 +98,7 @@ export function OpenPage() {
106
98
  </Card>
107
99
  </div>
108
100
  <div className="flex-1 md:pl-4">
109
- <Card
110
- icon={<i className="pi pi-history text-sm"></i>}
111
- title="Recent Pages"
112
- description="Quick access to your recently viewed pages"
113
- noPadding
114
- className="h-full"
115
- >
116
- <div className="relative h-full">
117
- <ul className="absolute inset-0 overflow-auto p-4 pt-0 md:p-6">
118
- {history?.map((page, index) => (
119
- <li
120
- key={index}
121
- onMouseOver={() => setSelectedPage(page)}
122
- onClick={() => loadItem(page)}
123
- className="flex cursor-pointer items-center gap-2 rounded p-1.5 text-xs hover:bg-gray-100"
124
- >
125
- {page.icon && (
126
- <img src={page.icon} width="16" height="16" />
127
- )}{" "}
128
- {page.name}{" "}
129
- <span className="text-gray-500">({page.language})</span>
130
- </li>
131
- ))}
132
- </ul>
133
- </div>
134
- </Card>
101
+ <RecentPages />
135
102
  </div>
136
103
  </div>
137
104
  </div>
@@ -0,0 +1,123 @@
1
+ "use client";
2
+
3
+ import { useState, useEffect } from "react";
4
+ import { HistoryEntry } from "../types";
5
+ import { useEditContext } from "../editor/client/editContext";
6
+ import { ItemDescriptor, FullItem } from "../editor/pageModel";
7
+ import { Card } from "../components/ui/card";
8
+
9
+ export function RecentPages() {
10
+ const savedHistory =
11
+ typeof window !== "undefined"
12
+ ? localStorage.getItem("editor.browseHistory")
13
+ : null;
14
+
15
+ const editContext = useEditContext();
16
+ const recentPages: HistoryEntry[] = savedHistory
17
+ ? JSON.parse(savedHistory)
18
+ : [];
19
+
20
+ const [history, setHistory] = useState<FullItem[]>();
21
+ const [selectedPage, setSelectedPage] = useState<HistoryEntry | null>(null);
22
+
23
+ useEffect(() => {
24
+ const fetchItems = async () => {
25
+ const pages = await editContext?.itemsRepository.getItems(recentPages);
26
+ setHistory(pages);
27
+ };
28
+ fetchItems();
29
+ }, [editContext?.itemsRepository]);
30
+
31
+ const handlePageSelect = (page: HistoryEntry) => {
32
+ setSelectedPage(page);
33
+ };
34
+
35
+ const handlePageLoad = (item: ItemDescriptor) => {
36
+ if (editContext) {
37
+ editContext
38
+ .loadItem({
39
+ id: item.id,
40
+ language: item.language ?? "en",
41
+ version: item.version,
42
+ })
43
+ .then(() => {
44
+ // Switch to the appropriate editor view after loading
45
+ editContext.switchView(
46
+ editContext.contentEditorItem?.hasLayout
47
+ ? "page-editor"
48
+ : "content-editor",
49
+ );
50
+ });
51
+ }
52
+ };
53
+
54
+ const formatDate = (date?: Date | string) => {
55
+ if (!date) return "—";
56
+ const d = new Date(date);
57
+ return d.toLocaleDateString();
58
+ };
59
+
60
+ return (
61
+ <Card
62
+ icon={<i className="pi pi-history text-sm"></i>}
63
+ title="Recent Pages"
64
+ description="Quick access to your recently viewed pages"
65
+ className="flex h-full flex-col"
66
+ >
67
+ <div className="relative flex min-h-0 flex-1 flex-col">
68
+ <div className="absolute inset-0 overflow-auto">
69
+ <table className="w-full text-xs">
70
+ <tbody>
71
+ {history?.map((page, index) => (
72
+ <tr
73
+ key={page.id || index}
74
+ onMouseOver={() => handlePageSelect(page)}
75
+ onClick={() => handlePageLoad(page)}
76
+ className="cursor-pointer border-b border-gray-100 hover:bg-gray-50"
77
+ >
78
+ <td className="py-3">
79
+ <div className="flex items-center gap-2">
80
+ {/* {page.icon && (
81
+ <img
82
+ src={page.icon}
83
+ width="16"
84
+ height="16"
85
+ alt=""
86
+ className="flex-shrink-0"
87
+ />
88
+ )} */}
89
+ <div className="min-w-0 flex-1">
90
+ <div className="font-medium text-gray-900">
91
+ {page.name}
92
+ </div>
93
+ <div className="text-xs break-all text-gray-500">
94
+ {page.path}
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </td>
99
+ <td className="hidden p-3 text-gray-700 md:table-cell">
100
+ <div className="truncate">{page.templateName || "—"}</div>
101
+ </td>
102
+ <td className="p-3">
103
+ <span className="inline-flex items-center truncate rounded-full bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
104
+ {page.workflowState || "Draft"}
105
+ </span>
106
+ </td>
107
+ <td className="hidden p-3 text-gray-700 md:table-cell">
108
+ {page.versions || 0}
109
+ </td>
110
+ </tr>
111
+ ))}
112
+ </tbody>
113
+ </table>
114
+ {(!history || history.length === 0) && (
115
+ <div className="p-6 text-center text-sm text-gray-500">
116
+ No recent pages found
117
+ </div>
118
+ )}
119
+ </div>
120
+ </div>
121
+ </Card>
122
+ );
123
+ }
@@ -1,9 +1,11 @@
1
1
  import { Card } from "../components/ui/card";
2
- import { Logo } from "../editor/ui/Icons";
2
+ import { Logo, MagicEditIcon } from "../editor/ui/Icons";
3
3
  import { useEditContext } from "../editor/client/editContext";
4
4
  import { useEffect, useState } from "react";
5
5
  import { getWizards } from "../page-wizard/service";
6
6
  import { Wizard } from "../page-wizard/PageWizard";
7
+ import { ActionButton } from "../components/ActionButton";
8
+ import { RecentPages } from "./RecentPages";
7
9
 
8
10
  export function SplashScreen() {
9
11
  const editContext = useEditContext();
@@ -57,57 +59,72 @@ export function SplashScreen() {
57
59
  });
58
60
  };
59
61
 
60
- return (
61
- <div className="flex h-full w-full items-center justify-center bg-gray-100">
62
- <Card
63
- title="Welcome to the Editor Without A Name"
64
- description="The easiest way to create and manage your content"
65
- icon={<Logo />}
66
- >
67
- <div className="flex flex-col gap-4 text-sm text-gray-500">
68
- Ewan is an editor for your favorite content management system. It
69
- allows you to create and manage your content in a simple and intuitive
70
- way.
71
- <div className="flex flex-col gap-4">
72
- {/* Show demo wizard button if demoId is present and wizard is available */}
73
- {demoWizard && (
74
- <CtaButton onClick={launchDemoWizard}>
75
- Launch Page Wizard
76
- </CtaButton>
77
- )}
78
- {!demoWizard && (
79
- <>
80
- <CtaButton onClick={() => editContext?.switchView("new-page")}>
81
- Create New Page
82
- </CtaButton>
83
- </>
84
- )}
85
- <CtaButton onClick={() => editContext?.switchView("open-page")}>
86
- Open Existing Page
87
- </CtaButton>
88
- {/* <CtaButton onClick={() => editContext?.switchView("new-page")}>
89
- Take a Tour
90
- </CtaButton> */}
62
+ if (demoWizard) {
63
+ return (
64
+ <div className="relative flex h-full w-full bg-gray-100 md:items-center md:justify-center">
65
+ <div className="z-10 flex flex-1 flex-col items-stretch gap-4 p-4 md:max-w-screen-xl md:flex-row">
66
+ <div className="flex-1 flex-col gap-7 rounded-lg bg-white p-6">
67
+ <div className="flex flex-col gap-4 md:flex-row">
68
+ <div className="flex flex-col gap-2">
69
+ <h1 className="text-normal flex items-center gap-2 font-bold">
70
+ <Logo className="h-5" /> Create content like magic
71
+ </h1>
72
+ <h2 className="mb-2 text-xs text-gray-500">
73
+ Stunning business pages in no time. Just describe your idea
74
+ and let the AI-wizard do the magic.
75
+ </h2>
76
+ </div>
77
+
78
+ <ActionButton onClick={launchDemoWizard}>
79
+ Launch wizard <MagicEditIcon />
80
+ </ActionButton>
81
+ </div>
82
+ <div className="bg-wizard-demo mt-3 aspect-[1.75] w-full rounded-lg"></div>
83
+ </div>
84
+ <div className="flex-1">
85
+ <RecentPages />
91
86
  </div>
92
87
  </div>
93
- </Card>
94
- </div>
95
- );
96
- }
97
-
98
- function CtaButton({
99
- children,
100
- onClick,
101
- }: {
102
- children: React.ReactNode;
103
- onClick: () => void;
104
- }) {
105
- return (
106
- <button
107
- className="border-theme-secondary hover:bg-theme-secondary-light flex cursor-pointer flex-col gap-4 rounded-lg border p-8 text-2xl"
108
- onClick={onClick}
109
- >
110
- {children}
111
- </button>
112
- );
88
+ <div className="bg-wizard absolute inset-0" />
89
+ </div>
90
+ );
91
+ } else {
92
+ return (
93
+ <div className="flex h-full w-full gap-2 bg-gray-100 md:items-center md:justify-center">
94
+ <div className="z-10 flex flex-1 flex-col items-stretch gap-4 p-4 md:min-h-[40vh] md:max-w-screen-xl md:flex-row">
95
+ <Card
96
+ title="Welcome to the Editor Without A Name"
97
+ description="The easiest way to create and manage your content"
98
+ icon={<Logo />}
99
+ className="flex-1"
100
+ >
101
+ <div className="flex flex-col gap-4 text-sm text-gray-500">
102
+ Ewan is an editor for your favorite content management system. It
103
+ allows you to create and manage your content in a simple and
104
+ intuitive way.
105
+ <div className="flex flex-col gap-4">
106
+ <ActionButton
107
+ onClick={() => editContext?.switchView("new-page")}
108
+ >
109
+ Create new page
110
+ </ActionButton>
111
+ <ActionButton
112
+ onClick={() => editContext?.switchView("open-page")}
113
+ >
114
+ Open existing page
115
+ </ActionButton>
116
+ <ActionButton onClick={() => editContext?.startTour()}>
117
+ Take tour <MagicEditIcon />
118
+ </ActionButton>
119
+ </div>
120
+ </div>
121
+ </Card>
122
+ <div className="flex-1">
123
+ <RecentPages />
124
+ </div>
125
+ </div>
126
+ <div className="bg-wizard absolute inset-0" />
127
+ </div>
128
+ );
129
+ }
113
130
  }