enzostvs HF Staff commited on
Commit
bcb0fad
·
1 Parent(s): 0967b2e

add refresh button + confirm modal

Browse files
src/components/App.tsx CHANGED
@@ -3,7 +3,7 @@ import { useRef, useState } from "react";
3
  import Editor from "@monaco-editor/react";
4
  import classNames from "classnames";
5
  import { editor } from "monaco-editor";
6
- import { useMount, useUnmount } from "react-use";
7
  import { toast } from "react-toastify";
8
 
9
  import Header from "./header/header";
@@ -12,6 +12,7 @@ import { defaultHTML } from "../utils/consts";
12
  import Tabs from "./tabs/tabs";
13
  import AskAI from "./ask-ai/ask-ai";
14
  import { Auth } from "../utils/types";
 
15
 
16
  function App() {
17
  const preview = useRef<HTMLDivElement>(null);
@@ -55,6 +56,13 @@ function App() {
55
  document.removeEventListener("mouseup", handleMouseUp);
56
  };
57
 
 
 
 
 
 
 
 
58
  useMount(() => {
59
  fetchMe();
60
  if (!editor.current || !preview.current) return;
@@ -95,7 +103,7 @@ function App() {
95
  }
96
  }}
97
  >
98
- <Tabs>{/* <Settings /> */}</Tabs>
99
  <Editor
100
  language="html"
101
  theme="vs-dark"
@@ -131,18 +139,12 @@ function App() {
131
  ref={resizer}
132
  className="bg-gray-700 hover:bg-blue-500 w-2 cursor-col-resize h-[calc(100dvh-54px)]"
133
  />
134
- <div
 
 
 
135
  ref={preview}
136
- className="w-full border-l border-gray-900 bg-white h-[calc(100dvh-54px)]"
137
- >
138
- <iframe
139
- title="output"
140
- className={classNames("w-full h-full select-none", {
141
- "pointer-events-none": isResizing || isAiWorking,
142
- })}
143
- srcDoc={html}
144
- />
145
- </div>
146
  </main>
147
  <main className="lg:hidden p-5">
148
  <p className="p-5 bg-red-500/10 text-red-500 rounded-md text-base text-pretty">
 
3
  import Editor from "@monaco-editor/react";
4
  import classNames from "classnames";
5
  import { editor } from "monaco-editor";
6
+ import { useMount, useUnmount, useEvent } from "react-use";
7
  import { toast } from "react-toastify";
8
 
9
  import Header from "./header/header";
 
12
  import Tabs from "./tabs/tabs";
13
  import AskAI from "./ask-ai/ask-ai";
14
  import { Auth } from "../utils/types";
15
+ import Preview from "./preview/preview";
16
 
17
  function App() {
18
  const preview = useRef<HTMLDivElement>(null);
 
56
  document.removeEventListener("mouseup", handleMouseUp);
57
  };
58
 
59
+ useEvent("beforeunload", (e) => {
60
+ if (isAiWorking || html !== defaultHTML) {
61
+ e.preventDefault();
62
+ return "";
63
+ }
64
+ });
65
+
66
  useMount(() => {
67
  fetchMe();
68
  if (!editor.current || !preview.current) return;
 
103
  }
104
  }}
105
  >
106
+ <Tabs />
107
  <Editor
108
  language="html"
109
  theme="vs-dark"
 
139
  ref={resizer}
140
  className="bg-gray-700 hover:bg-blue-500 w-2 cursor-col-resize h-[calc(100dvh-54px)]"
141
  />
142
+ <Preview
143
+ html={html}
144
+ isResizing={isResizing}
145
+ isAiWorking={isAiWorking}
146
  ref={preview}
147
+ />
 
 
 
 
 
 
 
 
 
148
  </main>
149
  <main className="lg:hidden p-5">
150
  <p className="p-5 bg-red-500/10 text-red-500 rounded-md text-base text-pretty">
src/components/ask-ai/ask-ai.tsx CHANGED
@@ -21,6 +21,7 @@ function AskAI({
21
  }) {
22
  const [open, setOpen] = useState(false);
23
  const [prompt, setPrompt] = useState("");
 
24
 
25
  const callAi = async () => {
26
  if (isAiWorking) return;
@@ -57,6 +58,7 @@ function AskAI({
57
  toast.success("AI responded successfully");
58
  setPrompt("");
59
  setisAiWorking(false);
 
60
  return;
61
  }
62
 
@@ -97,7 +99,9 @@ function AskAI({
97
  type="text"
98
  disabled={isAiWorking}
99
  className="w-full bg-transparent outline-none pl-3 text-white placeholder:text-gray-500 font-code"
100
- placeholder="Ask AI anything..."
 
 
101
  value={prompt}
102
  onChange={(e) => setPrompt(e.target.value)}
103
  onKeyDown={(e) => {
 
21
  }) {
22
  const [open, setOpen] = useState(false);
23
  const [prompt, setPrompt] = useState("");
24
+ const [hasAsked, setHasAsked] = useState(false);
25
 
26
  const callAi = async () => {
27
  if (isAiWorking) return;
 
58
  toast.success("AI responded successfully");
59
  setPrompt("");
60
  setisAiWorking(false);
61
+ setHasAsked(true);
62
  return;
63
  }
64
 
 
99
  type="text"
100
  disabled={isAiWorking}
101
  className="w-full bg-transparent outline-none pl-3 text-white placeholder:text-gray-500 font-code"
102
+ placeholder={
103
+ hasAsked ? "What do you want to ask AI next?" : "Ask AI anything..."
104
+ }
105
  value={prompt}
106
  onChange={(e) => setPrompt(e.target.value)}
107
  onKeyDown={(e) => {
src/components/login/login.tsx CHANGED
@@ -11,7 +11,7 @@ function Login({ children }: { children?: React.ReactNode }) {
11
  {children}
12
  <a href="/api/login">
13
  <img
14
- src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-md-dark.svg"
15
  alt="Sign in with Hugging Face"
16
  className="mx-auto"
17
  />
 
11
  {children}
12
  <a href="/api/login">
13
  <img
14
+ src="https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-lg-dark.svg"
15
  alt="Sign in with Hugging Face"
16
  className="mx-auto"
17
  />
src/components/preview/preview.tsx ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import classNames from "classnames";
2
+ import { useRef } from "react";
3
+ import { TbReload } from "react-icons/tb";
4
+
5
+ function Preview({
6
+ html,
7
+ isResizing,
8
+ isAiWorking,
9
+ ref,
10
+ }: {
11
+ html: string;
12
+ isResizing: boolean;
13
+ isAiWorking: boolean;
14
+ ref: React.RefObject<HTMLDivElement | null>;
15
+ }) {
16
+ const iframeRef = useRef<HTMLIFrameElement | null>(null);
17
+
18
+ const handleRefreshIframe = () => {
19
+ if (iframeRef.current) {
20
+ const iframe = iframeRef.current;
21
+ const content = iframe.srcdoc;
22
+ iframe.srcdoc = "";
23
+ setTimeout(() => {
24
+ iframe.srcdoc = content;
25
+ }, 10);
26
+ }
27
+ };
28
+
29
+ return (
30
+ <div
31
+ ref={ref}
32
+ className="w-full border-l border-gray-900 bg-white h-[calc(100dvh-54px)] relative"
33
+ >
34
+ <iframe
35
+ ref={iframeRef}
36
+ title="output"
37
+ className={classNames("w-full h-full select-none", {
38
+ "pointer-events-none": isResizing || isAiWorking,
39
+ })}
40
+ srcDoc={html}
41
+ />
42
+ <button
43
+ className="bg-gray-900 shadow-md text-white text-sm font-medium absolute bottom-5 right-5 py-2 px-4 rounded-lg flex items-center gap-2 border border-gray-800 hover:brightness-150 transition-all duration-100 cursor-pointer"
44
+ onClick={handleRefreshIframe}
45
+ >
46
+ <TbReload />
47
+ Refresh Preview
48
+ </button>
49
+ </div>
50
+ );
51
+ }
52
+
53
+ export default Preview;