enzostvs HF Staff commited on
Commit
09841e5
Β·
1 Parent(s): c1cb3bd

discord promo modal

Browse files
components/discord-promo-modal/index.tsx ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import { useEffect, useState } from "react";
4
+ import { useLocalStorage } from "react-use";
5
+ import Image from "next/image";
6
+ import { Button } from "@/components/ui/button";
7
+ import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
8
+ import { DiscordIcon } from "@/components/icons/discord";
9
+ import Logo from "@/assets/logo.svg";
10
+
11
+ const DISCORD_PROMO_KEY = "discord-promo-dismissed";
12
+ const DISCORD_URL = "https://discord.gg/KpanwM3vXa";
13
+
14
+ export const DiscordPromoModal = () => {
15
+ const [open, setOpen] = useState(false);
16
+ const [dismissed, setDismissed] = useLocalStorage<boolean>(
17
+ DISCORD_PROMO_KEY,
18
+ false
19
+ );
20
+
21
+ useEffect(() => {
22
+ const cookieDismissed = document.cookie
23
+ .split("; ")
24
+ .find((row) => row.startsWith(`${DISCORD_PROMO_KEY}=`))
25
+ ?.split("=")[1];
26
+
27
+ if (dismissed || cookieDismissed === "true") {
28
+ return;
29
+ }
30
+
31
+ const timer = setTimeout(() => {
32
+ setOpen(true);
33
+ }, 60000);
34
+
35
+ return () => clearTimeout(timer);
36
+ }, [dismissed]);
37
+
38
+ const handleClose = () => {
39
+ setOpen(false);
40
+ setDismissed(true);
41
+
42
+ const expiryDate = new Date();
43
+ expiryDate.setFullYear(expiryDate.getFullYear() + 1);
44
+ document.cookie = `${DISCORD_PROMO_KEY}=true; expires=${expiryDate.toUTCString()}; path=/; SameSite=Lax`;
45
+ };
46
+
47
+ const handleJoinDiscord = () => {
48
+ window.open(DISCORD_URL, "_blank");
49
+ handleClose();
50
+ };
51
+
52
+ return (
53
+ <Dialog open={open} onOpenChange={handleClose}>
54
+ <DialogContent
55
+ className="sm:max-w-md lg:!p-0 !rounded-3xl !bg-gradient-to-br !from-neutral-900 !via-neutral-800 !to-neutral-900 !border !border-neutral-700/50 overflow-hidden"
56
+ showCloseButton={false}
57
+ >
58
+ <DialogTitle className="hidden" />
59
+ <main className="flex flex-col items-center text-center relative p-8">
60
+ <div className="absolute inset-0 overflow-hidden pointer-events-none">
61
+ <div className="absolute top-0 left-0 w-32 h-32 bg-indigo-500/10 rounded-full blur-3xl animate-pulse" />
62
+ <div className="absolute bottom-0 right-0 w-40 h-40 bg-purple-500/10 rounded-full blur-3xl animate-pulse delay-1000" />
63
+ </div>
64
+
65
+ <div className="relative z-10 w-full">
66
+ <div className="inline-flex items-center justify-center mb-6 gap-3">
67
+ <div className="relative">
68
+ <div className="absolute inset-0 bg-white/10 rounded-xl blur-lg opacity-50 animate-pulse" />
69
+ <div className="relative bg-gradient-to-br from-white/10 to-white/5 backdrop-blur-sm rounded-xl p-3 shadow-2xl border border-white/20">
70
+ <Image
71
+ src={Logo}
72
+ alt="DeepSite"
73
+ width={32}
74
+ height={32}
75
+ className="w-8 h-8"
76
+ />
77
+ </div>
78
+ </div>
79
+
80
+ <div className="text-white/40 text-2xl font-bold animate-pulse">
81
+ +
82
+ </div>
83
+
84
+ <div className="relative">
85
+ <div
86
+ className="absolute inset-0 bg-indigo-500/80 rounded-xl blur-lg opacity-50 animate-pulse"
87
+ style={{ animationDelay: "0.5s" }}
88
+ />
89
+ <div className="relative bg-indigo-500 backdrop-blur-sm rounded-xl p-3 shadow-2xl border border-indigo-500/30">
90
+ <DiscordIcon className="size-8 text-whie" />
91
+ </div>
92
+ </div>
93
+ </div>
94
+
95
+ <h2 className="text-3xl font-bold text-white mb-3">
96
+ Join Our Community! πŸŽ‰
97
+ </h2>
98
+
99
+ <p className="text-neutral-300 text-base mb-6 max-w-xs mx-auto leading-relaxed">
100
+ Connect with other DeepSite users, get help, share your projects,
101
+ and stay updated with the latest features!
102
+ </p>
103
+
104
+ <div className="flex flex-col gap-2 mb-8 text-left">
105
+ {[
106
+ { emoji: "πŸ’¬", text: "Chat with the community" },
107
+ { emoji: "πŸ””", text: "Get notified when new features drop" },
108
+ { emoji: "🎨", text: "Share your creations" },
109
+ { emoji: "🀝", text: "Get help from the team" },
110
+ ].map((benefit, index) => (
111
+ <div
112
+ key={index}
113
+ className="flex items-center gap-3 text-neutral-200 text-sm bg-white/5 rounded-lg px-4 py-2 backdrop-blur-sm border border-white/10"
114
+ style={{
115
+ animation: `slideIn 0.3s ease-out ${index * 0.1}s both`,
116
+ }}
117
+ >
118
+ <span className="text-base">{benefit.emoji}</span>
119
+ <span>{benefit.text}</span>
120
+ </div>
121
+ ))}
122
+ </div>
123
+
124
+ <div className="flex flex-col gap-3 w-full">
125
+ <Button
126
+ onClick={handleJoinDiscord}
127
+ className="w-full !h-12 !text-base font-semibold !bg-indigo-500 hover:!bg-indigo-600 !text-white !border-0 transform hover:scale-[1.02] transition-all duration-300"
128
+ >
129
+ <DiscordIcon className="size-4 mr-2" />
130
+ Join Discord Community
131
+ </Button>
132
+ <button
133
+ onClick={handleClose}
134
+ className="text-neutral-400 hover:text-neutral-300 text-sm font-medium transition-colors"
135
+ >
136
+ Maybe later
137
+ </button>
138
+ </div>
139
+ </div>
140
+ </main>
141
+
142
+ <style jsx>{`
143
+ @keyframes slideIn {
144
+ from {
145
+ opacity: 0;
146
+ transform: translateX(-10px);
147
+ }
148
+ to {
149
+ opacity: 1;
150
+ transform: translateX(0);
151
+ }
152
+ }
153
+ `}</style>
154
+ </DialogContent>
155
+ </Dialog>
156
+ );
157
+ };
components/editor/index.tsx CHANGED
@@ -15,6 +15,7 @@ import { FileBrowser } from "./file-browser";
15
  import { AskAi } from "./ask-ai";
16
  import { Preview } from "./preview";
17
  import { SaveChangesPopup } from "./save-changes-popup";
 
18
  import Loading from "../loading";
19
  import { Page } from "@/types";
20
 
@@ -158,7 +159,6 @@ export const AppEditor = ({
158
  <Preview isNew={isNew} namespace={namespace} repoId={repoId} />
159
  </main>
160
 
161
- {/* Save Changes Popup */}
162
  <SaveChangesPopup
163
  isOpen={showSavePopup}
164
  onClose={() => setShowSavePopup(false)}
@@ -167,6 +167,8 @@ export const AppEditor = ({
167
  pages={pages}
168
  project={project}
169
  />
 
 
170
  </section>
171
  );
172
  };
 
15
  import { AskAi } from "./ask-ai";
16
  import { Preview } from "./preview";
17
  import { SaveChangesPopup } from "./save-changes-popup";
18
+ import { DiscordPromoModal } from "@/components/discord-promo-modal";
19
  import Loading from "../loading";
20
  import { Page } from "@/types";
21
 
 
159
  <Preview isNew={isNew} namespace={namespace} repoId={repoId} />
160
  </main>
161
 
 
162
  <SaveChangesPopup
163
  isOpen={showSavePopup}
164
  onClose={() => setShowSavePopup(false)}
 
167
  pages={pages}
168
  project={project}
169
  />
170
+
171
+ <DiscordPromoModal />
172
  </section>
173
  );
174
  };