32 | {children ? (
33 | cloneElement(children, {
34 | onClick: () => !disabled && setShow(!show),
35 | })
36 | ) : (
37 |
!disabled && setShow(!show)}
39 | className={LogsStyle.color_picker}
40 | style={{ backgroundColor: [value] }}
41 | >
42 | )}
43 | {show && (
44 | <>
45 |
setShow(!show)}
54 | />
55 |
56 | >
57 | )}
58 |
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/components/illustrations/empty-responses.js:
--------------------------------------------------------------------------------
1 | export const EmptyResponses = () => (
2 |
9 |
10 |
17 |
25 |
33 |
34 |
35 |
44 |
53 |
54 |
63 |
72 |
73 | )
74 |
--------------------------------------------------------------------------------
/components/Memberships/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 | import style from '@style/userPremium.module.css'
3 | import UserPlansSwitcher from '@component/premium/UserPlans'
4 | import PlanItem from '@component/premium/PlanItem'
5 | import PlansFeaturesTalbe from '@component/premium/PlansFeaturesTalbe'
6 | import strings from '@script/locale'
7 | import { useContext } from 'react'
8 | import { Context } from '@script/_context'
9 |
10 | export const PLANS_DATA = [
11 | {
12 | item: 1001,
13 | icon: '/images/icons/silver.svg',
14 | amount: 5,
15 | type: 'silver'
16 | },
17 | {
18 | item: 1002,
19 | icon: '/images/icons/gold.svg',
20 | amount: 10,
21 | type: 'gold'
22 | },
23 | {
24 | item: 1003,
25 | icon: '/images/icons/diamond.svg',
26 | amount: 30,
27 | type: 'diamond'
28 | }
29 | ]
30 |
31 | export default function MembershipLayout() {
32 | const { user } = useContext(Context)
33 | const [plan, setPlan] = React.useState('yearly')
34 |
35 | return (
36 |
37 |
45 |
46 |
47 | {PLANS_DATA.map((planData, index) => (
48 |
49 | ))}
50 |
51 |
52 |
53 | )
54 | }
55 |
--------------------------------------------------------------------------------
/components/premium/method_checkout_full_iframe.jsx:
--------------------------------------------------------------------------------
1 | import Loading from "@component/loader";
2 | import { useEffect, useRef, useState } from "react";
3 | import CheckoutComForm from "./method_checkout";
4 | import Approved from "./status_approved";
5 | import Declined from "./status_declined";
6 |
7 | export default function CheckoutFullIframe({payText}){
8 | const [processing, processPayment] = useState(false);
9 | const [payment,paymentData] = useState(null);
10 | const checkoutForm = useRef(null);
11 |
12 | useEffect(() => {
13 | console.log("CHECKOUT OFOFOFOFF ", payment)
14 | },[payment]);
15 |
16 | const onPaymentMessage = (event) => {
17 | if (event.data?.type === "checkout_payment") {
18 | paymentData(event.data)
19 | console.log("got message checkout form", event.data, event);
20 | }
21 | };
22 |
23 | useEffect(() => {
24 | window.addEventListener("message", onPaymentMessage);
25 | return () => window.removeEventListener("message", onPaymentMessage);
26 | }, [onPaymentMessage]);
27 |
28 | if(payment?.redirect) return
38 | if(payment) return payment.approved ?
:
;
39 | if(processing) return
40 |
41 |
42 |
43 | return <>
44 |
45 |
46 | >
47 | }
--------------------------------------------------------------------------------
/components/ColorListPicker/index.jsx:
--------------------------------------------------------------------------------
1 | import ColorPicker from "@component/ColorPicker";
2 | import Image from "next/image";
3 | import { DEFAULT_COLORS_LIST } from "./constants";
4 |
5 | export default function ColorListPicker({ activeColor, onChange }) {
6 | const ACTIVE_COLOR_OBJECT = DEFAULT_COLORS_LIST.find(
7 | (item) => parseInt(item.color.replace("#", ""), 16) === activeColor
8 | );
9 |
10 | return (
11 |
12 | {DEFAULT_COLORS_LIST.map((item) => (
13 |
onChange(parseInt(item.color.replace("#", ""), 16))}
30 | data-color={item.color}
31 | />
32 | ))}
33 | onChange(parseInt(color.hex.replace("#", ""), 16))}
42 | >
43 |
44 |
45 |
46 | );
47 | }
48 |
--------------------------------------------------------------------------------
/styles/fields.module.css:
--------------------------------------------------------------------------------
1 | .outlinedInput,
2 | .filled-select-input {
3 | display: flex;
4 | flex-direction: column;
5 | }
6 | .outlinedInput input {
7 | outline: none;
8 | background-color: transparent;
9 | padding: 10px 15px;
10 | border: 1px solid #434350;
11 | border-radius: 12px;
12 | }
13 | .filled-select-input select {
14 | border-radius: 13px;
15 | }
16 | .filled-select-input select > option {
17 | border-radius: 13px !important;
18 | width: 2000px;
19 | margin: 10px;
20 | }
21 | .filled-input {
22 | border: none;
23 | outline: none;
24 | padding: 12px 16px 12px 16px;
25 | border-radius: 12px;
26 | background-color: var(--purple);
27 | }
28 | .filled-input:hover {
29 | opacity: 0.8;
30 | }
31 | .textarea-Outlined {
32 | display: flex;
33 | flex-direction: column;
34 | }
35 | .textarea-Outlined textarea {
36 | padding: 1rem;
37 | outline: none;
38 | resize: vertical;
39 | width: 100% !important;
40 | background-color: transparent;
41 | border-radius: 12px;
42 | border: 1px solid #434350;
43 | }
44 | .counting-input {
45 | width: 151.33px;
46 | display: flex;
47 | justify-content: space-between;
48 | align-items: center;
49 | padding: 5px;
50 | border: 1px solid var(--gray-1);
51 | border-radius: 12px;
52 | font-size: 14px;
53 | }
54 | .counting-input button {
55 | background-color: var(--gray-1);
56 | display: flex;
57 | justify-content: center;
58 | border-radius: 10px;
59 | min-width: 33px;
60 | min-height: 33px;
61 | font-size: 1rem;
62 | align-items: center;
63 | border: none;
64 | }
65 | .counting-input input {
66 | width: 90%;
67 | background: transparent;
68 | text-align: center;
69 | outline: none;
70 | border: none;
71 | }
72 | .counting-input__footer {
73 | color: var(--text-color);
74 | font-size: 0.8rem;
75 | margin: 0;
76 | margin-top: 5px;
77 | }
78 |
--------------------------------------------------------------------------------
/pages/dashboard.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import Head from 'next/head'
3 | import { Context } from '@script/_context'
4 | import style from '@style/overview.module.css'
5 | import strings from '@script/locale'
6 |
7 | export function Card({ title, icon, amount, colorsStyle, description }) {
8 | return (
9 |
10 |
11 |
12 |
13 |
{title}
14 | {description &&
{description}
}
15 |
16 |
17 |
18 | {typeof amount === 'string'
19 | ? amount.split('undefined').join('00')
20 | : amount?.toFixed().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,') ||
21 | '0000'}
22 |
23 |
24 | )
25 | }
26 |
27 | export default function Dashboard() {
28 |
29 | const { user } = useContext(Context)
30 |
31 | return (
32 |
33 |
34 |
35 | {strings.dashboard} - {strings.probot}
36 |
37 |
38 |
39 |
40 |
46 |
52 |
58 |
64 |
65 |
66 | )
67 | }
68 |
--------------------------------------------------------------------------------
/public/static/overlay_stars_1.svg:
--------------------------------------------------------------------------------
1 |
5 |
overlay_stars_1
--------------------------------------------------------------------------------
/components/SelectChannels/icons.tsx:
--------------------------------------------------------------------------------
1 | export const CATEGORY_ICON = (
2 |
9 |
15 |
16 | )
17 |
18 | export const CHANNEL_ICON = (
19 |
27 |
33 |
34 | )
35 |
--------------------------------------------------------------------------------
/components/Memberships/TransferData/OtpInput.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useRef, useContext } from 'react'
2 | import { Context } from '@script/_context'
3 |
4 | const OtpInput = ({
5 | setOtp,
6 | otp,
7 | placeholder
8 | }: {
9 | otp: string
10 | setOtp: React.Dispatch
>
11 | placeholder: string
12 | }) => {
13 | const { rtl } = useContext(Context)
14 | const inputRefs = useRef([])
15 | const MAX_LENGTH = 6
16 |
17 | const handleChange = (
18 | e: React.ChangeEvent,
19 | index: number
20 | ) => {
21 | const { value } = e.target
22 | const prevOtp = otp
23 | const otpArray = prevOtp.split('')
24 | otpArray[index] = value
25 |
26 | if (otpArray.join('').length >= MAX_LENGTH + 1) return
27 | setOtp(otpArray.join(''))
28 |
29 | if (value && inputRefs.current[index + 1]) {
30 | inputRefs.current[index + 1].focus()
31 | }
32 | }
33 |
34 | const handlePaste = (e: React.ClipboardEvent) => {
35 | const pasteData = e.clipboardData.getData('text/plain')
36 | const otpArray = pasteData.split('').slice(0, MAX_LENGTH)
37 | setOtp(otpArray.join(''))
38 | inputRefs.current[0].focus()
39 | }
40 |
41 | return (
42 |
43 | {Array.from({ length: MAX_LENGTH }, (_, index) => (
44 | handleChange(e, index)}
51 | onPaste={handlePaste}
52 | ref={(el) => (inputRefs.current[index] = el)}
53 | placeholder={placeholder}
54 | {...(index === 0 ? { autoFocus: true } : null)}
55 | />
56 | ))}
57 |
58 | )
59 | }
60 |
61 | export default OtpInput
62 |
--------------------------------------------------------------------------------
/styles/panelLogs.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | }
5 |
6 | .head {
7 | display: flex;
8 | justify-content: space-between;
9 | background-color: var(--gray-4);
10 | color: var(--text-color);
11 | padding: 2rem 4rem;
12 | border-radius: 13px 13px 0 0;
13 | font-weight: 700;
14 | position: relative;
15 | }
16 | .head > div {
17 | text-align: center;
18 | }
19 | .head > div:first-child {
20 | left: 60px;
21 | width: 100px;
22 | justify-content: flex-start;
23 | }
24 | .head > div:nth-child(2) {
25 | left: 39%;
26 | width: 200px;
27 | }
28 | .head > div:nth-child(3) {
29 | left: 65%;
30 | width: 100px;
31 | }
32 |
33 | .row {
34 | align-items: center;
35 | border-bottom: 4px solid var(--gray-3);
36 | background-color: var(--command-bg);
37 | padding: 1rem 2rem;
38 | display: flex;
39 | justify-content: space-between;
40 | }
41 | .row-action i {
42 | margin-inline-start: 1rem;
43 | color: var(--purple);
44 | }
45 | .user-info {
46 | padding-top: 1.5rem;
47 | display: flex;
48 | }
49 | .user-info p {
50 | margin: 0;
51 | word-break: break-word;
52 | width: 200px;
53 | }
54 | .user-info p:last-child {
55 | opacity: 0.5;
56 | }
57 | .user-info img {
58 | margin-inline-end: 1rem;
59 | border-radius: 50%;
60 | width: 43px;
61 | height: 43px;
62 | }
63 | /* @media screen and (max-width: 650px) {
64 | .row-date,
65 | .head > div:last-child {
66 | display: none;
67 | }
68 | .row-action {
69 | font-size: 1rem;
70 | overflow: hidden;
71 | max-width: 150px;
72 | text-overflow: ellipsis;
73 | white-space: nowrap;
74 | }
75 | .username_d {
76 | line-height: 1.5;
77 | font-size: 1rem;
78 | }
79 | .user_id {
80 | font-size: 10px;
81 | }
82 | .head {
83 | padding: 2rem;
84 | }
85 | .user-info img {
86 | width: 35px;
87 | height: 35px;
88 | }
89 | } */
90 |
--------------------------------------------------------------------------------
/styles/transactions.module.css:
--------------------------------------------------------------------------------
1 | #container {
2 | overflow: auto;
3 | border-radius: 20px;
4 | border: 1px solid var(--gray-2) !important;
5 | }
6 | .user {
7 | justify-content: space-around;
8 | height: 60px;
9 | align-items: center;
10 | }
11 | .user-balance {
12 | width: 100px;
13 | display: flex;
14 | align-items: center;
15 | gap: 10px;
16 | }
17 | .user-balance img {
18 | margin-inline-start: 10px;
19 | }
20 | .user-info {
21 | width: 300px;
22 | align-items: center;
23 | display: flex;
24 | padding-inline-start: 2rem;
25 | padding-inline-end: 20px;
26 | }
27 | .user-info p {
28 | gap: 5px;
29 | margin: 0;
30 | unicode-bidi: plaintext;
31 | display: flex;
32 | direction: ltr;
33 | }
34 | .user-info img {
35 | user-select: none;
36 | pointer-events: none;
37 | width: 40px;
38 | height: 40px;
39 | border-radius: 50%;
40 | }
41 |
42 | .user-credits p {
43 | margin: 0;
44 | display: flex;
45 | }
46 |
47 | .user-date, .user-credits, .user-balance {
48 | width: 200px;
49 | }
50 |
51 | .table {
52 | width: 100%;
53 | }
54 |
55 | .head {
56 | height: 60px;
57 | background-color: var(--gray-2);
58 | margin-inline-start: 1rem;
59 | }
60 | .head > th:first-child {
61 | padding-inline-start: 2.5rem;
62 | }
63 | #container *:not(.border-bottom) {
64 | border: 0 !important;
65 | }
66 | .border-bottom {
67 | border-bottom: 1px solid #393943 !important;
68 | }
69 |
70 | /* media queries */
71 |
72 | @media screen and (max-width: 768px) {
73 | .user-info p {
74 | font-size: 13px;
75 | overflow: hidden;
76 | display: inline-block;
77 | text-overflow: ellipsis;
78 | white-space: nowrap;
79 | }
80 | }
81 |
82 | @media screen and (max-width: 376px) {
83 | #container {
84 | font-size: 10px;
85 | }
86 | .user-credits p {
87 | font-size: 10px;
88 | }
89 | .user-balance img {
90 | width: 8px;
91 | height: 5px;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/components/ui/button.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { cva, type VariantProps } from 'class-variance-authority'
3 | import PulseLoader from 'react-spinners/PulseLoader'
4 | import { cn } from '@script/utils'
5 |
6 | // usage:
7 | // {}}
12 | // >
13 | // Apply
14 | //
15 |
16 | const button = cva(
17 | 'tw-rounded-[5px] tw-border-0 tw-text-center tw-font-medium tw-text-white tw-outline-none tw-transition-colors tw-duration-200 tw-ease-in-out first-letter:tw-uppercase',
18 | {
19 | variants: {
20 | intent: {
21 | primary: ['tw-bg-purple-main hover:tw-bg-purple-hover'],
22 | secondary: ['tw-bg-grey-2 hover:tw-bg-grey-1'],
23 | ghost: ['tw-bg-transparent hover:tw-bg-grey-2'],
24 | danger: ['tw-bg-[#ED4C5C] hover:tw-bg-[#d03747]']
25 | },
26 | size: {
27 | xsmall: ['tw-text-sm tw-py-1 tw-px-2'],
28 | small: ['tw-text-base tw-py-2 tw-px-3'],
29 | medium: ['tw-text-s3 tw-px-5 tw-py-2 sm:tw-px-4 sm:tw-py-2']
30 | }
31 | },
32 | compoundVariants: [{ intent: 'primary', size: 'medium' }],
33 | defaultVariants: {
34 | intent: 'primary',
35 | size: 'medium'
36 | }
37 | }
38 | )
39 |
40 | export interface ButtonProps
41 | extends React.ButtonHTMLAttributes,
42 | VariantProps {
43 | isLoading?: boolean
44 | }
45 |
46 | export const Button = React.forwardRef(
47 | ({ className, children, intent, isLoading, size, ...props }) => {
48 | return (
49 |
54 | {isLoading ? (
55 |
60 | ) : (
61 | children
62 | )}
63 |
64 | )
65 | }
66 | )
67 | Button.displayName = 'Button'
68 |
--------------------------------------------------------------------------------
/components/Confirm.jsx:
--------------------------------------------------------------------------------
1 | import Modal from 'react-modal'
2 | import strings from '@script/locale'
3 | import { useContext } from 'react'
4 | import { Context } from '@script/_context'
5 |
6 | export default function Confirm({
7 | title,
8 | text,
9 | show,
10 | onConfirm,
11 | onCancel,
12 | loading = false
13 | }) {
14 | const { rtl } = useContext(Context)
15 |
16 | if (!show) return <>>
17 |
18 | return (
19 | document.getElementById('main')}
27 | >
28 |
29 |
30 |
31 |
{strings[title]}
32 |
33 |
34 |
35 |
36 |
{text}
37 |
38 |
39 |
{strings.never_mind}
40 |
41 | {strings.delete}
42 | {loading && (
43 |
49 |
57 |
62 |
63 | )}
64 |
65 |
66 |
67 |
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/pages/index.jsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable indent */
2 | import strings from '@script/locale'
3 | import {
4 | Navbar,
5 | Hero,
6 | Stats,
7 | Features,
8 | Footer
9 | } from '../components/LandingPage'
10 | import { Manrope } from 'next/font/google'
11 | import Image from 'next/image'
12 | import { useEffect } from 'react'
13 | import AOS from 'aos'
14 | import 'aos/dist/aos.css'
15 | import { useRouter } from 'next/router'
16 |
17 | const manrope = Manrope({
18 | subsets: ['latin']
19 | })
20 |
21 | function Home() {
22 | const { locale } = useRouter()
23 | useEffect(() => {
24 | AOS.init({ once: true })
25 | AOS.refresh()
26 | }, [])
27 |
28 | const sectionStyle = 'tw-max-w-[1240px] tw-m-auto tw-px-3 lg:tw-px-8'
29 |
30 | return (
31 | <>
32 |
41 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
65 |
66 |
67 |
74 |
75 |
76 | >
77 | )
78 | }
79 |
80 | export default Home
81 |
--------------------------------------------------------------------------------
/components/LandingPage/FeaturePage/OtherFeatures.tsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import Image from 'next/image'
3 | import strings from '@script/locale'
4 |
5 | export default function OtherFeatures({ features }) {
6 | return (
7 |
8 |
13 |
14 | {strings.feautres_learn_more_about_other}
15 |
16 |
17 |
21 | {features.map((feature: any, index: number) => (
22 |
33 |
34 |
41 |
42 | {feature.tag}
43 |
44 |
45 |
46 | {feature.headline}
47 |
48 |
49 | ))}
50 |
51 |
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/components/TooltipSlider.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import Slider from 'rc-slider';
3 | import type { SliderProps } from 'rc-slider';
4 | import raf from 'rc-util/lib/raf';
5 | import Tooltip from 'rc-tooltip';
6 |
7 | const HandleTooltip = (props: {
8 | value: number;
9 | children: React.ReactElement;
10 | visible: boolean;
11 | tipFormatter?: (value: number) => React.ReactNode;
12 | }) => {
13 | const { value, children, visible, tipFormatter = (val) => `${val}`, ...restProps } = props;
14 |
15 | const tooltipRef = React.useRef();
16 | const rafRef = React.useRef(null);
17 |
18 | function cancelKeepAlign() {
19 | raf.cancel(rafRef.current!);
20 | }
21 |
22 | function keepAlign() {
23 | rafRef.current = raf(() => {
24 | tooltipRef.current?.forcePopupAlign();
25 | });
26 | }
27 |
28 | React.useEffect(() => {
29 | if (visible) {
30 | keepAlign();
31 | } else {
32 | cancelKeepAlign();
33 | }
34 |
35 | return cancelKeepAlign;
36 | }, [value, visible]);
37 |
38 | return (
39 |
47 | {children}
48 |
49 | );
50 | };
51 |
52 | export const handleRender: SliderProps['handleRender'] = (node, props) => {
53 | return (
54 |
55 | {node}
56 |
57 | );
58 | };
59 |
60 | const TooltipSlider = ({
61 | tipFormatter,
62 | tipProps,
63 | ...props
64 | }: SliderProps & { tipFormatter?: (value: number) => React.ReactNode; tipProps: any }) => {
65 | const tipHandleRender: SliderProps['handleRender'] = (node, handleProps) => {
66 | return (
67 |
73 | {node}
74 |
75 | );
76 | };
77 |
78 | return ;
79 | };
80 |
81 | export default TooltipSlider;
--------------------------------------------------------------------------------
/components/LandingPage/FeaturesSection.tsx:
--------------------------------------------------------------------------------
1 | import Feature from './Feature'
2 | import 'aos/dist/aos.css'
3 | import strings from '@script/locale'
4 |
5 | export default function Features() {
6 | const featuresContent = [
7 | {
8 | id: 1,
9 | tag: strings.landing_welcome_messages_tag,
10 | title: strings.landing_welcome_messages_title,
11 | desc: strings.landing_welcome_messages_description,
12 | btn: strings.landing_welcome_messages_learn,
13 | img: 'static/landing/welcome.svg',
14 | reversed: true,
15 | link: '/features/welcome-messages',
16 | icon: 'static/landing/features/welcome/welcome-icon.svg'
17 | },
18 | {
19 | id: 2,
20 | tag: strings.embeder,
21 | title: strings.landing_embed_messages_title,
22 | desc: strings.landing_embed_messages_description,
23 | btn: strings.landing_embed_messages_learn,
24 | img: 'static/landing/embed.svg',
25 | reversed: false,
26 | link: '/features/embed-messages',
27 | icon: 'static/landing/features/embed/embed-icon.svg'
28 | },
29 | {
30 | id: 3,
31 | tag: strings.reaction_roles,
32 | title: strings.landing_self_assignable_roles_title,
33 | desc: strings.landing_self_assignable_roles_description,
34 | btn: strings.landing_self_assignable_roles_learn,
35 | img: 'static/landing/rr.svg',
36 | reversed: true,
37 | link: '/features/self-assignable-role',
38 | icon: 'static/landing/features/rr/rr-icon.svg'
39 | },
40 | {
41 | id: 4,
42 | tag: strings.index_card3_title,
43 | title: strings.landing_leveling_system_title,
44 | desc: strings.landing_leveling_system_description,
45 | btn: strings.landing_leveling_system_learn,
46 | img: 'static/landing/leveling.svg',
47 | reversed: false,
48 | link: '/features/leveling-system',
49 | icon: 'static/landing/features/leveling/leveling-icon.svg'
50 | }
51 | ]
52 | return (
53 |
57 | {featuresContent.map((feature, index) => (
58 |
59 | ))}
60 |
61 | )
62 | }
63 |
--------------------------------------------------------------------------------
/components/emoji-picker/constants.js:
--------------------------------------------------------------------------------
1 | import data from "./discord-emojis.json";
2 | const toneArray = [];
3 | export const EMOJIS = data.emojiDefinitions.map((emoji, i) => {
4 | return {
5 | id: emoji.primaryName,
6 | name: !emoji.primaryName.includes("_tone") && ["_tone1","_tone2","_tone3","_tone4","_tone5"].some((e) => data.emojiDefinitions[i+1]?.primaryName.endsWith(e)) ? `${emoji.primaryName}_tone0` : emoji.primaryName,
7 | native: emoji.surrogates,
8 | category: emoji.category,
9 | asset: emoji.assetFileName,
10 | };
11 | }).filter((e, i) => data.emojiDefinitions.findIndex((s) => s.assetFileName === e.asset) === i);
12 |
13 |
14 |
15 | //console.log(EMOJIS.filter(e => e.name?.includes("thumb")))
16 | export function getEmojiAsset(native){
17 | let emoji = data.emojiDefinitions.find((e) => e.surrogates === native);
18 | if(!emoji) return {};
19 | console.log("i'm running now lmao and i'm expensive on your browser")
20 | return emoji.assetFileName;
21 | }
22 |
23 | export const CATEGORY_LIST = [
24 | { id: 0, name: "Custom", icon: },
25 | {
26 | id: 1,
27 | name: "People",
28 | icon: ,
29 | },
30 | {
31 | id: 2,
32 | name: "Nature",
33 | icon: ,
34 | },
35 | { name: "Food", icon: },
36 | {
37 | id: 3,
38 | name: "Travel",
39 | icon: ,
40 | },
41 | { id: 4, name: "Activity", icon: },
42 | { id: 5, name: "Objects", icon: },
43 | { id: 6, name: "Symbols", icon: },
44 | { id: 7, name: "Flags", icon: },
45 | ];
46 |
47 | export const EMOJIS_THEME_COLOR_LIST = [
48 | {id: 0, name: "Default", emoji: "👏"},
49 | { id: 1, name: "Light Skin Tone", emoji: "👏🏻" },
50 | {
51 | id: 2,
52 | name: "Medium-Light Skin Tone",
53 | emoji: "👏🏼",
54 | },
55 | { id: 3, name: "Medium Skin Tone", emoji: "👏🏽" },
56 | {
57 | id: 4,
58 | name: "Medium-Dark Skin Tone",
59 | emoji: "👏🏾",
60 | },
61 | { id: 5, name: "Dark Skin Tone", emoji: "👏🏿" },
62 | ];
63 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "probot-next-setup",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@tailwindcss/aspect-ratio": "^0.4.2",
13 | "@tailwindcss/container-queries": "^0.1.1",
14 | "@tailwindcss/forms": "^0.5.6",
15 | "@tailwindcss/typography": "^0.5.10",
16 | "aos": "^2.3.4",
17 | "array-move": "^4.0.0",
18 | "axios": "^1.5.1",
19 | "class-variance-authority": "^0.7.0",
20 | "clsx": "^2.0.0",
21 | "crypto-js": "^4.1.1",
22 | "formik": "^2.4.5",
23 | "framer-motion": "^10.16.4",
24 | "highlight.js": "^11.9.0",
25 | "humanize-duration": "^3.30.0",
26 | "invariant": "^2.2.4",
27 | "lodash": "^4.17.21",
28 | "moment": "^2.29.4",
29 | "next": "13.5.4",
30 | "numeral": "^2.0.6",
31 | "popmotion": "^11.0.5",
32 | "probot-locale": "github:ProBotOrg/locale",
33 | "prop-types": "^15.8.1",
34 | "r-onboarding": "^2.1.0",
35 | "radix-ui": "^1.0.1",
36 | "rc-dropdown": "^4.1.0",
37 | "rc-slider": "^10.3.0",
38 | "rc-tooltip": "^6.1.1",
39 | "react": "^18",
40 | "react-color": "^2.19.3",
41 | "react-countup": "^6.4.2",
42 | "react-dom": "^18",
43 | "react-drag-drop-files": "^2.3.10",
44 | "react-fast-marquee": "^1.6.2",
45 | "react-indiana-drag-scroll": "^2.2.0",
46 | "react-loading-skeleton": "^3.3.1",
47 | "react-localization": "^1.0.19",
48 | "react-markdown": "^9.0.0",
49 | "react-modal": "^3.16.1",
50 | "react-select": "^5.7.7",
51 | "react-spinners": "^0.13.8",
52 | "react-switch": "^7.0.0",
53 | "react-turnstile": "^1.1.2",
54 | "socket.io-client": "^4.7.2",
55 | "sweetalert2": "^11.7.32",
56 | "tailwind-merge": "^1.14.0",
57 | "yup": "^1.3.2"
58 | },
59 | "devDependencies": {
60 | "@types/node": "^20",
61 | "@types/react": "^18",
62 | "@types/react-dom": "^18",
63 | "autoprefixer": "^10",
64 | "eslint": "^8",
65 | "eslint-config-next": "13.5.4",
66 | "mini-css-extract-plugin": "^2.7.6",
67 | "postcss": "^8",
68 | "tailwindcss": "^3",
69 | "typescript": "^5"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/public/static/commandIcon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/components/ReactionRoles/SelectMenus/index.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useContext } from "react";
2 | import SingleRow from "./SingleRow";
3 | import styles from "./styles.module.css";
4 | import strings from "@script/locale";
5 | import {
6 | SortableContainer,
7 | SortableItem,
8 | } from "pages/server/[guild_id]/reaction_roles";
9 | import { Context } from "@script/_context";
10 | import { arrayMoveImmutable } from "array-move";
11 |
12 | export default function SelectMenus({ reactions, handleChange, index }) {
13 | const { rtl } = useContext(Context);
14 | const [open, setOpen] = useState(false);
15 |
16 | const onSortEnd = ({ oldIndex, newIndex }) => {
17 | handleChange(
18 | "UPDATE_SELECT_OPTION_LOCATION",
19 | index,
20 | arrayMoveImmutable(reactions.options, oldIndex, newIndex)
21 | );
22 | };
23 |
24 | if (!reactions) return <>>;
25 | return (
26 |
27 |
28 |
29 | {strings.rr_select_menu_placeholder}
30 |
31 |
37 | handleChange("UPDATE_SELECT_MENU_PLACEHOLDER", index, value)
38 | }
39 | placeholder={strings.type_here}
40 | />
41 |
42 |
43 | {reactions.options.map((selectMenu, selectMenuIndex) => (
44 |
58 | setOpen(open === selectMenuIndex ? false : selectMenuIndex)
59 | }
60 | />
61 | }
62 | />
63 | ))}
64 |
65 |
66 | );
67 | }
68 |
--------------------------------------------------------------------------------
/components/premium/status_approved.jsx:
--------------------------------------------------------------------------------
1 | import strings from "@script/locale";
2 | export default function Approved({ msg }) {
3 | return (
4 |
5 |
12 |
13 |
17 |
24 |
25 |
26 |
27 | {strings.success}
28 | {msg ? msg : strings.billing_recharged_success}
29 |
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/components/LandingPage/Feature.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react'
2 | import { Button } from './Button'
3 | import Link from 'next/link'
4 | import Image from 'next/image'
5 |
6 | type featureData = {
7 | reversed: boolean
8 | tag?: string
9 | title: string
10 | desc: string
11 | btn: string
12 | img: string
13 | link: string
14 | icon: string
15 | }
16 |
17 | export default function Feature({ feature }: { feature: featureData }) {
18 | return (
19 |
29 |
30 | {/* Header */}
31 |
32 | {feature.tag ? (
33 |
34 |
35 |
42 |
43 |
{feature.tag}
44 |
45 | ) : null}
46 |
47 |
48 | {feature.title}
49 |
50 |
51 | {feature.desc}
52 |
53 |
54 |
55 | {/* CTA */}
56 |
57 |
58 |
59 | {feature.btn}
60 |
61 |
62 |
63 |
64 |
71 |
72 | )
73 | }
74 |
--------------------------------------------------------------------------------
/8e19c08bc4401c6c.css:
--------------------------------------------------------------------------------
1 | /* cyrillic-ext */
2 | @font-face {
3 | font-family: '__Manrope_8f5b94';
4 | font-style: normal;
5 | font-weight: 200 800;
6 | font-display: swap;
7 | src: url(/_next/static/media/78187650dd6b50b3-s.woff2) format('woff2');
8 | unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
9 | }
10 | /* cyrillic */
11 | @font-face {
12 | font-family: '__Manrope_8f5b94';
13 | font-style: normal;
14 | font-weight: 200 800;
15 | font-display: swap;
16 | src: url(/_next/static/media/4529092560591ab4-s.woff2) format('woff2');
17 | unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
18 | }
19 | /* greek */
20 | @font-face {
21 | font-family: '__Manrope_8f5b94';
22 | font-style: normal;
23 | font-weight: 200 800;
24 | font-display: swap;
25 | src: url(/_next/static/media/b8222d26e20b2e06-s.woff2) format('woff2');
26 | unicode-range: U+0370-03FF;
27 | }
28 | /* vietnamese */
29 | @font-face {
30 | font-family: '__Manrope_8f5b94';
31 | font-style: normal;
32 | font-weight: 200 800;
33 | font-display: swap;
34 | src: url(/_next/static/media/008f2e8b4aae291f-s.woff2) format('woff2');
35 | unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
36 | }
37 | /* latin-ext */
38 | @font-face {
39 | font-family: '__Manrope_8f5b94';
40 | font-style: normal;
41 | font-weight: 200 800;
42 | font-display: swap;
43 | src: url(/_next/static/media/3c46462b57ac880e-s.woff2) format('woff2');
44 | unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
45 | }
46 | /* latin */
47 | @font-face {
48 | font-family: '__Manrope_8f5b94';
49 | font-style: normal;
50 | font-weight: 200 800;
51 | font-display: swap;
52 | src: url(/_next/static/media/3534416bbfdcc9be-s.p.woff2) format('woff2');
53 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
54 | }@font-face {font-family: '__Manrope_Fallback_8f5b94';src: local("Arial");ascent-override: 102.96%;descent-override: 28.98%;line-gap-override: 0.00%;size-adjust: 103.53%
55 | }.__className_8f5b94 {font-family: '__Manrope_8f5b94', '__Manrope_Fallback_8f5b94';font-style: normal
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/components/premium/status_declined.jsx:
--------------------------------------------------------------------------------
1 | import strings from "@script/locale";
2 |
3 | export default function Declined({ payment }) {
4 | return (
5 |
6 |
13 |
14 |
20 |
27 |
28 |
29 |
30 | {strings.billing_payment_declined}
31 | {payment.response_summary
32 | ? payment.response_summary
33 | : payment.response_code}
34 |
35 |
36 | );
37 | }
38 |
--------------------------------------------------------------------------------
/public/static/topStar.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/components/react-sortable-hoc/AutoScroller/index.js:
--------------------------------------------------------------------------------
1 | export default class AutoScroller {
2 | constructor(container, onScrollCallback) {
3 | this.container = container;
4 | this.onScrollCallback = onScrollCallback;
5 | }
6 |
7 | clear() {
8 | if (this.interval == null) {
9 | return;
10 | }
11 |
12 | clearInterval(this.interval);
13 | this.interval = null;
14 | }
15 |
16 | update({translate, minTranslate, maxTranslate, width, height}) {
17 | const direction = {
18 | x: 0,
19 | y: 0,
20 | };
21 | const speed = {
22 | x: 1,
23 | y: 1,
24 | };
25 | const acceleration = {
26 | x: 10,
27 | y: 10,
28 | };
29 |
30 | const {
31 | scrollTop,
32 | scrollLeft,
33 | scrollHeight,
34 | scrollWidth,
35 | clientHeight,
36 | clientWidth,
37 | } = this.container;
38 |
39 | const isTop = scrollTop === 0;
40 | const isBottom = scrollHeight - scrollTop - clientHeight === 0;
41 | const isLeft = scrollLeft === 0;
42 | const isRight = scrollWidth - scrollLeft - clientWidth === 0;
43 |
44 | if (translate.y >= maxTranslate.y - height / 2 && !isBottom) {
45 | // Scroll Down
46 | direction.y = 1;
47 | speed.y =
48 | acceleration.y *
49 | Math.abs((maxTranslate.y - height / 2 - translate.y) / height);
50 | } else if (translate.x >= maxTranslate.x - width / 2 && !isRight) {
51 | // Scroll Right
52 | direction.x = 1;
53 | speed.x =
54 | acceleration.x *
55 | Math.abs((maxTranslate.x - width / 2 - translate.x) / width);
56 | } else if (translate.y <= minTranslate.y + height / 2 && !isTop) {
57 | // Scroll Up
58 | direction.y = -1;
59 | speed.y =
60 | acceleration.y *
61 | Math.abs((translate.y - height / 2 - minTranslate.y) / height);
62 | } else if (translate.x <= minTranslate.x + width / 2 && !isLeft) {
63 | // Scroll Left
64 | direction.x = -1;
65 | speed.x =
66 | acceleration.x *
67 | Math.abs((translate.x - width / 2 - minTranslate.x) / width);
68 | }
69 |
70 | if (this.interval) {
71 | this.clear();
72 | this.isAutoScrolling = false;
73 | }
74 |
75 | if (direction.x !== 0 || direction.y !== 0) {
76 | this.interval = setInterval(() => {
77 | this.isAutoScrolling = true;
78 | const offset = {
79 | left: speed.x * direction.x,
80 | top: speed.y * direction.y,
81 | };
82 | this.container.scrollTop += offset.top;
83 | this.container.scrollLeft += offset.left;
84 |
85 | this.onScrollCallback(offset);
86 | }, 5);
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/components/react-sortable-hoc/SortableElement/index.js:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import PropTypes from 'prop-types';
3 | import {findDOMNode} from 'react-dom';
4 | import invariant from 'invariant';
5 | import {SortableContext} from '../SortableContainer';
6 |
7 | import {provideDisplayName, omit} from '../utils';
8 |
9 | const propTypes = {
10 | index: PropTypes.number.isRequired,
11 | collection: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
12 | disabled: PropTypes.bool,
13 | };
14 |
15 | const omittedProps = Object.keys(propTypes);
16 |
17 | export default function sortableElement(
18 | WrappedComponent,
19 | config = {withRef: false},
20 | ) {
21 | return class WithSortableElement extends React.Component {
22 | static displayName = provideDisplayName(
23 | 'sortableElement',
24 | WrappedComponent,
25 | );
26 |
27 | static contextType = SortableContext;
28 |
29 | static propTypes = propTypes;
30 |
31 | static defaultProps = {
32 | collection: 0,
33 | };
34 |
35 | componentDidMount() {
36 | this.register();
37 | }
38 |
39 | componentDidUpdate(prevProps) {
40 | if (this.node) {
41 | if (prevProps.index !== this.props.index) {
42 | this.node.sortableInfo.index = this.props.index;
43 | }
44 |
45 | if (prevProps.disabled !== this.props.disabled) {
46 | this.node.sortableInfo.disabled = this.props.disabled;
47 | }
48 | }
49 |
50 | if (prevProps.collection !== this.props.collection) {
51 | this.unregister(prevProps.collection);
52 | this.register();
53 | }
54 | }
55 |
56 | componentWillUnmount() {
57 | this.unregister();
58 | }
59 |
60 | register() {
61 | const {collection, disabled, index} = this.props;
62 | const node = findDOMNode(this);
63 |
64 | node.sortableInfo = {
65 | collection,
66 | disabled,
67 | index,
68 | manager: this.context.manager,
69 | };
70 |
71 | this.node = node;
72 | this.ref = {node};
73 |
74 | this.context.manager.add(collection, this.ref);
75 | }
76 |
77 | unregister(collection = this.props.collection) {
78 | this.context.manager.remove(collection, this.ref);
79 | }
80 |
81 | getWrappedInstance() {
82 | invariant(
83 | config.withRef,
84 | 'To access the wrapped instance, you need to pass in {withRef: true} as the second argument of the SortableElement() call',
85 | );
86 | return this.wrappedInstance.current;
87 | }
88 |
89 | wrappedInstance = React.createRef();
90 |
91 | render() {
92 | const ref = config.withRef ? this.wrappedInstance : null;
93 |
94 | return ;
95 | }
96 | };
97 | }
98 |
--------------------------------------------------------------------------------
/components/premium/CouponCode.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from 'react'
2 | import axios from 'axios'
3 | import strings from '@script/locale'
4 |
5 | export default function CouponCode({
6 | amount,
7 | couponDiscount,
8 | setCouponDiscount
9 | }) {
10 | const [loading, setLoading] = useState(false)
11 | const [errorMessage, setErrorMessage] = useState('')
12 |
13 | const initCouponDiscountState = {
14 | discount: undefined,
15 | code: ''
16 | }
17 |
18 | const getAmount = (type, DiscountAmount) => {
19 | const types = {
20 | 1: amount - amount * (DiscountAmount / 100)
21 | }
22 |
23 | return types[type]
24 | }
25 |
26 | const checkCoupon = () => {
27 | if (couponDiscount.discount >= 0) {
28 | setCouponDiscount(initCouponDiscountState)
29 |
30 | return
31 | }
32 |
33 | if (!couponDiscount.code) return setErrorMessage(strings.billing_no_coupon)
34 |
35 | setLoading(true)
36 |
37 | axios
38 | .get(`/billing/coupons/${encodeURIComponent(couponDiscount.code)}`)
39 | .then(({ data }) => {
40 | setLoading(false)
41 | setCouponDiscount({
42 | ...couponDiscount,
43 | discount: getAmount(data.type, data.amount)
44 | })
45 | setErrorMessage('')
46 | })
47 | .catch(() => {
48 | setErrorMessage(strings.billing_invalid_coupon)
49 | setLoading(false)
50 | })
51 | }
52 |
53 | return (
54 |
55 |
{strings.billing_coupon_code}
56 |
88 | {errorMessage &&
{errorMessage}
}
89 |
90 | )
91 | }
92 |
--------------------------------------------------------------------------------
/components/LandingPage/FeaturePage/FeatureHero.tsx:
--------------------------------------------------------------------------------
1 | import { Button } from "../Button"
2 | import Image from 'next/image'
3 | import { useContext } from 'react'
4 | import Link from 'next/link'
5 | import { Context } from '@script/_context'
6 |
7 | type FeatureHeroData = {
8 | tag: string
9 | headline: string
10 | desc: string
11 | img: string
12 | featureIcon: string
13 | btnGetStarted: string
14 | color: string
15 | }
16 |
17 | export default function FeatureHero({ data }: { data: FeatureHeroData }) {
18 | const { auth, logged } = useContext(Context)
19 |
20 | return (
21 |
22 |
23 |
24 | {/* TAG */}
25 |
31 | {data.tag}
32 |
33 | {/* Headline */}
34 |
35 |
40 | {data.headline}
41 |
42 |
47 | {' '}
48 | {data.desc}
49 |
50 |
51 |
52 | {/* Buttons */}
53 |
58 | {logged ? (
59 |
60 |
64 | {data.btnGetStarted}
65 |
66 |
67 | ) : (
68 | auth('auth')} intent="secondary">
69 | {data.btnGetStarted}
70 |
71 | )}
72 |
73 |
74 |
75 |
76 |
83 |
84 |
85 | )
86 | }
87 |
--------------------------------------------------------------------------------
/components/react-sortable-hoc/SortableContainer/props.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import invariant from 'invariant';
3 |
4 | import {KEYCODE} from '../utils';
5 | import defaultGetHelperDimensions from './defaultGetHelperDimensions';
6 | import defaultShouldCancelStart from './defaultShouldCancelStart';
7 |
8 | export const propTypes = {
9 | axis: PropTypes.oneOf(['x', 'y', 'xy']),
10 | contentWindow: PropTypes.any,
11 | disableAutoscroll: PropTypes.bool,
12 | distance: PropTypes.number,
13 | getContainer: PropTypes.func,
14 | getHelperDimensions: PropTypes.func,
15 | helperClass: PropTypes.string,
16 | helperContainer: PropTypes.oneOfType([
17 | PropTypes.func,
18 | typeof HTMLElement === 'undefined'
19 | ? PropTypes.any
20 | : PropTypes.instanceOf(HTMLElement),
21 | ]),
22 | hideSortableGhost: PropTypes.bool,
23 | keyboardSortingTransitionDuration: PropTypes.number,
24 | lockAxis: PropTypes.string,
25 | lockOffset: PropTypes.oneOfType([
26 | PropTypes.number,
27 | PropTypes.string,
28 | PropTypes.arrayOf(
29 | PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
30 | ),
31 | ]),
32 | lockToContainerEdges: PropTypes.bool,
33 | onSortEnd: PropTypes.func,
34 | onSortMove: PropTypes.func,
35 | onSortOver: PropTypes.func,
36 | onSortStart: PropTypes.func,
37 | pressDelay: PropTypes.number,
38 | pressThreshold: PropTypes.number,
39 | keyCodes: PropTypes.shape({
40 | lift: PropTypes.arrayOf(PropTypes.number),
41 | drop: PropTypes.arrayOf(PropTypes.number),
42 | cancel: PropTypes.arrayOf(PropTypes.number),
43 | up: PropTypes.arrayOf(PropTypes.number),
44 | down: PropTypes.arrayOf(PropTypes.number),
45 | }),
46 | shouldCancelStart: PropTypes.func,
47 | transitionDuration: PropTypes.number,
48 | updateBeforeSortStart: PropTypes.func,
49 | useDragHandle: PropTypes.bool,
50 | useWindowAsScrollContainer: PropTypes.bool,
51 | };
52 |
53 | export const defaultKeyCodes = {
54 | lift: [KEYCODE.SPACE],
55 | drop: [KEYCODE.SPACE],
56 | cancel: [KEYCODE.ESC],
57 | up: [KEYCODE.UP, KEYCODE.LEFT],
58 | down: [KEYCODE.DOWN, KEYCODE.RIGHT],
59 | };
60 |
61 | export const defaultProps = {
62 | axis: 'y',
63 | disableAutoscroll: false,
64 | distance: 0,
65 | getHelperDimensions: defaultGetHelperDimensions,
66 | hideSortableGhost: true,
67 | lockOffset: '50%',
68 | lockToContainerEdges: false,
69 | pressDelay: 0,
70 | pressThreshold: 5,
71 | keyCodes: defaultKeyCodes,
72 | shouldCancelStart: defaultShouldCancelStart,
73 | transitionDuration: 300,
74 | useWindowAsScrollContainer: false,
75 | };
76 |
77 | export const omittedProps = Object.keys(propTypes);
78 |
79 | export function validateProps(props) {
80 | invariant(
81 | !(props.distance && props.pressDelay),
82 | 'Attempted to set both `pressDelay` and `distance` on SortableContainer, you may only use one or the other, not both at the same time.',
83 | );
84 | }
85 |
--------------------------------------------------------------------------------
/components/premium/PlanItem.jsx:
--------------------------------------------------------------------------------
1 | import { Context } from '@script/_context'
2 | import style from '@style/userPremium.module.css'
3 | import { useContext, useState } from 'react'
4 | import Checkout from './checkout'
5 | import strings from '../../scripts/locale'
6 | import Image from 'next/image'
7 |
8 | export default function PlanItem({ item, planType }) {
9 | const { rtl, user } = useContext(Context)
10 | const [openModal, setOpenModal] = useState(false)
11 |
12 | const handleSubscribe = (event) => {
13 | event.preventDefault()
14 | setOpenModal({
15 | item: item.item,
16 | type: 'new',
17 | name: `Membership Tier ${String(item.item).substring(3)}`,
18 | price: planType === 'yearly' ? item.amount / 2 : item.amount,
19 | period: planType === 'yearly' ? 2 : 1
20 | })
21 | }
22 |
23 | const handleUpgrade = (event) => {
24 | event.preventDefault()
25 | setOpenModal({
26 | item: item.item,
27 | type: 'upgrade',
28 | name: `Upgrade Membership to tier ${String(item.item).substring(3)}`,
29 | price: planType === 'yearly' ? item.amount / 2 : item.amount,
30 | period: planType === 'yearly' ? 2 : 1
31 | })
32 | }
33 |
34 | return (
35 | <>
36 |
40 |
46 |
47 |
48 |
{strings[`membership_${item.type}`]}
49 |
50 |
51 | ${planType === 'yearly' ? item.amount * 6 : item.amount}
52 |
53 | /{strings[planType]}
54 |
55 |
56 | {strings[`membership_${item.type}_description`]}
57 |
58 |
59 |
60 |
61 |
68 | {user.membership_tier ? strings.upgrade : strings.subscribe}
69 |
70 |
71 |
72 |
73 | {openModal && (
74 |
75 | )}
76 | >
77 | )
78 | }
79 |
--------------------------------------------------------------------------------
/components/LandingPage/Hero.tsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'react'
2 | import { Button } from './Button'
3 | import { Context } from '@script/_context'
4 | import strings from '@script/locale'
5 | import Link from 'next/link'
6 | import LoadingSpinner from './LoadingSpinner'
7 |
8 | export default function Hero() {
9 | const { auth, user, loading } = useContext(Context)
10 | const text = {
11 | tag: strings.landing_new_membership,
12 | headlind: strings.index_header_big_string,
13 | desc: strings.why_probot_text,
14 | btnAdd: strings.add_to_discord,
15 | btnBrowse: strings.browser_features
16 | }
17 |
18 | return (
19 |
20 |
21 |
22 | {/* TAG */}
23 |
27 | {text.tag}
28 |
29 | {/* Headline */}
30 |
31 |
36 | {text.headlind}
37 |
38 |
43 | {' '}
44 | {text.desc}
45 |
46 |
47 |
48 | {/* Buttons */}
49 |
54 | auth('authback')}
58 | >
59 | {text.btnAdd}
60 |
61 | {loading ? (
62 |
63 | ) : user ? (
64 |
65 |
66 | {strings.dashboard}
67 |
68 |
69 | ) : (
70 |
71 |
72 | {text.btnBrowse}
73 |
74 |
75 | )}
76 |
77 |
78 |
79 | )
80 | }
81 |
--------------------------------------------------------------------------------
/components/DragDropFiles/index.jsx:
--------------------------------------------------------------------------------
1 | import { FileUploader } from "react-drag-drop-files";
2 |
3 | export default function DragDropFiles({
4 | handleChange,
5 | uploadedFile,
6 | accept,
7 | height,
8 | width,
9 | className,
10 | ...props
11 | }) {
12 | return (
13 |
26 | {uploadedFile ? (
27 |
38 |
handleChange(null)}>
39 |
40 |
41 |
46 |
47 | ) : (
48 |
{
51 | handleChange(file);
52 | }}
53 | types={accept ? accept : "image/*"}
54 | multiple={false}
55 | children={
56 |
75 | }
76 | {...props}
77 | />
78 | )}
79 |
80 | );
81 | }
82 |
--------------------------------------------------------------------------------
/components/premium/RechargeAccountBalanceRow.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useContext, useEffect } from "react";
2 | import { Context } from "../../scripts/_context";
3 | import Checkout from "./checkout";
4 | import strings from "@script/locale";
5 |
6 | export default function RechargeAccountBalanceRow() {
7 | const { user } = useContext(Context);
8 | const [open, setOpen] = useState(false);
9 | const [amount, setAmount] = useState(5);
10 | const [openModal, setOpenModal] = useState(false);
11 |
12 | const handleSubmit = (event) => {
13 | event.preventDefault();
14 | if (amount >= 5) {
15 | setOpenModal({
16 | item: 5,
17 | type: "recharge",
18 | name: strings.transactions_amount,
19 | price: amount,
20 | });
21 | }
22 | };
23 |
24 |
25 |
26 | return (
27 | <>
28 |
29 |
30 |
31 | {strings.formatString(
32 | strings.billing_account_balance,
33 | user.balance
34 | )}
35 |
36 |
setOpen(!open)}
39 | >
40 |
41 | {strings.add_funds}
42 |
43 |
44 | {open && (
45 |
46 |
47 |
69 |
70 |
71 |
72 |
73 | $ {strings.billing_available_credit}
74 |
75 | ${user.balance} USD
76 |
77 |
78 |
79 | )}
80 |
81 | {openModal && }
82 | >
83 | );
84 | }
85 |
--------------------------------------------------------------------------------
/components/PagesTitle.jsx:
--------------------------------------------------------------------------------
1 | import Pt from '@style/PagesTitle.module.css'
2 | import Switch from 'react-switch'
3 | import axios from 'axios'
4 | import { useCallback, useContext } from 'react'
5 | import { Context } from '@script/_context'
6 | import strings from '@script/locale'
7 | import debounce from 'lodash/debounce'
8 | import Head from 'next/head'
9 |
10 | export default function PagesTitle({ needInput, className, data }) {
11 | const { guild, setGuild } = useContext(Context)
12 |
13 | const changeModule = useCallback(
14 | debounce((module, bool) => {
15 | axios.put(`/guilds/${guild.id}/modules/${encodeURIComponent(module)}`, {
16 | enabled: bool
17 | })
18 | }, 800),
19 | []
20 | )
21 |
22 | if (!data) return <>>
23 | return (
24 |
25 |
26 |
27 | {strings[data.name]} ({guild.name}) - {strings.probot}
28 |
29 |
30 |
31 |
{
34 | changeModule(data.module, !guild.modules[data.module])
35 | setGuild({
36 | ...guild,
37 | modules: {
38 | ...guild.modules,
39 | [data.module]: !guild.modules[data.module]
40 | }
41 | })
42 | }}
43 | >
44 | {strings[data.name] || data.name}
45 |
46 | {!!strings[data.description] && (
47 |
48 | {strings[data.description]}
49 |
50 | )}
51 |
52 |
53 | {data && data.module && (
54 | {
64 | changeModule(data.module, !guild.modules[data.module])
65 | setGuild({
66 | ...guild,
67 | modules: {
68 | ...guild.modules,
69 | [data.module]: !guild.modules[data.module]
70 | }
71 | })
72 | }}
73 | onColor="#42FFA7"
74 | handleDiameter={37}
75 | height={40}
76 | uncheckedIcon={false}
77 | checkedIcon={false}
78 | boxShadow="0px 1px 5px rgba(0, 0, 0, 0.6)"
79 | activeBoxShadow="0px 0px 1px 10px rgba(0, 0, 0, 0.2)"
80 | aria-label="reaction role"
81 | width={80}
82 | className="dramexSwi"
83 | id="material-switch"
84 | disabled={data.disabled}
85 | />
86 | )}
87 | {needInput && }
88 |
89 |
90 | )
91 | }
92 |
--------------------------------------------------------------------------------
/public/static/gradient1.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/pages/_app.jsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head'
2 | import { Sidebar } from '@component/sidebar'
3 | import Navbar from '@component/navbar'
4 | import strings, { lang } from '@script/locale'
5 | import '@style/global.css'
6 | import '@style/variables.css'
7 | import '@style/landing.css'
8 | import Provider from '@script/_context'
9 | import App from '@component/app'
10 | import { motion } from 'framer-motion'
11 | import Premium from './pricing'
12 | import '@component/embed/css/index.css'
13 | import '@component/embed/css/discord.css'
14 | import 'highlight.js/styles/base16/solarized-dark.css'
15 | import 'rc-tooltip/assets/bootstrap.css'
16 | import 'rc-slider/assets/index.css'
17 | import '@style/dropdown.css'
18 | import '@style/editor.css'
19 | import { useEffect } from 'react'
20 |
21 | function MyApp({ Component, router }) {
22 | if (router.locale) strings.setLanguage(router.locale)
23 | const excludedRoutes = [
24 | '/',
25 | '/pricing',
26 | '/commands',
27 | '/refund-policy',
28 | '/terms-of-use',
29 | '/privacy-policy'
30 | ]
31 |
32 | const dir = router.locale === 'ar' || router.locale === 'fa' ? 'rtl' : 'ltr'
33 | useEffect(() => {
34 | document.documentElement.dir = dir
35 | }, [dir])
36 |
37 | return (
38 | <>
39 |
40 | {strings.title}
41 |
45 |
50 |
55 | {Object.keys(lang)
56 | .filter((lang) => lang !== 'en')
57 | .map((key) => (
58 |
66 | ))}
67 |
68 |
69 | {excludedRoutes.includes(router.route) ||
70 | router.route.startsWith('/features') ? null : (
71 |
72 | )}
73 |
74 |
75 | {router.route !== '/' ? (
76 |
89 |
90 |
91 | ) : (
92 |
93 | )}
94 |
95 |
96 |
97 | >
98 | )
99 | }
100 |
101 | export default MyApp
102 |
--------------------------------------------------------------------------------
/components/AutoRoles/AssignRole.jsx:
--------------------------------------------------------------------------------
1 | import makeAnimated from "react-select/animated";
2 | import { ROLES_STYLES } from "@script/constants";
3 | import strings from "@script/locale";
4 | import { Context } from "@script/_context";
5 | import { useContext, useState } from "react";
6 | import Select from "react-select";
7 |
8 | export default function AssignRole({ data, setData }) {
9 | const { guild } = useContext(Context);
10 | const [openRow, setOpenRow] = useState(false);
11 |
12 | const removeTheAssign = () => {
13 | setData("delete");
14 | }
15 |
16 | return (
17 |
18 |
19 |
{data.invite || strings.no_link_provide}
20 |
21 |
setOpenRow(!openRow)}
24 | >
25 | {strings.EDIT}
26 |
27 |
28 | {strings.delete}
29 |
30 |
31 |
32 | {openRow && (
33 |
34 |
35 |
36 | {strings.autorole_select_roles}
37 |
38 | data.roles?.includes(r.id) && !r.managed)
43 | .map((r) => ({ label: r.name, value: r.id, color: r.color }))
44 | }
45 | onChange={(val) =>
46 | setData({
47 | roles: val ? val.map((val) => val.value) : [],
48 | })
49 | }
50 | classNamePrefix="formselect"
51 | components={makeAnimated()}
52 | options={
53 | guild?.roles &&
54 | guild?.roles
55 | .filter((role) => role.id !== guild?.id && !role.managed)
56 | .map((role) => ({
57 | label: role.name,
58 | value: role.id,
59 | color: role.color,
60 | }))
61 | }
62 | isMulti
63 | placeholder={strings.select_placeholder_select}
64 | styles={ROLES_STYLES}
65 | noOptionsMessage={() => strings.no_option}
66 | isDisabled={guild.botnumber < 2}
67 | />
68 |
69 |
70 |
71 | {strings.autorole_invite_link}
72 |
73 | setData({ invite: val.target.value })}
80 | disabled={guild.botnumber < 2}
81 | />
82 |
83 |
84 | )}
85 |
86 | );
87 | }
88 |
--------------------------------------------------------------------------------
/components/fields.jsx:
--------------------------------------------------------------------------------
1 | import inputs from '../styles/fields.module.css'
2 | export function FilledInput({ label, handleClick, className }) {
3 | return (
4 |
8 | {label}
9 |
10 | )
11 | }
12 |
13 | export function OutlinedInput({
14 | label,
15 | onChange,
16 | onClick,
17 | type,
18 | value,
19 | className,
20 | placeholder,
21 | id
22 | }) {
23 | return (
24 |
25 | {label && {label} }
26 |
34 |
35 | )
36 | }
37 |
38 | export function FilledSelectInput({
39 | label,
40 | children,
41 | className,
42 | id,
43 | labelClassName
44 | }) {
45 | return (
46 |
52 |
56 | {label}
57 |
58 | {children}
59 |
60 | )
61 | }
62 |
63 | export function Textarea({
64 | label,
65 | onChange,
66 | value,
67 | className,
68 | placeholder,
69 | id
70 | }) {
71 | return (
72 |
75 | {label && {label} }
76 |
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 | count > min && onChange(Number(count) - 1)}
99 | >
100 | -
101 |
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 |
122 | max
123 | ? count < max && onChange(Number(count) + 1)
124 | : onChange(Number(count) + 1)
125 | }
126 | >
127 | +
128 |
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 |
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 |
46 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
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 |
91 | {plan.title}
92 |
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 |
--------------------------------------------------------------------------------