11import React from "react" ;
2- import Link from "next/link" ;
32import type { FlexProps , ModalProps } from "@mantine/core" ;
43import {
54 Modal ,
@@ -16,17 +15,13 @@ import {
1615 CloseButton ,
1716 FocusTrap ,
1817 Stack ,
19- Paper ,
18+ Badge ,
2019} from "@mantine/core" ;
20+ import styled from "styled-components" ;
2121import Cookie from "js-cookie" ;
22+ import { FaPlay } from "react-icons/fa6" ;
2223import { GoDependabot } from "react-icons/go" ;
23- import {
24- LuCheck ,
25- LuChevronRight ,
26- LuGitCompareArrows ,
27- LuInfinity ,
28- LuPencilRuler ,
29- } from "react-icons/lu" ;
24+ import { LuCheck , LuGitCompareArrows , LuInfinity , LuPencilRuler } from "react-icons/lu" ;
3025import useConfig from "../../../store/useConfig" ;
3126
3227export const UpgradeContent = ( props : FlexProps ) => {
@@ -94,35 +89,129 @@ export const UpgradeContent = (props: FlexProps) => {
9489 ) ;
9590} ;
9691
97- const FeatureCard = ( props : { title : string ; description : string ; icon : React . ReactNode } ) => {
92+ const StyledFeatureItem = styled . div `
93+ @property --gradient-1 {
94+ syntax: "<number>";
95+ initial-value: 0;
96+ inherits: false;
97+ }
98+ @property --gradient-2 {
99+ syntax: "<number>";
100+ initial-value: 0;
101+ inherits: false;
102+ }
103+ @property --gradient-3 {
104+ syntax: "<number>";
105+ initial-value: 0;
106+ inherits: false;
107+ }
108+
109+ background-image:
110+ radial-gradient(
111+ 65% 110% at 50% 0,
112+ rgba(168, 92, 92, var(--gradient-1)) 0,
113+ rgba(103, 69, 69, 0) 100%
114+ ),
115+ radial-gradient(
116+ 66% 135% at 77% 23%,
117+ rgba(4, 0, 255, var(--gradient-2)) 0,
118+ hsla(68, 15%, 59%, 0) 80%
119+ ),
120+ radial-gradient(
121+ 125% 234% at 10% 142%,
122+ rgba(217, 126, 75, var(--gradient-3)) 0,
123+ hsla(0, 0%, 100%, 0) 37%
124+ );
125+ transition:
126+ --gradient-1 0.3s,
127+ --gradient-2 0.3s,
128+ --gradient-3 0.3s;
129+ padding: 12px 16px;
130+ background-color: rgba(27, 23, 40, 0.025);
131+ border: 1px solid rgba(142, 142, 142, 0.35);
132+ border-radius: 0.5rem;
133+ max-width: 350px;
134+ cursor: pointer;
135+
136+ &.selected {
137+ --gradient-1: 0.1;
138+ --gradient-2: 0.15;
139+ --gradient-3: 0.15;
140+ border-color: rgba(130, 174, 255, 0.567);
141+ }
142+
143+ &:hover {
144+ --gradient-1: 0.1;
145+ --gradient-2: 0.15;
146+ --gradient-3: 0.15;
147+ }
148+ ` ;
149+
150+ const FeatureCard = ( props : {
151+ title : string ;
152+ description : string ;
153+ icon : React . ReactNode ;
154+ onClick : ( ) => void ;
155+ selected : boolean ;
156+ } ) => {
98157 return (
99- < Paper withBorder p = "xs" radius = "md" >
158+ < StyledFeatureItem className = { props . selected ? "selected" : "" } onClick = { props . onClick } >
100159 < Flex gap = "md" align = "flex-start" >
101- < ThemeIcon variant = "light" color = "teal " radius = "xl" size = "36" >
160+ < ThemeIcon variant = "light" color = "grape " radius = "xl" size = "36" >
102161 { props . icon }
103162 </ ThemeIcon >
104163 < Stack gap = "4" >
105- < Text fz = "md" fw = "600" c = "bright" >
106- { props . title }
107- </ Text >
164+ < Flex justify = "space-between" align = "center" >
165+ < Text fz = "md" fw = "600" c = "bright" >
166+ { props . title }
167+ </ Text >
168+ < ThemeIcon variant = "transparent" color = "grape" >
169+ { props . selected ? < LuCheck size = { 20 } /> : null }
170+ </ ThemeIcon >
171+ </ Flex >
108172 < Text fz = "sm" c = "gray" opacity = { 0.8 } >
109173 { props . description }
110174 </ Text >
111175 </ Stack >
112176 </ Flex >
113- </ Paper >
177+ </ StyledFeatureItem >
114178 ) ;
115179} ;
116180
181+ const FEATURES = [
182+ {
183+ title : "No File Size Limits" ,
184+ description : "Load and edit even the largest data files without restrictions." ,
185+ icon : < LuInfinity size = { 20 } /> ,
186+ } ,
187+ {
188+ title : "Visual Data Editing" ,
189+ description : "Edit JSON, YAML, CSV, and XML directly on the diagram." ,
190+ icon : < LuPencilRuler size = { 20 } /> ,
191+ } ,
192+ {
193+ title : "Live JSON Schema Validation" ,
194+ description : "Instantly see invalid fields highlighted in red on the diagram." ,
195+ icon : < LuGitCompareArrows size = { 20 } /> ,
196+ } ,
197+ {
198+ title : "AI Assistant" ,
199+ description : "Use AI to filter and transform data based on your needs." ,
200+ icon : < GoDependabot size = { 20 } /> ,
201+ } ,
202+ ] ;
203+
117204export const UpgradeModal = ( { opened, onClose } : ModalProps ) => {
205+ const [ selectedFeature , setSelectedFeature ] = React . useState ( 0 ) ;
206+
118207 const handleCloseModal = ( ) => {
119208 Cookie . set ( "upgrade_shown" , "true" , { expires : 3 } ) ;
120209 onClose ( ) ;
121210 } ;
122211
123212 return (
124213 < Modal
125- size = "xl "
214+ size = "auto "
126215 opened = { opened }
127216 onClose = { handleCloseModal }
128217 zIndex = { 1001 }
@@ -134,58 +223,58 @@ export const UpgradeModal = ({ opened, onClose }: ModalProps) => {
134223 < FocusTrap . InitialFocus />
135224 < Flex >
136225 < Stack >
137- < FeatureCard
138- title = "No File Size Limits"
139- description = "Load and edit even the largest data files without restrictions."
140- icon = { < LuInfinity size = { 20 } /> }
141- />
142- < FeatureCard
143- title = "Visual Data Editing"
144- description = "Edit JSON, YAML, CSV, and XML directly on the diagram."
145- icon = { < LuPencilRuler size = { 20 } /> }
146- />
147- < FeatureCard
148- title = "Live JSON Schema Validation"
149- description = "Instantly see invalid fields highlighted in red on the diagram."
150- icon = { < LuGitCompareArrows size = { 20 } /> }
151- />
152- < FeatureCard
153- title = "AI Assistant"
154- description = "Use AI to filter and transform data based on your needs."
155- icon = { < GoDependabot size = { 20 } /> }
156- />
226+ { FEATURES . map ( ( feature , index ) => (
227+ < FeatureCard
228+ key = { index }
229+ title = { feature . title }
230+ description = { feature . description }
231+ icon = { feature . icon }
232+ onClick = { ( ) => setSelectedFeature ( index ) }
233+ selected = { selectedFeature === index }
234+ />
235+ ) ) }
157236 </ Stack >
158237 < Divider orientation = "vertical" mx = "md" />
159238 < Box >
160239 < Flex justify = "center" align = "center" gap = "xs" >
161- < Image
162- ml = "auto"
163- pl = "28"
164- src = "https://todiagram.com/logo-64x64.png"
165- alt = "todiagram"
166- width = { 30 }
167- height = { 30 }
168- />
169- < Text fz = "24" fw = "600" c = "bright" >
170- JSON Crack 2.0
240+ < Badge size = "xl" radius = "sm" variant = "light" color = "teal" ml = "auto" >
241+ 🔥 NEW
242+ </ Badge >
243+ < Text fz = "24" fw = "700" c = "bright" >
244+ ToDiagram Editor
171245 </ Text >
172246 < CloseButton ml = "auto" onClick = { handleCloseModal } />
173247 </ Flex >
174- < UpgradeContent direction = "column-reverse" maw = "400" />
248+ < Image
249+ mt = "sm"
250+ src = { `/assets/td-${ selectedFeature + 1 } .webp` }
251+ w = "100%"
252+ maw = "385"
253+ radius = "md"
254+ alt = "upgrade"
255+ fit = "contain"
256+ />
175257 < Group justify = "center" gap = "xs" mt = "md" >
176258 < Button
177- component = { Link }
259+ component = "a"
178260 href = "https://todiagram.com/editor?utm_source=jsoncrack& utm_medium = upgrade_modal "
179261 rel = "noopener"
180262 target = "_blank"
181- fz = "lg"
182- fw = "600"
183- size = "md"
184- rightSection = { < LuChevronRight /> }
185- color = "green"
263+ radius = "lg"
264+ size = "lg"
265+ c = "black"
266+ autoContrast
267+ variant = "gradient"
268+ gradient = { { from : "#FF75B7" , to : "#FED761" } }
269+ leftSection = { < FaPlay /> }
186270 fullWidth
271+ fw = "600"
272+ style = { {
273+ boxShadow : "rgba(0, 0, 0, 0.12) 0px -3px 0px 0px inset" ,
274+ border : "none" ,
275+ } }
187276 >
188- Try now
277+ Upgrade now
189278 </ Button >
190279 </ Group >
191280 </ Box >
0 commit comments