├── public └── static │ ├── colors.png │ ├── crown.png │ ├── LogoTrovo.png │ ├── footer.webp │ ├── checkout │ ├── diners.png │ ├── visa-color.png │ ├── diners-color.png │ ├── safekey-color.png │ ├── mastercard-color.png │ ├── card.svg │ ├── error.svg │ ├── cvv.svg │ └── exp-date.svg │ ├── landing │ ├── landing-bg-min.png │ ├── colorsset.svg │ ├── arrow-down.svg │ ├── tick-premium.svg │ ├── features │ │ ├── embed │ │ │ └── embed-icon.svg │ │ ├── rr │ │ │ └── rr-icon.svg │ │ ├── welcome │ │ │ └── welcome-icon.svg │ │ └── leveling │ │ │ └── leveling-icon.svg │ ├── tick.svg │ ├── info-circle.svg │ └── premium.svg │ ├── edit.svg │ ├── menu-nav-icon.svg │ ├── block-icon.svg │ ├── questionmark.svg │ ├── timeout-icon.svg │ ├── gradient3.svg │ ├── gradient2.svg │ ├── gradient4.svg │ ├── overlay_stars_1.svg │ ├── commandIcon.svg │ ├── topStar.svg │ └── gradient1.svg ├── components ├── Memberships │ ├── ChangeBackground │ │ └── data.ts │ ├── Manage.tsx │ ├── TransferData │ │ ├── index.tsx │ │ └── OtpInput.tsx │ └── index.tsx ├── premium │ ├── status_follow_popup.jsx │ ├── StatusIcon.jsx │ ├── UserPlans.jsx │ ├── method_checkout_full_iframe.jsx │ ├── status_approved.jsx │ ├── status_declined.jsx │ ├── CouponCode.jsx │ ├── PlanItem.jsx │ └── RechargeAccountBalanceRow.jsx ├── react-sortable-hoc │ ├── SortableContainer │ │ ├── defaultGetHelperDimensions.js │ │ ├── defaultShouldCancelStart.js │ │ └── props.js │ ├── index.js │ ├── Manager │ │ └── index.js │ ├── SortableHandle │ │ └── index.js │ ├── AutoScroller │ │ └── index.js │ └── SortableElement │ │ └── index.js ├── loader.jsx ├── app.jsx ├── InfoIconWithText.jsx ├── emoji-picker │ ├── EmojiDescription.jsx │ ├── Emoji.jsx │ ├── ColorsTheme.jsx │ ├── constants.js │ └── EmojisList.jsx ├── LandingPage │ ├── index.js │ ├── LoadingSpinner.tsx │ ├── FeaturePage │ │ ├── Features.tsx │ │ ├── FeatureTags.tsx │ │ ├── OtherFeatures.tsx │ │ └── FeatureHero.tsx │ ├── Button.tsx │ ├── PremiumPage │ │ ├── Hero.tsx │ │ ├── FAQ.tsx │ │ └── Plans.tsx │ ├── FeaturesSection.tsx │ ├── Feature.tsx │ └── Hero.tsx ├── ReactionRoles │ ├── SwitchType.jsx │ ├── EmojisRows │ │ └── index.jsx │ ├── ButtonsRows │ │ └── index.jsx │ ├── SelectMenus │ │ └── index.jsx │ └── SkeletonLoading.jsx ├── modal.jsx ├── ColorListPicker │ ├── constants.js │ └── index.jsx ├── Streaks.jsx ├── Input.jsx ├── faqcontainer.jsx ├── login.jsx ├── EasyEmbed │ ├── AlignLeftIcon.jsx │ └── AlignHorizontallyIcon.jsx ├── dropdown.jsx ├── alert │ ├── style.module.css │ └── index.jsx ├── link.jsx ├── ui │ ├── tooltip.tsx │ ├── button.tsx │ └── dropdown.tsx ├── DailyOnboardingWrapper.jsx ├── ColorPicker.jsx ├── illustrations │ └── empty-responses.js ├── SelectChannels │ └── icons.tsx ├── Confirm.jsx ├── TooltipSlider.tsx ├── DragDropFiles │ └── index.jsx ├── PagesTitle.jsx ├── AutoRoles │ └── AssignRole.jsx └── fields.jsx ├── pages ├── premium │ ├── index.jsx │ └── manage.jsx ├── server │ └── guild_id │ │ ├── premium │ │ ├── manage.jsx │ │ └── index.jsx │ │ ├── notifications │ │ ├── reddit.jsx │ │ ├── youtube.jsx │ │ └── trovo.jsx │ │ ├── utility.jsx │ │ └── EasyEmbed.jsx ├── 500.jsx ├── memberships │ ├── index.tsx │ └── manage.tsx ├── pdf.jsx ├── _error.jsx ├── login │ └── token │ │ ├── index.jsx │ │ └── guild.jsx ├── markdown.jsx ├── 404.jsx ├── emoji-picker.jsx ├── pricing.jsx ├── privacy-policy.jsx ├── terms-of-use.jsx ├── refund-policy.jsx ├── dashboard.jsx ├── index.jsx └── _app.jsx ├── scripts ├── utils.ts ├── locale.js ├── handle_error.js └── commands.js ├── styles ├── colors.module.css ├── Notfound.module.css ├── variables.css ├── logs.module.css ├── tailwind.css ├── PagesTitle.module.css ├── overview.module.css ├── fields.module.css ├── panelLogs.module.css └── transactions.module.css ├── sentry.client.config.js ├── LICENSE ├── README.md ├── package.json └── 8e19c08bc4401c6c.css /public/static/colors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/colors.png -------------------------------------------------------------------------------- /public/static/crown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/crown.png -------------------------------------------------------------------------------- /public/static/LogoTrovo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/LogoTrovo.png -------------------------------------------------------------------------------- /public/static/footer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/footer.webp -------------------------------------------------------------------------------- /public/static/checkout/diners.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/checkout/diners.png -------------------------------------------------------------------------------- /public/static/checkout/visa-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/checkout/visa-color.png -------------------------------------------------------------------------------- /public/static/checkout/diners-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/checkout/diners-color.png -------------------------------------------------------------------------------- /public/static/checkout/safekey-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/checkout/safekey-color.png -------------------------------------------------------------------------------- /public/static/landing/landing-bg-min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/landing/landing-bg-min.png -------------------------------------------------------------------------------- /public/static/checkout/mastercard-color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkurkar/ProBotDiscordFontEnd/HEAD/public/static/checkout/mastercard-color.png -------------------------------------------------------------------------------- /components/Memberships/ChangeBackground/data.ts: -------------------------------------------------------------------------------- 1 | export const fileTypes = ['JPG', 'PNG', 'SVG'] 2 | export const maxFileSize = 3 * 1024 * 1024 // 3MB 3 | -------------------------------------------------------------------------------- /public/static/landing/colorsset.svg: -------------------------------------------------------------------------------- 1 | export default {"src":"/_next/static/media/colorsset.56b64b89.svg","height":274,"width":458,"blurWidth":0,"blurHeight":0}; -------------------------------------------------------------------------------- /pages/premium/index.jsx: -------------------------------------------------------------------------------- 1 | import Pricing from '../../components/premium/pricing' 2 | 3 | export default function PremiumIndex() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /pages/premium/manage.jsx: -------------------------------------------------------------------------------- 1 | import Manage from '../../components/premium/manage' 2 | 3 | export default function ManagePremium() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /components/premium/status_follow_popup.jsx: -------------------------------------------------------------------------------- 1 | export default function FollowPopup() { 2 | return
Follow instructions on popup
; 3 | } 4 | -------------------------------------------------------------------------------- /pages/server/guild_id/premium/manage.jsx: -------------------------------------------------------------------------------- 1 | import Manage from "@component/premium/manage"; 2 | 3 | export default function PremiumIndex() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /pages/server/guild_id/premium/index.jsx: -------------------------------------------------------------------------------- 1 | import Pricing from "@component/premium/pricing"; 2 | 3 | 4 | export default function PremiumIndex() { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /pages/500.jsx: -------------------------------------------------------------------------------- 1 | function Error() { 2 | return ( 3 |

4 | Error 500 5 |

6 | ); 7 | } 8 | 9 | 10 | export default Error; 11 | -------------------------------------------------------------------------------- /pages/server/guild_id/notifications/reddit.jsx: -------------------------------------------------------------------------------- 1 | import Notification from "@component/Notifications"; 2 | 3 | const Reddit = () => 4 | 5 | export default Reddit; -------------------------------------------------------------------------------- /pages/server/guild_id/notifications/youtube.jsx: -------------------------------------------------------------------------------- 1 | import Notification from "@component/Notifications"; 2 | 3 | const YouTube = () => 4 | 5 | export default YouTube; -------------------------------------------------------------------------------- /pages/server/guild_id/notifications/trovo.jsx: -------------------------------------------------------------------------------- 1 | import Notification from "../../../../components/Notifications"; 2 | 3 | const Trovo = () => 4 | 5 | export default Trovo; -------------------------------------------------------------------------------- /scripts/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from 'clsx' 2 | import { twMerge } from 'tailwind-merge' 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /pages/memberships/index.tsx: -------------------------------------------------------------------------------- 1 | import MembershipLayout from '@component/Memberships' 2 | import * as React from 'react' 3 | 4 | export default function Membership() { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /pages/pdf.jsx: -------------------------------------------------------------------------------- 1 | import Loading from "@component/loader"; 2 | export default function pdfLoading() { 3 | return
4 | 5 |
6 | } -------------------------------------------------------------------------------- /components/react-sortable-hoc/SortableContainer/defaultGetHelperDimensions.js: -------------------------------------------------------------------------------- 1 | export default function defaultGetHelperDimensions({node}) { 2 | return { 3 | height: node.offsetHeight, 4 | width: node.offsetWidth, 5 | }; 6 | } 7 | -------------------------------------------------------------------------------- /public/static/landing/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /scripts/locale.js: -------------------------------------------------------------------------------- 1 | import LocalizedStrings from "react-localization"; 2 | import Langs, {webLangs} from "probot-locale"; 3 | 4 | export const lang = webLangs; 5 | 6 | 7 | const locale = new LocalizedStrings(Langs); 8 | // locale._props = null; 9 | export default locale; 10 | -------------------------------------------------------------------------------- /scripts/handle_error.js: -------------------------------------------------------------------------------- 1 | import strings from '@script/locale' 2 | 3 | export function getLocaleError(err) { 4 | return err.response.data.strings 5 | ? strings.formatString( 6 | ...err.response.data.strings.map((s) => strings[s] || s) 7 | ) 8 | : err.response.data.error 9 | } 10 | -------------------------------------------------------------------------------- /components/loader.jsx: -------------------------------------------------------------------------------- 1 | export default function Loading({type}) { 2 | if(type === 2) return
; 3 | return ( 4 |
5 |
6 |
7 |
8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /components/app.jsx: -------------------------------------------------------------------------------- 1 | import {Context} from "@script/_context"; 2 | import {useContext} from 'react'; 3 | import Modal from "react-modal"; 4 | Modal.setAppElement("body"); 5 | export default function App({children}) { 6 | const {rtl, providerClass} = useContext(Context); 7 | return
{children}
; 8 | } 9 | -------------------------------------------------------------------------------- /public/static/checkout/card.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /pages/_error.jsx: -------------------------------------------------------------------------------- 1 | function Error({ statusCode }) { 2 | return ( 3 |

4 | {statusCode 5 | ? `An error ${statusCode} occurred on server` 6 | : "An error occurred on client"} 7 |

8 | ); 9 | } 10 | 11 | Error.getInitialProps = ({ res, err }) => { 12 | const statusCode = res ? res.statusCode : err ? err.statusCode : 404; 13 | return { statusCode }; 14 | }; 15 | 16 | export default Error; 17 | -------------------------------------------------------------------------------- /components/react-sortable-hoc/index.js: -------------------------------------------------------------------------------- 1 | export {default as SortableContainer} from './SortableContainer'; 2 | export {default as SortableElement} from './SortableElement'; 3 | export {default as SortableHandle} from './SortableHandle'; 4 | 5 | export {default as sortableContainer} from './SortableContainer'; 6 | export {default as sortableElement} from './SortableElement'; 7 | export {default as sortableHandle} from './SortableHandle'; 8 | 9 | export {arrayMove} from './utils'; 10 | -------------------------------------------------------------------------------- /pages/server/guild_id/utility.jsx: -------------------------------------------------------------------------------- 1 | import Command from '@component/Command' 2 | import PagesTitle from '@component/PagesTitle' 3 | import { utilityCommands } from '@script/commands' 4 | 5 | const Utility = () => ( 6 | <> 7 | 13 | {utilityCommands.map((command, index) => ( 14 | 15 | ))} 16 | 17 | ) 18 | export default Utility 19 | -------------------------------------------------------------------------------- /pages/memberships/manage.tsx: -------------------------------------------------------------------------------- 1 | import ManagePremiumLayout from '@component/Memberships/Manage' 2 | import { Context } from '@script/_context' 3 | import { useRouter } from 'next/router' 4 | import * as React from 'react' 5 | 6 | export default function ManagePremium() { 7 | const router = useRouter() 8 | const { user } = React.useContext(Context) 9 | 10 | if (!user.membership_tier) { 11 | router.push('/memberships') 12 | 13 | return null 14 | } 15 | return 16 | } 17 | -------------------------------------------------------------------------------- /pages/login/token/index.jsx: -------------------------------------------------------------------------------- 1 | import { Context } from "@script/_context"; 2 | import { useRouter } from "next/router" 3 | import { useContext, useEffect } from "react" 4 | 5 | export default function LoginIntoGuild(){ 6 | const router = useRouter(); 7 | const {login} = useContext(Context); 8 | useEffect(() => { 9 | if(!login || !router.query.token) return; 10 | login(router.query.token); 11 | 12 | router.push(`/dashboard`); 13 | },[login, router.query.token]) 14 | return <>Redirecting ... 15 | } -------------------------------------------------------------------------------- /components/premium/StatusIcon.jsx: -------------------------------------------------------------------------------- 1 | export default function StatusIcon({ color, height, width }) { 2 | return ( 3 | 10 | 11 | 19 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /pages/login/token/guild.jsx: -------------------------------------------------------------------------------- 1 | import { Context } from "@script/_context"; 2 | import { useRouter } from "next/router" 3 | import { useContext, useEffect } from "react" 4 | 5 | export default function LoginIntoGuild(){ 6 | const router = useRouter(); 7 | const {login} = useContext(Context); 8 | useEffect(() => { 9 | if(!login || !router.query.token) return; 10 | login(router.query.token); 11 | 12 | router.push(`/server/${router.query.guild}`); 13 | },[login, router.query.token]) 14 | return <>Redirecting ... 15 | } -------------------------------------------------------------------------------- /components/InfoIconWithText.jsx: -------------------------------------------------------------------------------- 1 | import Tooltip from "rc-tooltip"; 2 | 3 | export default function InfoIconWithText({ ms = 2, text, ...props }) { 4 | return ( 5 | <> 6 | 12 | e.preventDefault()} 15 | {...props} 16 | > 17 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /public/static/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/static/checkout/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /components/emoji-picker/EmojiDescription.jsx: -------------------------------------------------------------------------------- 1 | import Emoji from "./Emoji"; 2 | import styles from "./style.module.css"; 3 | 4 | export default function EmojiDescription({ hoveredEmoji }) { 5 | return ( 6 |
7 |
8 | {hoveredEmoji ? : "☝"} 9 |
10 |
11 |

14 | {hoveredEmoji ? `:${hoveredEmoji.id}:` : "Pick an emoji.."} 15 |

16 |
17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /public/static/menu-nav-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /public/static/landing/tick-premium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/static/landing/features/embed/embed-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /public/static/landing/tick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /styles/colors.module.css: -------------------------------------------------------------------------------- 1 | .row { 2 | display: flex; 3 | } 4 | .row > * { 5 | width: 50%; 6 | } 7 | .row > div:last-child { 8 | margin-inline-start: 1rem; 9 | } 10 | .upload { 11 | width: 100%; 12 | } 13 | #background-select { 14 | margin-inline-start: 0; 15 | } 16 | @media screen and (max-width: 769px) { 17 | .row { 18 | display: flex; 19 | flex-direction: column; 20 | } 21 | .row > * { 22 | width: 100%; 23 | } 24 | .row > div:last-child { 25 | margin-inline-start: 0; 26 | } 27 | .row > div { 28 | margin-top: 10px; 29 | } 30 | .row:first-child > div:first-child { 31 | margin-top: 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /components/LandingPage/index.js: -------------------------------------------------------------------------------- 1 | import Navbar from "./Navbar" 2 | import Stats from './Stats' 3 | import Footer from "./Footer" 4 | import Features from './FeaturesSection' 5 | import Hero from './Hero' 6 | import Plans from './PremiumPage/Plans' 7 | import PricingTable from './PremiumPage/PricingTable' 8 | import FaqPremium from './PremiumPage/FAQ' 9 | import FeatureHero from './FeaturePage/FeatureHero' 10 | import FeatureTags from './FeaturePage/FeatureTags' 11 | import OtherFeatures from './FeaturePage/OtherFeatures' 12 | 13 | export { 14 | Navbar, 15 | Stats, 16 | Footer, 17 | Features, 18 | Hero, 19 | Plans, 20 | PricingTable, 21 | FaqPremium, 22 | FeatureHero, 23 | FeatureTags, 24 | OtherFeatures 25 | } -------------------------------------------------------------------------------- /components/react-sortable-hoc/SortableContainer/defaultShouldCancelStart.js: -------------------------------------------------------------------------------- 1 | import {NodeType, closest} from '../utils'; 2 | 3 | export default function defaultShouldCancelStart(event) { 4 | // Cancel sorting if the event target is an `input`, `textarea`, `select` or `option` 5 | const interactiveElements = [ 6 | NodeType.Input, 7 | NodeType.Textarea, 8 | NodeType.Select, 9 | NodeType.Option, 10 | NodeType.Button, 11 | ]; 12 | 13 | if (interactiveElements.indexOf(event.target.tagName) !== -1) { 14 | // Return true to cancel sorting 15 | return true; 16 | } 17 | 18 | if (closest(event.target, (el) => el.contentEditable === 'true')) { 19 | return true; 20 | } 21 | 22 | return false; 23 | } 24 | -------------------------------------------------------------------------------- /pages/markdown.jsx: -------------------------------------------------------------------------------- 1 | // import Editor from "@component/Editor"; 2 | import { useState } from "react"; 3 | 4 | export default function Mark() { 5 | const [value, setValue] = useState(""); 6 | return ( 7 |
8 |

Lexical Textarea

9 | {/* setValue(val)} /> */} 10 | 11 |

Normal Textarea

12 | 19 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /public/static/checkout/cvv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /styles/Notfound.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | text-align: center; 3 | } 4 | 5 | .not-found-img { 6 | margin-top: 100px; 7 | width: 40%; 8 | user-select: none; 9 | pointer-events: none; 10 | } 11 | 12 | .not-found-button { 13 | border: none; 14 | background-color: var(--purple); 15 | padding: 9px 30px; 16 | color: var(--white); 17 | border-radius: 20px; 18 | transition: all 0.3s; 19 | cursor: pointer; 20 | text-transform: capitalize; 21 | } 22 | 23 | .not-found-button:hover { 24 | filter: drop-shadow(4px 4px 120px var(--hover-purple)); 25 | transition: all 0.3s; 26 | } 27 | @media screen and (max-width: 768px) { 28 | .not-found-img { 29 | width: 100%; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /components/LandingPage/LoadingSpinner.tsx: -------------------------------------------------------------------------------- 1 | export default function LoadingSpinner() { 2 | return ( 3 | 9 | 17 | 22 | 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /pages/404.jsx: -------------------------------------------------------------------------------- 1 | import strings from "@script/locale"; 2 | import Head from "next/head"; 3 | import style from "@style/Notfound.module.css"; 4 | import { useContext } from "react"; 5 | import { Context } from "@script/_context"; 6 | 7 | export default function NotFound() { 8 | useContext(Context); 9 | return ( 10 | <> 11 | 12 | {"Not found"} - {strings.probot} 13 | 14 |
15 | not-found 16 |

The page you're looking for can't be found.

17 | 18 |
19 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /components/LandingPage/FeaturePage/Features.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react' 2 | import { Button } from '../Button' 3 | import Feature from '../Feature' 4 | import AOS from 'aos' 5 | import 'aos/dist/aos.css' 6 | 7 | type Feature = { 8 | id: number 9 | title: string 10 | desc: string 11 | btn: string 12 | img: string 13 | reversed: boolean 14 | link: string 15 | icon: string 16 | } 17 | 18 | export default function Features({ features }: { features: Feature[] }) { 19 | useEffect(() => { 20 | AOS.init() 21 | }, []) 22 | 23 | return ( 24 |
25 | {features.map((feature, index) => ( 26 | 27 | ))} 28 |
29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /components/ReactionRoles/SwitchType.jsx: -------------------------------------------------------------------------------- 1 | import strings from "@script/locale"; 2 | 3 | export default function SwitchType({ switchType, onChangeSwitch }) { 4 | const TYPES = [ 5 | { key: 2, label: strings.rr_buttons }, 6 | { key: 3, label: strings.rr_select_menu }, 7 | { key: 0, label: strings.rr_reaction }, 8 | ]; 9 | return ( 10 |
11 | {TYPES.map(({ key, label }) => ( 12 | 24 | ))} 25 |
26 | ); 27 | } -------------------------------------------------------------------------------- /pages/emoji-picker.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import EmojiPicker from "@component/emoji-picker"; 3 | 4 | export default function EmojiPickerPage() { 5 | const [open, setOpen] = useState(false); 6 | const [text, setText] = useState(""); 7 | 8 | return ( 9 | <> 10 |
11 | { 15 | setText(text + emoji.native); 16 | setOpen(false); 17 | }} 18 | > 19 | 20 | 21 | setText(event.target.value)} 26 | /> 27 |
28 | 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /styles/variables.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --purple: #5865f2; 3 | --hover-purple: #344099; 4 | --hover-purple-low-opacity: rgba(88, 101, 242, 0.24); 5 | --white: #ffffff; 6 | --skeleton: #434350ab; 7 | --command-bg: #25252c; 8 | --text-color: #a5a5a8; 9 | --gray-0: #919198; 10 | --gray-1: #434350; 11 | --gray-2: #393943; 12 | --gray-3: #292930; 13 | --gray-3-4: #2c2c35; 14 | --gray-4: #1f1f25; 15 | --gray-5: #0c0c0f; 16 | --red: #ed4c5c; 17 | --orange: #f29358; 18 | --hover-red: #ed4c5c27; 19 | --pink: #eb459e; 20 | --pink-code: #ff50b9; 21 | --hover-pink: #f742aa42; 22 | --pink-labeltag: #4b0d32; 23 | --yellow: #fee75c; 24 | --green: #09a34f; 25 | --green-hover: #067437; 26 | --light-green: #42ffa7; 27 | --light-green-hover: #2cb274; 28 | --dark-green: #163828; 29 | --hover-gray-1: #70707c; 30 | --landing-bg: #131b21; 31 | 32 | --r-onboarding-step-arrow-size: 14px; 33 | } 34 | -------------------------------------------------------------------------------- /components/modal.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export function useOnClickOutside(refs, handler) { 4 | useEffect(() => { 5 | function listener(event) { 6 | if (refs.some(ref => !ref.current || ref.current.contains(event.target))) return; 7 | handler(event); 8 | } 9 | document.addEventListener("mousedown", listener); 10 | document.addEventListener("touchstart", listener); 11 | 12 | return () => { 13 | document.removeEventListener("mousedown", listener); 14 | document.removeEventListener("touchstart", listener); 15 | }; 16 | }, [refs, handler]); 17 | } 18 | 19 | export default function Modal({ children, isOpen, handler }) { 20 | const ref = useRef(null); 21 | useOnClickOutside([ref], handler); 22 | 23 | if (!isOpen) return <>; 24 | 25 | return ( 26 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /public/static/checkout/exp-date.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /components/LandingPage/FeaturePage/FeatureTags.tsx: -------------------------------------------------------------------------------- 1 | type FeatureTagData = { 2 | content: string[] 3 | color: string 4 | } 5 | 6 | export default function FeatureTags({ data }: { data: FeatureTagData }) { 7 | return ( 8 |
9 | {data.content.map((tag, index) => ( 10 |
21 | ))} 22 |
23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /components/ColorListPicker/constants.js: -------------------------------------------------------------------------------- 1 | export const DEFAULT_COLORS_LIST = [ 2 | { 3 | id: 0, 4 | name: "Venetian Red", 5 | color: "#F8371B", 6 | borderColor: "#F8371B50", 7 | background: "#F8371B20", 8 | }, 9 | { 10 | id: 1, 11 | name: "Pumpkin", 12 | color: "#F97C1B", 13 | borderColor: "#F97C1B50", 14 | background: "#F97C1B20", 15 | }, 16 | { 17 | id: 2, 18 | name: "Deep Lemon", 19 | color: "#FAC81C", 20 | borderColor: "#FAC81C50", 21 | background: "#FAC81C20", 22 | }, 23 | { 24 | id: 3, 25 | name: "Eucalyptus", 26 | color: "#42D1B5", 27 | borderColor: "#42D1B550", 28 | background: "#42D1B520", 29 | }, 30 | { 31 | id: 4, 32 | name: "Blue", 33 | color: "#2CAEF6", 34 | borderColor: "#2CAEF650", 35 | background: "#2CAEF620", 36 | }, 37 | { 38 | id: 5, 39 | name: "Purple", 40 | color: "#5865F2", 41 | borderColor: "#5865F250", 42 | background: "#5865F220", 43 | }, 44 | ]; 45 | -------------------------------------------------------------------------------- /public/static/block-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/static/landing/features/rr/rr-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /components/Streaks.jsx: -------------------------------------------------------------------------------- 1 | import { Context } from '@script/_context' 2 | import Tooltip from 'rc-tooltip' 3 | import { useContext } from 'react' 4 | import ScrollContainer from 'react-indiana-drag-scroll' 5 | 6 | export default function Streak({ streaks, id }) { 7 | const { user } = useContext(Context) 8 | 9 | return ( 10 |
11 | 12 | {streaks.map((streak, index) => ( 13 | 14 |
index ? ' streak-taken' : '' 17 | } ${user.streak_count === index ? 'active' : ''} ${ 18 | user.streak_count - 1 === index ? 'linear-gradient' : '' 19 | }`} 20 | > 21 | x{index + 1} 22 |
23 |
24 | ))} 25 |
26 |
27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /components/ReactionRoles/EmojisRows/index.jsx: -------------------------------------------------------------------------------- 1 | import Emoji from "@component/emoji-picker/Emoji"; 2 | import RolesList from "@component/roles_list"; 3 | 4 | export default function EmojisRowList({ reactions, handleChange, index }) { 5 | return ( 6 | <> 7 | {reactions.map((reaction, i) => ( 8 |
9 |
10 | 11 | 14 | handleChange("CHANGE_ROLES", index, { 15 | i, 16 | data, 17 | }) 18 | } 19 | /> 20 |
21 | 24 |
25 | ))} 26 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /public/static/questionmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /components/Input.jsx: -------------------------------------------------------------------------------- 1 | import strings from '@script/locale' 2 | 3 | export default function Input(props) { 4 | const { 5 | textarea, 6 | wrapperClassName, 7 | error, 8 | className, 9 | showErrorMessage = true, 10 | wrapperStyle, 11 | ...rest 12 | } = props 13 | 14 | if (textarea) { 15 | return ( 16 |
20 | 79 |
80 | ) 81 | } 82 | 83 | export function CountingComponent({ 84 | className, 85 | value: count, 86 | onChange, 87 | footer, 88 | min = 0, 89 | max = 9999999999999 90 | }) { 91 | return ( 92 | <> 93 |
96 | 102 | 106 | e.target.value < min 107 | ? onChange(Number(min)) 108 | : e.target.value > max 109 | ? onChange(Number(max)) 110 | : onChange(Number(e.target.value || 0)) 111 | } 112 | onChange={(event) => 113 | event.target.value >= min && 114 | onChange( 115 | event.target.value === '' ? '' : Number(event.target.value) 116 | ) 117 | } 118 | /> 119 | 129 |
130 | {footer &&
{footer}
} 131 | 132 | ) 133 | } 134 | -------------------------------------------------------------------------------- /components/LandingPage/PremiumPage/FAQ.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import strings from '@script/locale' 3 | 4 | function FAQitem({ q, a }) { 5 | const [isOpen, setIsOpen] = useState(false) 6 | 7 | const FAQ = [ 8 | { 9 | q: strings.premium_faq_question_1, 10 | a: strings.premium_faq_answer_1 11 | }, 12 | { 13 | q: strings.premium_faq_question_2, 14 | a: strings.premium_faq_answer_2 15 | }, 16 | { 17 | q: strings.premium_faq_question_3, 18 | a: strings.premium_faq_answer_3 19 | }, 20 | { 21 | q: strings.premium_faq_question_4, 22 | a: strings.premium_faq_answer_4 23 | }, 24 | { 25 | q: strings.premium_faq_question_5, 26 | a: strings.premium_faq_answer_5 27 | }, 28 | { 29 | q: strings.premium_faq_question_6, 30 | a: strings.premium_faq_answer_6 31 | } 32 | ] 33 | 34 | return ( 35 |
setIsOpen(!isOpen)} 40 | > 41 |

{q}

42 |
47 |
48 |

{a}

49 |
50 |
51 |
52 | ) 53 | } 54 | 55 | export default function FaqPremium() { 56 | const FAQ = [ 57 | { 58 | q: strings.premium_faq_question_1, 59 | a: strings.premium_faq_answer_1 60 | }, 61 | { 62 | q: strings.premium_faq_question_2, 63 | a: strings.premium_faq_answer_2 64 | }, 65 | { 66 | q: strings.premium_faq_question_3, 67 | a: strings.premium_faq_answer_3 68 | }, 69 | { 70 | q: strings.premium_faq_question_4, 71 | a: strings.premium_faq_answer_4 72 | }, 73 | { 74 | q: strings.premium_faq_question_5, 75 | a: strings.premium_faq_answer_5 76 | }, 77 | { 78 | q: strings.premium_faq_question_6, 79 | a: strings.premium_faq_answer_6 80 | } 81 | ] 82 | return ( 83 |
84 |
90 |

91 | {strings.membership_faq_title} 92 |

93 |

94 | {strings.formatString( 95 | strings.membership_faq_description, 96 | 97 | discord.gg/ProBot 98 | 99 | )} 100 |

101 |
102 |
108 | {FAQ.map((item, index) => ( 109 | 110 | ))} 111 |
112 |
113 | ) 114 | } 115 | -------------------------------------------------------------------------------- /public/static/landing/premium.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /components/emoji-picker/EmojisList.jsx: -------------------------------------------------------------------------------- 1 | import { Context } from "@script/_context"; 2 | import { useState, useRef, useEffect, useContext } from "react"; 3 | import { CATEGORY_LIST, EMOJIS } from "./constants"; 4 | import Emoji from "./Emoji"; 5 | import EmojiDescription from "./EmojiDescription"; 6 | import styles from "./style.module.css"; 7 | const EmojisList = ({ setRefs, search, onSelect, themeColor }) => { 8 | const [hoveredEmoji, setHoveredEmoji] = useState(null); 9 | const { guild } = useContext(Context); 10 | 11 | useEffect(() => { 12 | return () => { 13 | setHoveredEmoji(null); 14 | }; 15 | }, []); 16 | 17 | return ( 18 |
19 |
{} : () => {}} 22 | > 23 | {search 24 | ? [ 25 | ...(guild 26 | ? guild.emojis.map((emoji) => ({ 27 | id: emoji.id, 28 | name: emoji.name, 29 | short_names: [emoji.name], 30 | custom: true, 31 | category: "custom", 32 | })) 33 | : []), 34 | ...EMOJIS, 35 | ] 36 | .filter((emoji) => 37 | emoji.name.toLowerCase().includes(search.toLowerCase()) 38 | ) 39 | .filter((e) => { 40 | if (e.name.includes(`tone${themeColor}`)) return true; 41 | return !e.name.includes("tone"); 42 | }) 43 | .map((emoji, index) => ( 44 | 50 | )) 51 | : CATEGORY_LIST.filter((c) => 52 | c.id === 0 ? guild?.emojis?.length : true 53 | ).map((category, index) => ( 54 |
setRefs(node, index)} 58 | > 59 |
60 | {category.id === 0 ? guild.name : category.name} 61 |
62 | {[ 63 | ...(guild 64 | ? guild.emojis.map((emoji) => ({ 65 | id: emoji.id, 66 | name: emoji.name, 67 | short_names: [emoji.name], 68 | custom: true, 69 | category: "custom", 70 | animated: emoji.animated, 71 | })) 72 | : []), 73 | ...EMOJIS, 74 | ] 75 | .filter((e) => e.category === category.name.toLowerCase()) 76 | .filter((e) => { 77 | if (e.name.includes(`tone${themeColor}`)) return true; 78 | return !e.name.includes("tone"); 79 | }) 80 | .map((emojiItem, emojiIndex) => ( 81 | 87 | ))} 88 |
89 | ))} 90 |
91 |
92 | 93 |
94 |
95 | ); 96 | }; 97 | 98 | export default EmojisList; 99 | -------------------------------------------------------------------------------- /components/ReactionRoles/SkeletonLoading.jsx: -------------------------------------------------------------------------------- 1 | import { Context } from "@script/_context"; 2 | import { useContext } from "react"; 3 | import Skeleton, { SkeletonTheme } from "react-loading-skeleton"; 4 | 5 | export default function SkeletonLoading() { 6 | const { rtl } = useContext(Context); 7 | 8 | return ( 9 | <> 10 | 11 |
12 | 13 |
14 |
15 | 16 |
20 |
27 | 28 |
29 |
30 | 31 |
32 |
36 |
37 |
38 | 44 |
45 |
46 |
47 |
48 | 54 |
55 |
56 |
57 |
58 | 66 |
67 |
68 | 76 |
77 |
78 | 86 |
87 |
88 |
89 |
90 |
91 | 92 | ); 93 | } 94 | -------------------------------------------------------------------------------- /components/LandingPage/PremiumPage/Plans.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '../Button' 2 | import Link from 'next/link' 3 | import strings, { lang } from '@script/locale' 4 | 5 | export default function Plans({ yearly, monthly }) { 6 | const PlanInfo = [ 7 | { 8 | tier: 1, 9 | title: strings.formatString(strings.premium_tier_get, 1), 10 | price: monthly ? '5$' : '30$', 11 | descreption: strings.prime_description_2, 12 | features: [ 13 | strings.prime_features_1, 14 | strings.prime_features_2, 15 | strings.prime_features_3, 16 | strings.prime_features_4 17 | ] 18 | }, 19 | { 20 | tier: 2, 21 | title: strings.formatString(strings.premium_tier_get, 2), 22 | price: monthly ? '10$' : '60$', 23 | descreption: strings.premium_description_1, 24 | features: [ 25 | strings.prime_features_1, 26 | strings.prime_features_2, 27 | strings.premium_table_custom_bot, 28 | strings.premium_table_transfer_bot 29 | ], 30 | isSpecial: true 31 | } 32 | ] 33 | 34 | return ( 35 |
40 | {PlanInfo.map((plan, index) => ( 41 | 50 |
55 | {strings.premium_most_popular_tag} 56 |
57 |
58 |
59 |

60 | {plan.title} 61 |

62 |

63 | {plan.descreption} 64 |

65 |
66 |
67 |

{plan.price}

68 |

69 | {monthly ? `/${strings.monthly}` : `/${strings.yearly}`} 70 |

71 |
72 |
73 |
74 | {plan.features.map((feature, i) => ( 75 |
76 | 82 |

{feature}

{' '} 83 |
84 | ))} 85 |
86 | 93 | 94 | ))} 95 |
96 | ) 97 | } 98 | -------------------------------------------------------------------------------- /components/ui/dropdown.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' 3 | import { cn } from '@script/utils' 4 | 5 | const DropdownMenu = DropdownMenuPrimitive.Root 6 | 7 | const DropdownMenuTrigger = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }) => ( 11 | 17 | )) 18 | DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName 19 | 20 | const DropdownMenuGroup = DropdownMenuPrimitive.Group 21 | 22 | const DropdownMenuPortal = DropdownMenuPrimitive.Portal 23 | 24 | const DropdownMenuContent = React.forwardRef< 25 | React.ElementRef, 26 | React.ComponentPropsWithoutRef 27 | >(({ className, sideOffset = 4, ...props }, ref) => ( 28 | 29 | 37 | 38 | )) 39 | DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName 40 | 41 | const DropdownMenuItem = React.forwardRef< 42 | React.ElementRef, 43 | React.ComponentPropsWithoutRef & { 44 | inset?: boolean 45 | } 46 | >(({ className, inset, ...props }, ref) => ( 47 | 55 | )) 56 | DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName 57 | 58 | const DropdownMenuLabel = React.forwardRef< 59 | React.ElementRef, 60 | React.ComponentPropsWithoutRef & { 61 | inset?: boolean 62 | } 63 | >(({ className, inset, ...props }, ref) => ( 64 | 69 | )) 70 | DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName 71 | 72 | const DropdownMenuSeparator = React.forwardRef< 73 | React.ElementRef, 74 | React.ComponentPropsWithoutRef 75 | >(({ className, ...props }, ref) => ( 76 | 81 | )) 82 | DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName 83 | 84 | export { 85 | DropdownMenu, 86 | DropdownMenuTrigger, 87 | DropdownMenuContent, 88 | DropdownMenuItem, 89 | DropdownMenuLabel, 90 | DropdownMenuSeparator, 91 | DropdownMenuGroup, 92 | DropdownMenuPortal 93 | } 94 | --------------------------------------------------------------------------------