feat: golden edition modal

This commit is contained in:
Anoop M D 2024-01-05 03:17:55 +05:30
parent 2608ec035e
commit 0db6103b69
4 changed files with 209 additions and 3 deletions

View File

@ -0,0 +1,20 @@
import styled from 'styled-components';
const StyledWrapper = styled.div`
color: ${(props) => props.theme.text};
.collection-options {
svg {
position: relative;
top: -1px;
}
.label {
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
`;
export default StyledWrapper;

View File

@ -0,0 +1,177 @@
import React, { useState, useEffect } from 'react';
import Modal from 'components/Modal/index';
import { PostHog } from 'posthog-node';
import { uuid } from 'utils/common';
import { IconHeart, IconUser, IconUsers } from '@tabler/icons';
import platformLib from 'platform';
import StyledWrapper from './StyledWrapper';
let posthogClient = null;
const posthogApiKey = 'phc_7gtqSrrdZRohiozPMLIacjzgHbUlhalW1Bu16uYijMR';
const getPosthogClient = () => {
if (posthogClient) {
return posthogClient;
}
posthogClient = new PostHog(posthogApiKey);
return posthogClient;
};
const getAnonymousTrackingId = () => {
let id = localStorage.getItem('bruno.anonymousTrackingId');
if (!id || !id.length || id.length !== 21) {
id = uuid();
localStorage.setItem('bruno.anonymousTrackingId', id);
}
return id;
};
const HeartIcon = () => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
className="flex-shrink-0 w-5 h-4 text-yellow-600"
viewBox="0 0 16 16"
>
<path fillRule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
</svg>
);
};
const CheckIcon = () => {
return (
<svg
className="flex-shrink-0 w-5 h-5 text-green-500"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
></path>
</svg>
);
};
const GoldenEdition = ({ onClose }) => {
useEffect(() => {
const anonymousId = getAnonymousTrackingId();
const client = getPosthogClient();
client.capture({
distinctId: anonymousId,
event: 'golden-edition-modal-opened',
properties: {
os: platformLib.os.family
}
});
}, []);
const goldenEditionBuyClick = () => {
const anonymousId = getAnonymousTrackingId();
const client = getPosthogClient();
client.capture({
distinctId: anonymousId,
event: 'golden-edition-buy-clicked',
properties: {
os: platformLib.os.family
}
});
};
const goldenEditon = [
'Inbuilt Bru File Explorer',
'Visual Git (Like Gitlens for Vscode)',
'GRPC, Websocket, SocketIO, MQTT',
'Intergration with Secret Managers',
'Load Data from File for Collection Run',
'Developer Tools',
'OpenAPI Designer',
'Performance/Load Testing',
'Inbuilt Terminal',
'Custom Themes'
];
const [pricingOption, setPricingOption] = useState('individuals');
const handlePricingOptionChange = (option) => {
setPricingOption(option);
};
return (
<StyledWrapper>
<Modal size="sm" title={'Golden Edition'} handleCancel={onClose} hideFooter={true}>
<div className="flex flex-col text-gray-900 bg-white w-full">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">Golden Edition</h3>
<a
onClick={() => {
goldenEditionBuyClick();
window.open('https://www.usebruno.com/pricing', '_blank');
}}
target="_blank"
className="flex text-white bg-yellow-600 hover:bg-yellow-700 font-medium rounded-lg text-sm px-4 py-2 text-center cursor-pointer"
>
<IconHeart size={18} strokeWidth={1.5} />{' '}
<span className="ml-2">{pricingOption === 'individuals' ? 'Buy' : 'Subscribe'}</span>
</a>
</div>
{pricingOption === 'individuals' ? (
<div>
<div className="my-4">
<span className="text-3xl font-extrabold">$19</span>
</div>
<p className="bg-yellow-200 rounded-md px-2 py-1 mb-2 inline-flex text-sm">One Time Payment</p>
<p className="text-sm">perpetual license for 2 devices, with 2 years of updates</p>
</div>
) : (
<div>
<div className="my-4">
<span className="text-3xl font-extrabold">$2</span>
</div>
<p>/user/month</p>
</div>
)}
<div
className="flex items-center justify-between my-8 w-40 bg-gray-200 rounded-full p-1"
style={{ width: '24rem' }}
>
<div
className={`cursor-pointer w-1/2 h-8 flex items-center justify-center rounded-full ${
pricingOption === 'individuals' ? 'bg-white text-gray-900 font-medium' : 'text-gray-500'
}`}
onClick={() => handlePricingOptionChange('individuals')}
>
<IconUser className="text-gray-500 mr-2 icon" size={16} strokeWidth={1.5} /> Individuals
</div>
<div
className={`cursor-pointer w-1/2 h-8 flex items-center justify-center rounded-full ${
pricingOption === 'organizations' ? 'bg-white text-gray-900 font-medium' : 'text-gray-500'
}`}
onClick={() => handlePricingOptionChange('organizations')}
>
<IconUsers className="text-gray-500 mr-2 icon" size={16} strokeWidth={1.5} /> Organizations
</div>
</div>
<ul role="list" className="space-y-3 text-left">
<li className="flex items-center space-x-3">
<HeartIcon />
<span>Support Bruno's Development</span>
</li>
{goldenEditon.map((item, index) => (
<li className="flex items-center space-x-3" key={index}>
<CheckIcon />
<span>{item}</span>
</li>
))}
</ul>
</div>
</Modal>
</StyledWrapper>
);
};
export default GoldenEdition;

View File

@ -4,19 +4,21 @@ import StyledWrapper from './StyledWrapper';
import GitHubButton from 'react-github-btn';
import Preferences from 'components/Preferences';
import Cookies from 'components/Cookies';
import GoldenEdition from './GoldenEdition';
import { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { IconSettings, IconCookie } from '@tabler/icons';
import { IconSettings, IconCookie, IconHeart } from '@tabler/icons';
import { updateLeftSidebarWidth, updateIsDragging, showPreferences } from 'providers/ReduxStore/slices/app';
import { useTheme } from 'providers/Theme';
const MIN_LEFT_SIDEBAR_WIDTH = 222;
const MIN_LEFT_SIDEBAR_WIDTH = 221;
const MAX_LEFT_SIDEBAR_WIDTH = 600;
const Sidebar = () => {
const leftSidebarWidth = useSelector((state) => state.app.leftSidebarWidth);
const preferencesOpen = useSelector((state) => state.app.showPreferences);
const [goldenEditonOpen, setGoldenEditonOpen] = useState(false);
const [asideWidth, setAsideWidth] = useState(leftSidebarWidth);
const [cookiesOpen, setCookiesOpen] = useState(false);
@ -79,6 +81,7 @@ const Sidebar = () => {
return (
<StyledWrapper className="flex relative h-screen">
<aside>
{goldenEditonOpen && <GoldenEdition onClose={() => setGoldenEditonOpen(false)} />}
<div className="flex flex-row h-screen w-full">
{preferencesOpen && <Preferences onClose={() => dispatch(showPreferences(false))} />}
{cookiesOpen && <Cookies onClose={() => setCookiesOpen(false)} />}
@ -103,6 +106,12 @@ const Sidebar = () => {
className="mr-2 hover:text-gray-700"
onClick={() => setCookiesOpen(true)}
/>
<IconHeart
size={18}
strokeWidth={1.5}
className="mr-2 hover:text-gray-700"
onClick={() => setGoldenEditonOpen(true)}
/>
</div>
<div className="pl-1" style={{ position: 'relative', top: '3px' }}>
{/* This will get moved to home page */}

View File

@ -107,7 +107,7 @@ app.on('ready', async () => {
mainWindow.webContents.setWindowOpenHandler((details) => {
require('electron').shell.openExternal(details.url);
return { action: 'allow' };
return { action: 'deny' };
});
// register all ipc handlers