├── .editorconfig ├── .env.development ├── .env.example ├── .env.production ├── .eslintrc.js ├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .npmrc ├── .prettierrc.js ├── .stylelintrc ├── .yarn └── releases │ └── yarn-1.22.19.cjs ├── .yarnrc.yml ├── LICENSE ├── README.md ├── build.bat ├── craco.config.js ├── package.json ├── public ├── Lightence-screenshot.png ├── favicon.ico ├── index.html ├── logo-dark-192.png ├── logo-dark-512.png ├── logo192.png ├── logo512.png ├── manifest.json ├── robots.txt └── spinners │ └── spinner.svg ├── sidebar-changes.patch ├── sidebar-clean.patch ├── src ├── @types │ ├── beforeinstallpromptevent.d.ts │ ├── bip-schnorr.d.ts │ ├── credit-cards.d.ts │ ├── event-target.d.ts │ └── react-app-env.d.ts ├── App.tsx ├── api │ ├── ApiError.ts │ ├── activity.api.ts │ ├── auth.api.ts │ ├── blockedPubkeys.api.ts │ ├── calendar.api.ts │ ├── covid.api.ts │ ├── doctors.api.ts │ ├── earnings.api.ts │ ├── http.api.ts │ ├── mocks │ │ ├── auth.api.mock.ts │ │ └── http.api.mock.ts │ ├── moderationStats.api.ts │ ├── news.api.ts │ ├── nftDashboard.api.ts │ ├── notifications.api.ts │ ├── paidSubscribers.ts │ ├── paymentCards.api.ts │ ├── paymentHistory.api.ts │ ├── paymentNotifications.api.ts │ ├── reportNotifications.api.ts │ ├── screenings.api.ts │ ├── statistics.api.ts │ ├── table.api.ts │ └── trendingCreators.ts ├── assets │ ├── admin-default-avatar.png │ ├── icons │ │ ├── arrow-down.svg │ │ ├── bones.svg │ │ ├── btc.svg │ │ ├── eth.svg │ │ ├── facebook.svg │ │ ├── fat.svg │ │ ├── google.svg │ │ ├── hive.svg │ │ ├── map-background.svg │ │ ├── marker-doctor.svg │ │ ├── marker-polyclinic.svg │ │ ├── media.svg │ │ ├── nft-icon.svg │ │ ├── pigeon.svg │ │ ├── protein.svg │ │ ├── stats.svg │ │ ├── storage-settings.svg │ │ └── water.svg │ ├── images │ │ ├── card-issuers │ │ │ ├── maestro.png │ │ │ ├── mastercard.png │ │ │ └── visa.png │ │ ├── error404.svg │ │ ├── login-bg.webp │ │ ├── new-lane.webp │ │ ├── nothing-found.webp │ │ ├── profile1.webp │ │ ├── profile10.webp │ │ ├── profile11.png │ │ ├── profile12.webp │ │ ├── profile13.webp │ │ ├── profile2.jpg │ │ ├── profile3.jpg │ │ ├── profile3.webp │ │ ├── profile4.webp │ │ ├── profile5.jpg │ │ ├── profile6.jpg │ │ ├── profile7.jpg │ │ ├── profile8.gif │ │ ├── profile9.gif │ │ ├── server-error.svg │ │ ├── stub-avatar.webp │ │ └── verify-email.webp │ ├── logo-dark-192.png │ ├── logo-dark-512.png │ ├── logo-dark-old.png │ ├── logo-dark.png │ ├── logo-old.png │ ├── logo.png │ └── map-data │ │ └── countries.geo.json ├── components │ ├── AuthGuard.tsx │ ├── Error │ │ ├── Error.styles.ts │ │ └── Error.tsx │ ├── PwaSupportChecker.tsx │ ├── SubscriptionTiersManager │ │ ├── SubscriptionTiersManager.tsx │ │ └── index.ts │ ├── apps │ │ └── newsFeed │ │ │ ├── NewsFeed.tsx │ │ │ ├── NewsFilter │ │ │ ├── NewsFilter.styles.ts │ │ │ └── NewsFilter.tsx │ │ │ └── Validator.ts │ ├── auth │ │ ├── ForgotPasswordForm │ │ │ ├── ForgotPasswordForm.styles.ts │ │ │ └── ForgotPasswordForm.tsx │ │ ├── LockForm │ │ │ ├── LockForm.styles.ts │ │ │ └── LockForm.tsx │ │ ├── LoginForm │ │ │ ├── LoginForm.styles.ts │ │ │ └── LoginForm.tsx │ │ ├── NewPasswordForm │ │ │ ├── NewPasswordForm.styles.ts │ │ │ └── NewPasswordForm.tsx │ │ ├── SecurityCodeForm │ │ │ ├── SecurityCodeForm.styles.ts │ │ │ └── SecurityCodeForm.tsx │ │ └── SignUpForm │ │ │ ├── SignUpForm.styles.tsx │ │ │ └── SignUpForm.tsx │ ├── blocked-pubkeys │ │ ├── BlockedPubkeys.styles.ts │ │ ├── BlockedPubkeys.tsx │ │ ├── components │ │ │ ├── BlockPubkeyForm.tsx │ │ │ ├── BlockedPubkeysTable.tsx │ │ │ └── FlaggedPubkeysTable.tsx │ │ └── index.ts │ ├── charts │ │ ├── BarAnimationDelayChart │ │ │ └── BarAnimationDelayChart.tsx │ │ ├── GradientStackedAreaChart │ │ │ └── GradientStackedAreaChart.tsx │ │ ├── LineRaceChart │ │ │ ├── LineRaceChart.tsx │ │ │ └── data.json │ │ ├── ScatterChart │ │ │ └── ScatterChart.tsx │ │ └── VisitorsPieChart.tsx │ ├── common │ │ ├── BaseAlert │ │ │ ├── BaseAlert.styles.ts │ │ │ └── BaseAlert.tsx │ │ ├── BaseArticle │ │ │ ├── BaseArticle.styles.ts │ │ │ └── BaseArticle.tsx │ │ ├── BaseAutoComplete │ │ │ └── BaseAutoComplete.tsx │ │ ├── BaseAvatar │ │ │ └── BaseAvatar.tsx │ │ ├── BaseBadge │ │ │ ├── BaseBadge.styles.ts │ │ │ └── BaseBadge.tsx │ │ ├── BaseBreadcrumb │ │ │ └── BaseBreadcrumb.tsx │ │ ├── BaseButton │ │ │ ├── BaseButton.styles.ts │ │ │ └── BaseButton.tsx │ │ ├── BaseCard │ │ │ ├── BaseCard.styles.ts │ │ │ └── BaseCard.tsx │ │ ├── BaseCarousel │ │ │ ├── Carousel.tsx │ │ │ └── CarouselArrow │ │ │ │ ├── CarouselArrow.styles.ts │ │ │ │ └── CarouselArrow.tsx │ │ ├── BaseCascader │ │ │ └── BaseCascader.tsx │ │ ├── BaseCheckbox │ │ │ ├── BaseCheckbox.styles.ts │ │ │ └── BaseCheckbox.tsx │ │ ├── BaseCol │ │ │ └── BaseCol.tsx │ │ ├── BaseCollapse │ │ │ └── BaseCollapse.tsx │ │ ├── BaseDivider │ │ │ └── BaseDivider.tsx │ │ ├── BaseDropdown │ │ │ └── Dropdown.tsx │ │ ├── BaseEmpty │ │ │ └── BaseEmpty.tsx │ │ ├── BaseFeed │ │ │ ├── BaseFeed.styles.ts │ │ │ └── BaseFeed.tsx │ │ ├── BaseHashTag │ │ │ ├── BaseHashTag.styles.ts │ │ │ └── BaseHashTag.tsx │ │ ├── BaseImage │ │ │ └── BaseImage.tsx │ │ ├── BaseLayout │ │ │ └── BaseLayout.tsx │ │ ├── BaseList │ │ │ └── BaseList.tsx │ │ ├── BaseMenu │ │ │ └── BaseMenu.tsx │ │ ├── BaseModal │ │ │ └── BaseModal.tsx │ │ ├── BaseNotification │ │ │ ├── BaseNotification.styles.ts │ │ │ └── BaseNotification.tsx │ │ ├── BasePagination │ │ │ ├── BasePagination.styles.ts │ │ │ └── BasePagination.tsx │ │ ├── BasePopconfirm │ │ │ └── BasePopconfirm.tsx │ │ ├── BasePopover │ │ │ └── BasePopover.tsx │ │ ├── BaseProgress │ │ │ └── BaseProgress.tsx │ │ ├── BaseRadio │ │ │ ├── BaseRadio.styles.ts │ │ │ └── BaseRadio.tsx │ │ ├── BaseRate │ │ │ ├── BaseRate.styles.ts │ │ │ └── BaseRate.tsx │ │ ├── BaseResult │ │ │ ├── BaseResult.styles.ts │ │ │ └── BaseResult.tsx │ │ ├── BaseRow │ │ │ └── BaseRow.tsx │ │ ├── BaseSkeleton │ │ │ └── BaseSkeleton.tsx │ │ ├── BaseSlider │ │ │ ├── BaseSlider.styles.ts │ │ │ └── BaseSlider.tsx │ │ ├── BaseSpace │ │ │ └── BaseSpace.tsx │ │ ├── BaseSpin │ │ │ └── BaseSpin.tsx │ │ ├── BaseSteps │ │ │ ├── BaseSteps.styles.ts │ │ │ └── BaseSteps.tsx │ │ ├── BaseSwitch │ │ │ ├── BaseSwitch.styles.ts │ │ │ └── BaseSwitch.tsx │ │ ├── BaseTable │ │ │ ├── BaseTable.styles.ts │ │ │ └── BaseTable.tsx │ │ ├── BaseTabs │ │ │ ├── BaseTabs.styles.ts │ │ │ └── BaseTabs.tsx │ │ ├── BaseTag │ │ │ └── BaseTag.tsx │ │ ├── BaseTooltip │ │ │ └── BaseTooltip.tsx │ │ ├── BaseTypography │ │ │ └── BaseTypography.tsx │ │ ├── BaseUpload │ │ │ └── BaseUpload.tsx │ │ ├── Burger │ │ │ └── BurgerIcon.tsx │ │ ├── CalendarSwitch │ │ │ ├── CalendarSwitch.styles.ts │ │ │ └── CalendarSwitch.tsx │ │ ├── CopyToClipboard │ │ │ └── CopyToClipboard.tsx │ │ ├── CountryMap │ │ │ ├── CountryMap.styles.ts │ │ │ └── CountryMap.tsx │ │ ├── DoctorProfile │ │ │ ├── DoctorProfile.styles.ts │ │ │ └── DoctorProfile.tsx │ │ ├── GlobalSpinner │ │ │ └── GlobalSpinner.tsx │ │ ├── Loading │ │ │ └── Loading.tsx │ │ ├── MoonSunSwitch │ │ │ ├── MoonSunSwitch.styles.ts │ │ │ └── MoonSunSwitch.tsx │ │ ├── NotFound │ │ │ ├── NotFound.styles.ts │ │ │ └── NotFound.tsx │ │ ├── Overlay │ │ │ └── Overlay.tsx │ │ ├── PageTitle │ │ │ └── PageTitle.tsx │ │ ├── RefForwardingBadge │ │ │ └── RefForwardingBadge.tsx │ │ ├── References │ │ │ ├── References.styles.ts │ │ │ └── References.tsx │ │ ├── RequireFullscreen │ │ │ └── RequireFullscreen.tsx │ │ ├── SplideCarousel │ │ │ └── SplideCarousel.tsx │ │ ├── charts │ │ │ ├── BaseChart.tsx │ │ │ ├── Legend │ │ │ │ ├── Legend.styles.ts │ │ │ │ └── Legend.tsx │ │ │ ├── PieChart.tsx │ │ │ └── PieChartCustomLegend.tsx │ │ ├── forms │ │ │ ├── BaseButtonsForm │ │ │ │ └── BaseButtonsForm.tsx │ │ │ ├── BaseForm │ │ │ │ └── BaseForm.tsx │ │ │ └── components │ │ │ │ ├── BaseButtonsGroup │ │ │ │ ├── BaseButtonsGroup.styles.ts │ │ │ │ └── BaseButtonsGroup.tsx │ │ │ │ ├── BaseFormItem │ │ │ │ └── BaseFormItem.ts │ │ │ │ ├── BaseFormList │ │ │ │ └── BaseFormList.ts │ │ │ │ └── BaseFormTitle │ │ │ │ └── BaseFormTitle.ts │ │ ├── icons │ │ │ ├── FacebookIcon.tsx │ │ │ ├── FilterIcon.tsx │ │ │ ├── ImageIcon.tsx │ │ │ ├── LinkedinIcon.tsx │ │ │ ├── MoonIcon.tsx │ │ │ ├── MusicIcon.tsx │ │ │ ├── SunIcon.tsx │ │ │ └── VideoIcon.tsx │ │ ├── inputs │ │ │ ├── BaseInput │ │ │ │ ├── BaseInput.styles.ts │ │ │ │ └── BaseInput.tsx │ │ │ ├── ClipboardInput │ │ │ │ └── ClipboardInput.tsx │ │ │ ├── InputNumber │ │ │ │ ├── InputNumber.styles.ts │ │ │ │ └── InputNumber.tsx │ │ │ ├── InputPassword │ │ │ │ ├── InputPassword.styles.ts │ │ │ │ └── InputPassword.tsx │ │ │ ├── OpenURLInput │ │ │ │ └── OpenURLInput.tsx │ │ │ ├── SearchInput │ │ │ │ ├── SearchInput.styles.ts │ │ │ │ └── SearchInput.tsx │ │ │ ├── SuffixInput │ │ │ │ ├── SuffixInput.styles.ts │ │ │ │ └── SuffixInput.tsx │ │ │ └── VerificationCodeInput │ │ │ │ ├── VerificationCodeInput.styles.ts │ │ │ │ └── VerificationCodeInput.tsx │ │ ├── pickers │ │ │ ├── BaseDatePicker.tsx │ │ │ ├── DayjsDatePicker.tsx │ │ │ └── TimeRangePicker.tsx │ │ └── selects │ │ │ ├── BaseSelect │ │ │ ├── BaseSelect.styles.ts │ │ │ └── BaseSelect.tsx │ │ │ ├── MonthSelect │ │ │ └── MonthSelect.tsx │ │ │ └── StatisticsSelect │ │ │ └── StatisticsSelect.tsx │ ├── forms │ │ ├── ControlForm │ │ │ ├── AddUserFormModal.tsx │ │ │ ├── ControlForm.styles.ts │ │ │ ├── ControlForm.tsx │ │ │ └── useResetFormOnCloseModal.ts │ │ ├── DynamicForm │ │ │ ├── DynamicForm.styles.ts │ │ │ └── DynamicForm.tsx │ │ ├── InputCode │ │ │ └── InputCode.tsx │ │ ├── StepForm │ │ │ ├── StepForm.styles.ts │ │ │ ├── StepForm.tsx │ │ │ └── Steps │ │ │ │ ├── Step1.tsx │ │ │ │ ├── Step2.tsx │ │ │ │ ├── Step3.tsx │ │ │ │ └── Step4.tsx │ │ └── ValidationForm │ │ │ └── ValidationForm.tsx │ ├── header │ │ ├── Header.styles.ts │ │ ├── Header.tsx │ │ ├── components │ │ │ ├── GithubButton │ │ │ │ └── GitHubButton.tsx │ │ │ ├── HeaderFullscreen │ │ │ │ └── HeaderFullscreen.tsx │ │ │ ├── HeaderSearch │ │ │ │ ├── HeaderSearch.styles.ts │ │ │ │ └── HeaderSearch.tsx │ │ │ ├── notificationsDropdown │ │ │ │ ├── NotificationsDropdown.tsx │ │ │ │ ├── NotificationsOverlay │ │ │ │ │ ├── NotificationsOverlay.styles.ts │ │ │ │ │ └── NotificationsOverlay.tsx │ │ │ │ ├── PaymentNotificationsOverlay │ │ │ │ │ ├── PaymentNotificationsOverlay.tsx │ │ │ │ │ └── index.ts │ │ │ │ └── ReportNotificationsOverlay │ │ │ │ │ ├── ReportNotificationsOverlay.tsx │ │ │ │ │ └── index.ts │ │ │ ├── profileDropdown │ │ │ │ ├── ProfileDropdown │ │ │ │ │ ├── ProfileDropdown.styles.ts │ │ │ │ │ └── ProfileDropdown.tsx │ │ │ │ └── ProfileOverlay │ │ │ │ │ ├── ProfileOverlay.styles.ts │ │ │ │ │ └── ProfileOverlay.tsx │ │ │ ├── searchDropdown │ │ │ │ ├── SearchDropdown.tsx │ │ │ │ └── searchOverlay │ │ │ │ │ ├── SearchFilter │ │ │ │ │ ├── SearchFilter.styles.ts │ │ │ │ │ └── SearchFilter.tsx │ │ │ │ │ ├── SearchOverlay │ │ │ │ │ ├── SearchOverlay.styles.ts │ │ │ │ │ └── SearchOverlay.tsx │ │ │ │ │ └── SearchResults │ │ │ │ │ ├── SearchResults.styles.ts │ │ │ │ │ └── SearchResults.tsx │ │ │ └── settingsDropdown │ │ │ │ ├── SettingsDropdown.tsx │ │ │ │ └── settingsOverlay │ │ │ │ ├── LanguagePicker │ │ │ │ └── LanguagePicker.tsx │ │ │ │ ├── ServerPicker │ │ │ │ └── SmartBaseModeSettings.tsx │ │ │ │ ├── SettingsOverlay │ │ │ │ ├── SettingsOverlay.styles.ts │ │ │ │ └── SettingsOverlay.tsx │ │ │ │ ├── ThemePicker │ │ │ │ └── ThemePicker.tsx │ │ │ │ └── nightModeSettings │ │ │ │ ├── NightModeSettings.tsx │ │ │ │ └── NightTimePicker │ │ │ │ ├── NightTimePicker.styles.ts │ │ │ │ └── NightTimePicker.tsx │ │ ├── dropdowns │ │ │ └── settingsDropdown │ │ │ │ └── settingsOverlay │ │ │ │ └── nightModeSettings │ │ │ │ └── NightTimeSlider │ │ │ │ ├── NightTimeSlider.styles.ts │ │ │ │ └── NightTimeSlider.tsx │ │ └── layouts │ │ │ ├── DesktopHeader.tsx │ │ │ └── MobileHeader.tsx │ ├── layouts │ │ ├── AuthLayout │ │ │ ├── AuthLayout.styles.ts │ │ │ └── AuthLayout.tsx │ │ └── main │ │ │ ├── MainContent │ │ │ └── MainContent.tsx │ │ │ ├── MainHeader │ │ │ ├── MainHeader.styles.ts │ │ │ └── MainHeader.tsx │ │ │ ├── MainLayout │ │ │ ├── MainLayout.styles.ts │ │ │ └── MainLayout.tsx │ │ │ └── sider │ │ │ ├── MainSider │ │ │ ├── MainSider.styles.ts │ │ │ └── MainSider.tsx │ │ │ ├── SiderLogo.tsx │ │ │ ├── SiderMenu │ │ │ ├── SiderMenu.styles.ts │ │ │ └── SiderMenu.tsx │ │ │ └── sidebarNavigation.tsx │ ├── media │ │ ├── MediaLayout.styles.ts │ │ ├── MediaLayout.tsx │ │ └── MediaManager │ │ │ ├── MediaItem │ │ │ ├── MediaItem.styles.ts │ │ │ └── MediaItem.tsx │ │ │ ├── MediaManager.styles.ts │ │ │ ├── MediaManager.tsx │ │ │ └── MediaViewer │ │ │ ├── MediaViewer.styles.ts │ │ │ └── MediaViewer.tsx │ ├── medical-dashboard │ │ ├── DashboardCard │ │ │ └── DashboardCard.tsx │ │ ├── HealthCard │ │ │ └── HealthCard.tsx │ │ ├── NewsCard │ │ │ ├── NewsCard.styles.ts │ │ │ └── NewsCard.tsx │ │ ├── PatientResultsCard │ │ │ ├── PatientResultsCard.styles.ts │ │ │ └── PatientResultsCard.tsx │ │ ├── activityCard │ │ │ ├── ActivityCard.tsx │ │ │ └── ActivityChart.tsx │ │ ├── bloodScreeningCard │ │ │ ├── BloodScreeningCard │ │ │ │ ├── BloodScreeningCard.styles.ts │ │ │ │ └── BloodScreeningCard.tsx │ │ │ ├── BloodScreeningChart │ │ │ │ └── BloodScreeningChart.tsx │ │ │ └── BloodScreeningTable │ │ │ │ ├── BloodScreeningTable.styles.ts │ │ │ │ └── BloodScreeningTable.tsx │ │ ├── covidCard │ │ │ ├── CovidCard.tsx │ │ │ └── CovidChart.tsx │ │ ├── favoriteDoctors │ │ │ ├── DoctorCard │ │ │ │ ├── DoctorCard.styles.ts │ │ │ │ └── DoctorCard.tsx │ │ │ └── FavoriteDoctorsCard │ │ │ │ ├── FavoritesDoctorsCard.styles.ts │ │ │ │ └── FavoritesDoctorsCard.tsx │ │ ├── mapCard │ │ │ ├── DoctorsMap │ │ │ │ ├── DoctorsMap.styles.ts │ │ │ │ └── DoctorsMap.tsx │ │ │ └── MapCard.tsx │ │ ├── screeningsCard │ │ │ ├── ScreeningsCard │ │ │ │ ├── ScreeningsCard.styles.ts │ │ │ │ └── ScreeningsCard.tsx │ │ │ ├── ScreeningsChart │ │ │ │ └── ScreeningsChart.tsx │ │ │ ├── ScreeningsHeader │ │ │ │ └── ScreeningsHeader.tsx │ │ │ └── screeningsFriends │ │ │ │ ├── DesktopScreenings │ │ │ │ ├── DesktopScreenings.styles.ts │ │ │ │ └── DesktopScreenings.tsx │ │ │ │ ├── MobileScreenings │ │ │ │ ├── MobileScreenings.styles.ts │ │ │ │ └── MobileScreenings.tsx │ │ │ │ ├── ScreeningsFriend │ │ │ │ ├── ScreeningsFriend.styles.ts │ │ │ │ └── ScreeningsFriend.tsx │ │ │ │ ├── ScreeningsFriends │ │ │ │ ├── ScreeningsFriends.styles.ts │ │ │ │ └── ScreeningsFriends.tsx │ │ │ │ └── interfaces.ts │ │ ├── statisticsCards │ │ │ ├── StatisticsCards.tsx │ │ │ └── statisticsCard │ │ │ │ ├── StatisticsCard │ │ │ │ ├── StatisticsCard.styles.ts │ │ │ │ └── StatisticsCard.tsx │ │ │ │ ├── StatisticsInfo │ │ │ │ ├── StatisticsInfo.styles.ts │ │ │ │ └── StatisticsInfo.tsx │ │ │ │ └── StatisticsProgress │ │ │ │ ├── StatisticsProgress.styles.ts │ │ │ │ └── StatisticsProgress.tsx │ │ └── treatmentCard │ │ │ ├── TreatmentCalendar │ │ │ ├── TreatmentCalendar.styles.ts │ │ │ └── TreatmentCalendar.tsx │ │ │ ├── TreatmentCard.tsx │ │ │ ├── TreatmentDoctor │ │ │ ├── TreatmentDoctor.styles.ts │ │ │ └── TreatmentDoctor.tsx │ │ │ ├── TreatmentNotFound │ │ │ ├── TreatmentNotFound.styles.ts │ │ │ └── TreatmentNotFound.tsx │ │ │ └── TreatmentPanel.tsx │ ├── nft-dashboard │ │ └── trending-creators │ │ │ └── SubscriberDetailModal │ │ │ ├── SubscriberDetailModal.styles.ts │ │ │ ├── SubscriberDetailModal.tsx │ │ │ └── index.ts │ ├── payment │ │ └── PaymentNotifications │ │ │ ├── PaymentNotifications.styles.ts │ │ │ ├── PaymentNotifications.tsx │ │ │ └── index.ts │ ├── profile │ │ ├── ProfileLayout.tsx │ │ └── profileCard │ │ │ ├── ProfileInfo │ │ │ ├── ProfileInfo.styles.ts │ │ │ └── ProfileInfo.tsx │ │ │ ├── ProfileNav │ │ │ ├── ProfileNav.styles.ts │ │ │ └── ProfileNav.tsx │ │ │ └── profileFormNav │ │ │ ├── ProfileFormNav.tsx │ │ │ └── nav │ │ │ ├── PersonalInfo │ │ │ ├── AddressItem │ │ │ │ └── AddressItem.tsx │ │ │ ├── BirthdayItem │ │ │ │ ├── BirthdayItem.styles.ts │ │ │ │ └── BirthdayItem.tsx │ │ │ ├── CitiesItem │ │ │ │ └── CitiesItem.tsx │ │ │ ├── CountriesItem │ │ │ │ ├── CountriesItem.styles.ts │ │ │ │ └── CountriesItem.tsx │ │ │ ├── EmailItem │ │ │ │ └── EmailItem.tsx │ │ │ ├── FirstNameItem │ │ │ │ └── FirstNameItem.tsx │ │ │ ├── LanguageItem │ │ │ │ └── LanguageItem.tsx │ │ │ ├── LastNameItem │ │ │ │ └── LastNameItem.tsx │ │ │ ├── NicknameItem │ │ │ │ └── NicknameItem.tsx │ │ │ ├── PersonalInfo.tsx │ │ │ ├── PhoneItem │ │ │ │ ├── PhoneItem.styles.ts │ │ │ │ └── PhoneItem.tsx │ │ │ ├── SexItem │ │ │ │ └── SexItem.tsx │ │ │ ├── SocialLinksItem │ │ │ │ └── SocialLinksItem.tsx │ │ │ ├── WebsiteItem │ │ │ │ └── WebsiteItem.tsx │ │ │ └── ZipcodeItem │ │ │ │ └── ZipcodeItem.tsx │ │ │ ├── SecuritySettings │ │ │ ├── SecuritySettings.tsx │ │ │ ├── passwordForm │ │ │ │ ├── ConfirmPasswordItem │ │ │ │ │ └── ConfirmPasswordItem.tsx │ │ │ │ ├── CurrentPasswordItem │ │ │ │ │ └── CurrentPasswordItem.tsx │ │ │ │ ├── NewPasswordItem │ │ │ │ │ └── NewPasswordItem.tsx │ │ │ │ └── PasswordForm │ │ │ │ │ ├── PasswordForm.styles.ts │ │ │ │ │ └── PasswordForm.tsx │ │ │ └── twoFactorAuth │ │ │ │ ├── TwoFactorAuth.styles.ts │ │ │ │ ├── TwoFactorAuth.tsx │ │ │ │ ├── TwoFactorOptions │ │ │ │ ├── TwoFactorOptions.styles.ts │ │ │ │ └── TwoFactorOptions.tsx │ │ │ │ └── TwoFactorSwitch │ │ │ │ └── TwoFactorSwitch.tsx │ │ │ ├── notifications │ │ │ ├── CheckboxColumn │ │ │ │ ├── CheckboxColumn.styles.ts │ │ │ │ └── CheckboxColumn.tsx │ │ │ ├── Notifications │ │ │ │ ├── Notifications.styles.ts │ │ │ │ └── Notifications.tsx │ │ │ ├── NotificationsTypes │ │ │ │ ├── NotificationsTypes.styles.ts │ │ │ │ └── NotificationsTypes.tsx │ │ │ └── interfaces.ts │ │ │ └── payments │ │ │ ├── Payments.tsx │ │ │ ├── paymentHistory │ │ │ ├── Payment │ │ │ │ ├── Payment.styles.ts │ │ │ │ └── Payment.tsx │ │ │ ├── PaymentHistory │ │ │ │ ├── PaymentHistory.styles.ts │ │ │ │ └── PaymentHistory.tsx │ │ │ ├── PaymentsTable │ │ │ │ ├── PaymentsTable.styles.ts │ │ │ │ └── PaymentsTable.tsx │ │ │ └── Status │ │ │ │ ├── Status.styles.ts │ │ │ │ └── Status.tsx │ │ │ └── paymentMethod │ │ │ ├── ActionButtons │ │ │ ├── ActionButtons.styles.ts │ │ │ └── ActionButtons.tsx │ │ │ ├── PaymentCard │ │ │ ├── PaymentCard.styles.ts │ │ │ └── PaymentCard.tsx │ │ │ ├── PaymentCardsWidget.tsx │ │ │ ├── PaymentMethod.tsx │ │ │ ├── addNewCard │ │ │ ├── AddNewCardButton │ │ │ │ ├── AddNewCardButton.styles.ts │ │ │ │ └── AddNewCardButton.tsx │ │ │ └── AddNewCardModal.tsx │ │ │ └── paymentForm │ │ │ ├── CVVItem │ │ │ └── CVVItem.tsx │ │ │ ├── CardNumberItem │ │ │ └── CardNumberItem.tsx │ │ │ ├── CardThemeItem │ │ │ ├── CardThemeItem.styles.ts │ │ │ └── CardThemeItem.tsx │ │ │ ├── CardholderItem │ │ │ └── CardholderItem.tsx │ │ │ ├── ExpDateItem │ │ │ └── ExpDateItem.tsx │ │ │ ├── PaymentForm │ │ │ ├── PaymentForm.styles.ts │ │ │ └── PaymentForm.tsx │ │ │ └── interfaces.ts │ ├── relay-dashboard │ │ ├── Balance │ │ │ ├── Balance.styles.ts │ │ │ ├── Balance.tsx │ │ │ ├── components │ │ │ │ ├── AddressList │ │ │ │ │ └── AddressList.tsx │ │ │ │ ├── SendButton │ │ │ │ │ └── SendButton.tsx │ │ │ │ ├── SendForm │ │ │ │ │ ├── SendForm.styles.ts │ │ │ │ │ ├── SendForm.tsx │ │ │ │ │ └── components │ │ │ │ │ │ ├── ResultScreen.styles.ts │ │ │ │ │ │ ├── ResultScreen.tsx │ │ │ │ │ │ ├── ResultScreen │ │ │ │ │ │ ├── ResultScreen.styles.ts │ │ │ │ │ │ └── ResultScreen.tsx │ │ │ │ │ │ └── TieredFees │ │ │ │ │ │ ├── TieredFees.styles.ts │ │ │ │ │ │ └── TieredFees.tsx │ │ │ │ ├── SendModal │ │ │ │ │ ├── SendModal.styles.ts │ │ │ │ │ └── SendModal.tsx │ │ │ │ ├── TopUpBalanceButton │ │ │ │ │ ├── TopUpBalanceButton.styles.ts │ │ │ │ │ └── TopUpBalanceButton.tsx │ │ │ │ ├── TopUpBalanceForm │ │ │ │ │ ├── TopUpBalanceForm.styles.ts │ │ │ │ │ └── TopUpBalanceForm.tsx │ │ │ │ ├── TopUpBalanceModal │ │ │ │ │ └── TopUpBalanceModal.tsx │ │ │ │ └── TopUpPaymentCard │ │ │ │ │ ├── TopUpPaymentCard.styles.ts │ │ │ │ │ └── TopUpPaymentCard.tsx │ │ │ └── interfaces │ │ │ │ └── interfaces.ts │ │ ├── common │ │ │ ├── NFTCard │ │ │ │ ├── NFTCard.styles.ts │ │ │ │ └── NFTCard.tsx │ │ │ ├── NFTCardHeader │ │ │ │ ├── NFTCardHeader.styles.ts │ │ │ │ └── NFTCardHeader.tsx │ │ │ └── ViewAll │ │ │ │ ├── ViewAll.styles.ts │ │ │ │ ├── ViewAll.tsx │ │ │ │ └── ViewTransactions.tsx │ │ ├── paid-subscribers │ │ │ ├── PaidSubscribers.styles.ts │ │ │ ├── PaidSubscribers.tsx │ │ │ ├── SubscriberDetailModal │ │ │ │ ├── SubscriberDetailModal.styles.ts │ │ │ │ ├── SubscriberDetailModal.tsx │ │ │ │ └── index.ts │ │ │ ├── avatar │ │ │ │ ├── SubscriberAvatar.styles.ts │ │ │ │ └── SubscriberAvatar.tsx │ │ │ └── index.ts │ │ ├── recentActivity │ │ │ ├── RecentActivity.styles.ts │ │ │ ├── RecentActivity.tsx │ │ │ ├── RecentActivityHeader │ │ │ │ └── RecentActivityHeader.tsx │ │ │ ├── recentActivityFeed │ │ │ │ ├── RecentActivityFeed.styles.ts │ │ │ │ ├── RecentActivityFeed.tsx │ │ │ │ └── RecentActivityItem │ │ │ │ │ ├── RecentActivityItem.styles.ts │ │ │ │ │ └── RecentActivityItem.tsx │ │ │ └── recentActivityFilters │ │ │ │ ├── RecentActivityFilter.styles.ts │ │ │ │ ├── RecentActivityFilter.tsx │ │ │ │ └── RecentActivityStatusFilter │ │ │ │ ├── RecentActivityStatusFilter.styles.ts │ │ │ │ └── RecentActivityStatusFilter.tsx │ │ ├── recently-added │ │ │ ├── RecentlyAddedNft.styles.ts │ │ │ ├── RecentlyAddedNft.tsx │ │ │ └── nft-card │ │ │ │ ├── NftCard.styles.ts │ │ │ │ └── NftCard.tsx │ │ ├── totalEarning │ │ │ ├── TotalEarning.styles.ts │ │ │ ├── TotalEarning.tsx │ │ │ └── TotalEarningChart │ │ │ │ └── TotalEarningChart.tsx │ │ ├── transactions │ │ │ ├── TransactionItem │ │ │ │ ├── TransactionItem.styles.ts │ │ │ │ └── TransactionItem.tsx │ │ │ ├── Transactions.styles.ts │ │ │ └── Transactions.tsx │ │ ├── trending-collections │ │ │ ├── TrendingCollections.styles.ts │ │ │ ├── TrendingCollections.tsx │ │ │ └── collection │ │ │ │ ├── TrendingCollection.styles.ts │ │ │ │ └── TrendingCollection.tsx │ │ ├── trending-creators │ │ │ ├── SubscriberDetailModal │ │ │ │ ├── SubscriberDetailModal.styles.ts │ │ │ │ ├── SubscriberDetailModal.tsx │ │ │ │ └── index.ts │ │ │ ├── TrendingCreators.styles.ts │ │ │ ├── TrendingCreators.tsx │ │ │ └── story │ │ │ │ ├── TrendingCreatorsStory.styles.ts │ │ │ │ └── TrendingCreatorsStory.tsx │ │ └── unconfirmed-transactions │ │ │ ├── UnconfirmedTransactions.styles.ts │ │ │ ├── UnconfirmedTransactions.tsx │ │ │ └── components │ │ │ ├── ButtonTrigger │ │ │ └── ButtonTrigger.tsx │ │ │ ├── Modal │ │ │ ├── UnconfirmedTxModal.styles.ts │ │ │ └── UnconfirmedTxModal.tsx │ │ │ ├── ReplaceTransaction │ │ │ ├── ReplaceTransaction.styles.ts │ │ │ └── ReplaceTransaction.tsx │ │ │ └── UnconfirmedTransaction │ │ │ ├── UnconfirmedTransaction.styles.ts │ │ │ └── UnconfirmedTransaction.tsx │ ├── relay-settings │ │ ├── layouts │ │ │ ├── DesktopLayout.tsx │ │ │ └── MobileLayout.tsx │ │ ├── sections │ │ │ ├── AppBucketsSection │ │ │ │ ├── AppBucketsSection.tsx │ │ │ │ ├── components │ │ │ │ │ ├── AddBucketForm.tsx │ │ │ │ │ ├── BucketsList.tsx │ │ │ │ │ └── DynamicBucketsList.tsx │ │ │ │ └── index.ts │ │ │ ├── KindsSection │ │ │ │ ├── KindsSection.tsx │ │ │ │ ├── components │ │ │ │ │ ├── AddKindForm.tsx │ │ │ │ │ ├── DynamicKindsList.tsx │ │ │ │ │ └── KindsList.tsx │ │ │ │ └── index.ts │ │ │ ├── MediaSection │ │ │ │ ├── MediaSection.tsx │ │ │ │ ├── components │ │ │ │ │ ├── MediaToggle.tsx │ │ │ │ │ └── MediaTypeList.tsx │ │ │ │ └── index.ts │ │ │ ├── ModerationSection │ │ │ │ ├── ModerationSection.tsx │ │ │ │ ├── components │ │ │ │ │ └── ModerationModeSelect.tsx │ │ │ │ └── index.ts │ │ │ ├── NetworkSection │ │ │ │ ├── NetworkSection.tsx │ │ │ │ ├── components │ │ │ │ │ ├── FileStorageToggle.tsx │ │ │ │ │ └── ProtocolSelect.tsx │ │ │ │ └── index.ts │ │ │ └── SubscriptionSection │ │ │ │ ├── SubscriptionSection.tsx │ │ │ │ └── index.ts │ │ └── shared │ │ │ ├── CollapsibleSection │ │ │ ├── CollapsibleSection.styles.ts │ │ │ ├── CollapsibleSection.tsx │ │ │ └── index.ts │ │ │ └── SectionCard │ │ │ ├── SectionCard.styles.ts │ │ │ ├── SectionCard.tsx │ │ │ └── index.ts │ ├── report │ │ └── ReportNotifications │ │ │ ├── ReportNotifications.styles.ts │ │ │ ├── ReportNotifications.tsx │ │ │ └── index.ts │ ├── router │ │ ├── AppRouter.tsx │ │ ├── Logout.tsx │ │ ├── RequireAdminAuth.tsx │ │ └── RequireAuth.tsx │ ├── settings │ │ ├── BaseSettingsForm.tsx │ │ ├── BaseSettingsPanel.tsx │ │ ├── ContentFilterSettings.tsx │ │ ├── GeneralSettings.tsx │ │ ├── ImageModerationSettings.tsx │ │ ├── NestFeederSettings.tsx │ │ ├── OllamaSettings.tsx │ │ ├── QueryCacheSettings.tsx │ │ ├── RelayInfoSettings.tsx │ │ ├── SettingsNavigation.tsx │ │ ├── SettingsPage.tsx │ │ ├── WalletSettings.tsx │ │ ├── layouts │ │ │ └── AdvancedSettingsLayout.tsx │ │ └── panels │ │ │ ├── ContentFilterPanel.tsx │ │ │ ├── GeneralSettingsPanel.tsx │ │ │ ├── ImageModerationPanel.tsx │ │ │ ├── NestFeederPanel.tsx │ │ │ ├── OllamaPanel.tsx │ │ │ ├── QueryCachePanel.tsx │ │ │ └── WalletPanel.tsx │ └── tables │ │ ├── BasicTable │ │ └── BasicTable.tsx │ │ ├── Tables │ │ ├── Tables.styles.ts │ │ └── Tables.tsx │ │ ├── TreeTable │ │ └── TreeTable.tsx │ │ └── editableTable │ │ ├── EditableCell.tsx │ │ └── EditableTable.tsx ├── config │ └── config.ts ├── constants │ ├── Dates.ts │ ├── bloodTestResults.ts │ ├── cardThemes.ts │ ├── categoriesList.ts │ ├── config │ │ ├── activityStatuses.tsx │ │ ├── components.ts │ │ ├── currencies.ts │ │ └── statistics.ts │ ├── dashboardNews.ts │ ├── defaultPaddings.ts │ ├── enums │ │ └── priorities.ts │ ├── healthChartData.ts │ ├── kindMapping.ts │ ├── languages.ts │ ├── maxNews.ts │ ├── modalSizes.ts │ ├── newsTags.ts │ ├── notificationsSeverities.ts │ ├── patientResultStatus.ts │ ├── patientResultsData.tsx │ ├── patterns.ts │ ├── paymentStatuses.ts │ ├── polyclinicsData.ts │ ├── profileNavData.tsx │ ├── relaySettings.ts │ └── specifities.ts ├── controllers │ └── notificationController.tsx ├── domain │ └── UserModel.ts ├── hocs │ └── withLoading.hoc.tsx ├── hooks │ ├── authUtils.ts │ ├── reduxHooks.ts │ ├── useActivityData.ts │ ├── useAutoNightMode.ts │ ├── useBalanceData.ts │ ├── useBarChartData.ts │ ├── useBitcoinRates.ts │ ├── useBlockedPubkeys.ts │ ├── useChartData.ts │ ├── useDebounce.ts │ ├── useDimensions.ts │ ├── useGenericSettings.ts │ ├── useIdleTimer.ts │ ├── useKindData.ts │ ├── useKindTrendData.ts │ ├── useLanguage.ts │ ├── useLineChartData.ts │ ├── useLogin.ts │ ├── useMedia.ts │ ├── useModerationStats.ts │ ├── useMounted.ts │ ├── useOnClickOutside.ts │ ├── usePWA.ts │ ├── usePaidSubscribers.ts │ ├── usePaymentNotifications.ts │ ├── usePendingTransactions.ts │ ├── useRelaySettings.ts │ ├── useReportNotifications.ts │ ├── useReportStats.ts │ ├── useResponsive.ts │ ├── useSignUp.ts │ ├── useSigner.ts │ ├── useThemeWatcher.ts │ ├── useTrendingCreators.ts │ └── useWalletAuth.ts ├── i18n.ts ├── index.tsx ├── interfaces │ └── interfaces.ts ├── locales │ ├── de │ │ └── translation.json │ └── en │ │ └── translation.json ├── pages │ ├── AdvancedFormsPage.tsx │ ├── BalancePage.tsx │ ├── BlockedPubkeysPage.tsx │ ├── ChartsPage.tsx │ ├── DashboardPages │ │ ├── DashboardPage.styles.ts │ │ ├── MedicalDashboardPage.tsx │ │ └── NftDashboardPage.tsx │ ├── DataTablesPage.tsx │ ├── Error404Page.tsx │ ├── ForgotPasswordPage.tsx │ ├── LockPage.tsx │ ├── LoginPage.tsx │ ├── MediaPage.tsx │ ├── NewPasswordPage.tsx │ ├── NewsFeedPage.tsx │ ├── NotificationsPage.tsx │ ├── PaymentNotificationsPage.tsx │ ├── PaymentsPage.tsx │ ├── PersonalInfoPage.tsx │ ├── RelaySettingsPage.tsx │ ├── RelayStatsPage.tsx │ ├── ReportNotificationsPage.tsx │ ├── SecurityCodePage.tsx │ ├── SecuritySettingsPage.tsx │ ├── ServerErrorPage.tsx │ ├── SignUpPage.tsx │ ├── maps │ │ ├── GoogleMapsPage │ │ │ └── GoogleMapsPage.tsx │ │ ├── LeafletMapsPage │ │ │ └── LeafletMapsPage.tsx │ │ ├── PigeonsMapsPage │ │ │ └── PigeonsMapsPage.tsx │ │ ├── ReactSimpleMapsPage │ │ │ └── ReactSimpleMapsPage.tsx │ │ └── maps.styles.ts │ └── uiComponentsPages │ │ ├── ButtonsPage.tsx │ │ ├── DropdownsPage.tsx │ │ ├── SpinnersPage.tsx │ │ ├── UIComponentsPage.styles.ts │ │ ├── dataDisplay │ │ ├── AvatarsPage.tsx │ │ ├── BadgesPage.tsx │ │ ├── CollapsePage.tsx │ │ └── PaginationPage.tsx │ │ ├── feedback │ │ ├── AlertsPage.tsx │ │ ├── NotificationsPage.tsx │ │ ├── ProgressPage.tsx │ │ ├── ResultsPage.tsx │ │ └── SkeletonsPage.tsx │ │ ├── forms │ │ ├── AutoCompletesPage.tsx │ │ ├── CheckboxesPage.tsx │ │ ├── DateTimePickersPage.tsx │ │ ├── InputsPage.tsx │ │ ├── RadiosPage.tsx │ │ ├── RatesPage.tsx │ │ ├── SelectsPage.tsx │ │ ├── StepsPage.tsx │ │ ├── SwitchesPage.tsx │ │ └── UploadsPage.tsx │ │ ├── modals │ │ ├── ModalsPage.tsx │ │ ├── PopconfirmsPage.tsx │ │ └── PopoversPage.tsx │ │ └── navigation │ │ ├── BreadcrumbsPage.tsx │ │ └── TabsPage.tsx ├── react-app-env.d.ts ├── reportWebVitals.ts ├── service-worker.ts ├── serviceWorkerRegistration.ts ├── services │ ├── authService.ts │ └── localStorage.service.ts ├── store │ ├── middlewares │ │ └── errorLogging.middleware.ts │ ├── slices │ │ ├── authSlice.ts │ │ ├── index.ts │ │ ├── modeSlice.ts │ │ ├── nightModeSlice.ts │ │ ├── pwaSlice.ts │ │ ├── themeSlice.ts │ │ └── userSlice.ts │ └── store.ts ├── styles │ ├── GlobalStyle.ts │ ├── _override_variables.less │ ├── resetCss.ts │ └── themes │ │ ├── constants.ts │ │ ├── dark │ │ └── darkTheme.ts │ │ ├── light │ │ └── lightTheme.ts │ │ ├── main.less │ │ ├── themeVariables.ts │ │ └── types.ts ├── types │ ├── generalTypes.ts │ ├── modeTypes.ts │ ├── nostr.ts │ └── settings.types.ts └── utils │ ├── balanceFormatter.ts │ ├── dateFormatter.ts │ └── utils.ts ├── start-app.sh ├── start.bat ├── tsconfig.json ├── tsconfig.paths.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | 7 | [*.{js,json,yml}] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | REACT_APP_BASE_URL=http://localhost:9002 2 | REACT_APP_WALLET_BASE_URL=http://localhost:9003 3 | REACT_APP_ASSETS_BUCKET=http://localhost 4 | REACT_APP_DEMO_MODE=false 5 | 6 | # More info https://create-react-app.dev/docs/advanced-configuration 7 | ESLINT_NO_DEV_ERRORS=true 8 | TSC_COMPILE_ON_ERROR=true 9 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | NODE_OPTIONS=--openssl-legacy-provider 2 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | REACT_APP_BASE_URL=http://localhost:9002 2 | # REACT_APP_BASE_URL=https://9ee32ecaf5a1.ngrok.app 3 | REACT_APP_ASSETS_BUCKET=http://localhost 4 | 5 | # more info https://create-react-app.dev/docs/advanced-configuration 6 | ESLINT_NO_DEV_ERRORS=true 7 | TSC_COMPILE_ON_ERROR=true 8 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "prettier/prettier": [ 3 | "error", 4 | { 5 | "singleQuote": true, 6 | "parser": "flow", 7 | "endOfLine": "auto" 8 | } 9 | ], 10 | "rules": { 11 | "@typescript-eslint/no-unused-vars": "off", 12 | "@typescript-eslint/no-explicit-any": "off", 13 | "@typescript-eslint/explicit-module-boundary-types": "off", 14 | "@typescript-eslint/ban-types": "off", 15 | "react-hooks/exhaustive-deps": "off" 16 | } 17 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | .pnp.* 6 | .yarn/* 7 | !.yarn/patches 8 | !.yarn/plugins 9 | !.yarn/releases 10 | !.yarn/sdks 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | .env 22 | .env.development.local 23 | .env.test.local 24 | .env.production.local 25 | 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | 30 | # IDE files 31 | .idea 32 | 33 | # generated files 34 | /public/themes 35 | /memory-bank -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #. "$(dirname "$0")/_/husky.sh" 3 | 4 | #npx lint-staged 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: 'all', 4 | singleQuote: true, 5 | printWidth: 120, 6 | tabWidth: 2, 7 | silent: true, 8 | endOfLine:"auto" 9 | }; 10 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "processors": [ 4 | "stylelint-processor-styled-components" 5 | ], 6 | "extends": [ 7 | "stylelint-config-recommended", 8 | "stylelint-config-styled-components" 9 | ], 10 | "prettier/prettier": [ 11 | "error", 12 | { 13 | "endOfLine": "auto" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | enableGlobalCache: false 2 | 3 | nodeLinker: node-modules 4 | 5 | packageExtensions: 6 | react-scripts@*: 7 | dependencies: 8 | typescript: 4.5.5 9 | react@*: 10 | peerDependencies: 11 | react-dom: "*" 12 | 13 | yarnPath: .yarn/releases/yarn-1.22.19.cjs 14 | -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM This script sets the necessary environment variable and starts the React app 3 | 4 | echo Setting OpenSSL legacy provider and increasing memory allocation... 5 | set "NODE_OPTIONS=--openssl-legacy-provider --max-old-space-size=4096" 6 | 7 | REM Run lessc directly using local node_modules 8 | call node_modules\.bin\lessc --js --clean-css="--s1 --advanced" src/styles/themes/main.less public/themes/main.css 9 | if errorlevel 1 goto error 10 | 11 | echo Theme built successfully, starting the app... 12 | call yarn run craco build 13 | if errorlevel 1 goto error 14 | goto end 15 | 16 | :error 17 | echo Failed with error #%errorlevel%. 18 | exit /b %errorlevel% 19 | 20 | :end -------------------------------------------------------------------------------- /public/Lightence-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/public/Lightence-screenshot.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/public/favicon.ico -------------------------------------------------------------------------------- /public/logo-dark-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/public/logo-dark-192.png -------------------------------------------------------------------------------- /public/logo-dark-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/public/logo-dark-512.png -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "H.O.R.N.E.T.S", 3 | "name": "H.O.R.N.E.T.S Nostr Relay", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo-dark-192.png", 12 | "type": "image/png", 13 | "sizes": "192x192", 14 | "purpose": "any maskable" 15 | }, 16 | { 17 | "src": "logo-dark-512.png", 18 | "type": "image/png", 19 | "sizes": "512x512" 20 | } 21 | ], 22 | "start_url": "/", 23 | "display": "standalone", 24 | "theme_color": "#000000", 25 | "background_color": "#ffffff" 26 | } 27 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /sidebar-clean.patch: -------------------------------------------------------------------------------- 1 | --- a/src/components/layouts/main/sider/sidebarNavigation.tsx 2 | +++ b/src/components/layouts/main/sider/sidebarNavigation.tsx 3 | @@ -1,5 +1,5 @@ 4 | import React, { useMemo } from 'react'; 5 | -import { DashboardOutlined, TableOutlined } from '@ant-design/icons'; 6 | +import { DashboardOutlined, TableOutlined, StopOutlined, FlagOutlined } from '@ant-design/icons'; 7 | import { ReactComponent as NestIcon } from '@app/assets/icons/hive.svg'; 8 | import { ReactComponent as BtcIcon } from '@app/assets/icons/btc.svg'; 9 | import { ReactComponent as StatsIcon } from '@app/assets/icons/stats.svg'; 10 | @@ -31,6 +31,12 @@ export const useSidebarNavigation = (): SidebarNavigationItem[] => { 11 | url: '/relay-settings', 12 | icon: , 13 | }, 14 | + { 15 | + title: 'Access Control', 16 | + key: 'blocked-pubkeys', 17 | + url: '/blocked-pubkeys', 18 | + icon: , 19 | + }, 20 | { 21 | title: 'Nostr Statistics', 22 | key: 'dataTables', 23 | -------------------------------------------------------------------------------- /src/@types/bip-schnorr.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'bip-schnorr' { 2 | import { Buffer } from 'buffer'; 3 | 4 | export class Schnorr { 5 | static sign(privateKey: Buffer, message: Buffer): Buffer; 6 | static verify(publicKey: Buffer, message: Buffer, signature: Buffer): boolean; 7 | } 8 | 9 | export const schnorr: Schnorr; 10 | } 11 | -------------------------------------------------------------------------------- /src/@types/credit-cards.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'elt-react-credit-cards'; 2 | -------------------------------------------------------------------------------- /src/@types/event-target.d.ts: -------------------------------------------------------------------------------- 1 | interface EventTarget { 2 | state?: 'activated'; 3 | } 4 | -------------------------------------------------------------------------------- /src/@types/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/api/ApiError.ts: -------------------------------------------------------------------------------- 1 | export class ApiError extends Error { 2 | options?: T; 3 | 4 | constructor(message: string, options?: T) { 5 | super(message); 6 | this.options = options; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/api/covid.api.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | interface Data { 4 | [key: string]: number; 5 | } 6 | 7 | export interface CoronaData { 8 | cases: Data; 9 | deaths: Data; 10 | recovered: Data; 11 | } 12 | 13 | export const getCovidData = async (): Promise => { 14 | try { 15 | const response = await axios.get('https://disease.sh/v3/covid-19/historical/all?lastdays=all'); 16 | 17 | return response.data; 18 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 19 | } catch (e: any) { 20 | throw new Error(e); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /src/api/http.api.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { AxiosError } from 'axios'; 3 | import { ApiError } from '@app/api/ApiError'; 4 | import { readToken } from '@app/services/localStorage.service'; 5 | import config from '@app/config/config'; 6 | 7 | // export const httpApi = axios.create({ 8 | // baseURL: process.env.REACT_APP_BASE_URL, 9 | // }); 10 | 11 | export const httpApi = axios.create({ 12 | baseURL: config.baseURL, // Set the base URL for your backend server 13 | headers: { 14 | 'Content-Type': 'application/json', 15 | }, 16 | }); 17 | 18 | httpApi.interceptors.request.use((config) => { 19 | config.headers = { ...config.headers, Authorization: `Bearer ${readToken()}` }; 20 | 21 | return config; 22 | }); 23 | 24 | httpApi.interceptors.response.use(undefined, (error: AxiosError) => { 25 | throw new ApiError(error.response?.data.message || error.message, error.response?.data); 26 | }); 27 | 28 | export interface ApiErrorData { 29 | message: string; 30 | } 31 | -------------------------------------------------------------------------------- /src/api/mocks/http.api.mock.ts: -------------------------------------------------------------------------------- 1 | import AxiosMockAdapter from 'axios-mock-adapter'; 2 | import { httpApi } from '@app/api/http.api'; 3 | 4 | export const httpApiMock = new AxiosMockAdapter(httpApi, { delayResponse: 1000 }); 5 | -------------------------------------------------------------------------------- /src/api/notifications.api.ts: -------------------------------------------------------------------------------- 1 | export interface Message { 2 | id: number; 3 | description: string; 4 | } 5 | 6 | export interface Mention extends Message { 7 | userName: string; 8 | userIcon: string; 9 | place: string; 10 | href: string; 11 | } 12 | 13 | export type Notification = Mention | Message; 14 | 15 | // Export an empty array for notifications 16 | export const notifications: Notification[] = []; 17 | -------------------------------------------------------------------------------- /src/api/paidSubscribers.ts: -------------------------------------------------------------------------------- 1 | export interface PaidSubscriber { 2 | pubkey: string; 3 | picture: string; 4 | name?: string; 5 | about?: string; 6 | metadata?: { 7 | subscriptionTier?: string; 8 | subscribedSince?: string; 9 | }; 10 | } 11 | 12 | // This is a placeholder function if needed in the future 13 | // Currently the hook directly fetches from the API 14 | export const getPaidSubscribers = (): Promise => { 15 | return new Promise((res) => { 16 | setTimeout(() => { 17 | res([]); 18 | }, 0); 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /src/api/screenings.api.ts: -------------------------------------------------------------------------------- 1 | export interface Screening { 2 | id: number; 3 | value: number; 4 | prevValue: number; 5 | } 6 | 7 | export const getScreenings = (): Promise => { 8 | return new Promise((res) => { 9 | setTimeout(() => { 10 | res([ 11 | { 12 | id: 1, 13 | value: 45, 14 | prevValue: 30, 15 | }, 16 | { 17 | id: 2, 18 | value: 12, 19 | prevValue: 20, 20 | }, 21 | { 22 | id: 3, 23 | value: 90, 24 | prevValue: 60, 25 | }, 26 | { 27 | id: 4, 28 | value: 78, 29 | prevValue: 90, 30 | }, 31 | { 32 | id: 5, 33 | value: 78, 34 | prevValue: 0, 35 | }, 36 | { 37 | id: 6, 38 | value: 78, 39 | prevValue: 90, 40 | }, 41 | ]); 42 | }, 0); 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /src/api/statistics.api.ts: -------------------------------------------------------------------------------- 1 | export interface Statistic { 2 | id: number; 3 | value: number; 4 | prevValue: number; 5 | unit: 'kg'; 6 | } 7 | 8 | export const getStatistics = (): Promise => { 9 | return new Promise((res) => { 10 | setTimeout(() => { 11 | res([ 12 | { 13 | id: 1, 14 | value: 45, 15 | prevValue: 30, 16 | unit: 'kg', 17 | }, 18 | { 19 | id: 2, 20 | value: 12, 21 | prevValue: 20, 22 | unit: 'kg', 23 | }, 24 | { 25 | id: 3, 26 | value: 90, 27 | prevValue: 60, 28 | unit: 'kg', 29 | }, 30 | { 31 | id: 4, 32 | value: 78, 33 | prevValue: 90, 34 | unit: 'kg', 35 | }, 36 | ]); 37 | }, 0); 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /src/assets/admin-default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/admin-default-avatar.png -------------------------------------------------------------------------------- /src/assets/icons/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/bones.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/btc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/eth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/facebook.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/assets/icons/hive.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/assets/icons/map-background.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | 15 | 16 | 17 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/assets/icons/media.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/icons/stats.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/icons/storage-settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/assets/icons/water.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /src/assets/images/card-issuers/maestro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/card-issuers/maestro.png -------------------------------------------------------------------------------- /src/assets/images/card-issuers/mastercard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/card-issuers/mastercard.png -------------------------------------------------------------------------------- /src/assets/images/card-issuers/visa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/card-issuers/visa.png -------------------------------------------------------------------------------- /src/assets/images/login-bg.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/login-bg.webp -------------------------------------------------------------------------------- /src/assets/images/new-lane.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/new-lane.webp -------------------------------------------------------------------------------- /src/assets/images/nothing-found.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/nothing-found.webp -------------------------------------------------------------------------------- /src/assets/images/profile1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile1.webp -------------------------------------------------------------------------------- /src/assets/images/profile10.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile10.webp -------------------------------------------------------------------------------- /src/assets/images/profile11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile11.png -------------------------------------------------------------------------------- /src/assets/images/profile12.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile12.webp -------------------------------------------------------------------------------- /src/assets/images/profile13.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile13.webp -------------------------------------------------------------------------------- /src/assets/images/profile2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile2.jpg -------------------------------------------------------------------------------- /src/assets/images/profile3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile3.jpg -------------------------------------------------------------------------------- /src/assets/images/profile3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile3.webp -------------------------------------------------------------------------------- /src/assets/images/profile4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile4.webp -------------------------------------------------------------------------------- /src/assets/images/profile5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile5.jpg -------------------------------------------------------------------------------- /src/assets/images/profile6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile6.jpg -------------------------------------------------------------------------------- /src/assets/images/profile7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile7.jpg -------------------------------------------------------------------------------- /src/assets/images/profile8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile8.gif -------------------------------------------------------------------------------- /src/assets/images/profile9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/profile9.gif -------------------------------------------------------------------------------- /src/assets/images/stub-avatar.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/stub-avatar.webp -------------------------------------------------------------------------------- /src/assets/images/verify-email.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/images/verify-email.webp -------------------------------------------------------------------------------- /src/assets/logo-dark-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/logo-dark-192.png -------------------------------------------------------------------------------- /src/assets/logo-dark-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/logo-dark-512.png -------------------------------------------------------------------------------- /src/assets/logo-dark-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/logo-dark-old.png -------------------------------------------------------------------------------- /src/assets/logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/logo-dark.png -------------------------------------------------------------------------------- /src/assets/logo-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/logo-old.png -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HORNET-Storage/HORNETS-Relay-Panel/adf848ebba3a612839c331acbbedda5f2abdde76/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/AuthGuard.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Navigate, useLocation } from 'react-router-dom'; 3 | import { readToken } from '@app/services/localStorage.service'; 4 | import config from '@app/config/config'; // Import the config 5 | 6 | interface AuthGuardProps { 7 | children: React.ReactElement; 8 | } 9 | 10 | export const AuthGuard: React.FC = ({ children }) => { 11 | const location = useLocation(); 12 | const token = readToken(); 13 | 14 | console.log('Demo mode:', config.isDemoMode); 15 | 16 | if (config.isDemoMode) { 17 | console.log('Demo mode is active, allowing access'); 18 | return children; 19 | } 20 | 21 | if (!token || token === 'bearerToken' || token === null) { 22 | console.log('No valid token, redirecting to login'); 23 | return ; 24 | } 25 | 26 | return children; 27 | }; 28 | -------------------------------------------------------------------------------- /src/components/Error/Error.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useTranslation } from 'react-i18next'; 3 | import * as S from './Error.styles'; 4 | import { Link } from 'react-router-dom'; 5 | 6 | interface ErrorProps { 7 | img: string; 8 | msg: string; 9 | } 10 | 11 | export const Error: React.FC = ({ img, msg }) => { 12 | const { t } = useTranslation(); 13 | 14 | return ( 15 | 16 | 17 | 18 | {t('common.oops')} 19 | {msg} 20 | {/*TODO make common component */} 21 | 22 | {t('error404.comeBack')} 23 | 24 | 25 | 26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /src/components/PwaSupportChecker.tsx: -------------------------------------------------------------------------------- 1 | // components/PwaSupportChecker.tsx 2 | import React, { useEffect } from 'react'; 3 | import { useAppDispatch } from '@app/hooks/reduxHooks'; 4 | import { setPWASupported } from '@app/store/slices/pwaSlice'; 5 | 6 | const PwaSupportChecker: React.FC = () => { 7 | const dispatch = useAppDispatch(); 8 | 9 | useEffect(() => { 10 | const checkPWASupport = () => { 11 | const isSupported = 'serviceWorker' in navigator && 'BeforeInstallPromptEvent' in window; 12 | console.log('PWA support check:', isSupported); 13 | dispatch(setPWASupported(isSupported)); 14 | }; 15 | 16 | checkPWASupport(); 17 | }, [dispatch]); 18 | 19 | return null; // This component doesn't render anything 20 | }; 21 | 22 | export default PwaSupportChecker; 23 | -------------------------------------------------------------------------------- /src/components/SubscriptionTiersManager/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './SubscriptionTiersManager'; -------------------------------------------------------------------------------- /src/components/auth/ForgotPasswordForm/ForgotPasswordForm.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { FONT_SIZE, FONT_WEIGHT, media } from '@app/styles/themes/constants'; 3 | import { BaseButton } from '@app/components/common/BaseButton/BaseButton'; 4 | 5 | export const Description = styled.div` 6 | margin-bottom: 1.875rem; 7 | color: var(--text-main-color); 8 | font-size: ${FONT_SIZE.xs}; 9 | font-weight: ${FONT_WEIGHT.regular}; 10 | 11 | @media only screen and ${media.xs} { 12 | font-size: ${FONT_SIZE.xxs}; 13 | } 14 | 15 | @media only screen and ${media.md} { 16 | font-size: ${FONT_SIZE.xs}; 17 | } 18 | `; 19 | 20 | export const SubmitButton = styled(BaseButton)` 21 | font-size: ${FONT_SIZE.md}; 22 | font-weight: ${FONT_WEIGHT.semibold}; 23 | width: 100%; 24 | margin-top: 1.125rem; 25 | margin-bottom: 1rem; 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/auth/NewPasswordForm/NewPasswordForm.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { FONT_SIZE, FONT_WEIGHT, media } from '@app/styles/themes/constants'; 3 | import { BaseButton } from '@app/components/common/BaseButton/BaseButton'; 4 | 5 | export const Description = styled.div` 6 | margin-bottom: 1.875rem; 7 | color: var(--text-main-color); 8 | font-size: ${FONT_SIZE.xs}; 9 | font-weight: ${FONT_WEIGHT.regular}; 10 | 11 | @media only screen and ${media.xs} { 12 | font-size: ${FONT_SIZE.xxs}; 13 | } 14 | 15 | @media only screen and ${media.md} { 16 | font-size: ${FONT_SIZE.xs}; 17 | } 18 | `; 19 | 20 | export const SubmitButton = styled(BaseButton)` 21 | font-size: ${FONT_SIZE.md}; 22 | font-weight: ${FONT_WEIGHT.semibold}; 23 | width: 100%; 24 | margin-top: 1.125rem; 25 | margin-bottom: 1rem; 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/auth/SecurityCodeForm/SecurityCodeForm.styles.ts: -------------------------------------------------------------------------------- 1 | import { FONT_SIZE, FONT_WEIGHT, media } from '@app/styles/themes/constants'; 2 | import styled from 'styled-components'; 3 | 4 | export const ImageWrapper = styled.div` 5 | margin-bottom: 1.875rem; 6 | `; 7 | 8 | export const VerifyEmailDescription = styled.div` 9 | margin-bottom: 1.875rem; 10 | color: var(--text-main-color); 11 | font-size: ${FONT_SIZE.xs}; 12 | font-weight: ${FONT_WEIGHT.regular}; 13 | 14 | @media only screen and ${media.xs} { 15 | font-size: ${FONT_SIZE.xxs}; 16 | } 17 | 18 | @media only screen and ${media.md} { 19 | font-size: ${FONT_SIZE.xs}; 20 | } 21 | `; 22 | 23 | export const NoCodeText = styled.div` 24 | margin-top: 1rem; 25 | color: var(--primary-color); 26 | font-size: ${FONT_SIZE.xs}; 27 | font-weight: ${FONT_WEIGHT.regular}; 28 | text-decoration: underline; 29 | cursor: pointer; 30 | `; 31 | 32 | export const ContentWrapper = styled.div` 33 | display: flex; 34 | flex-direction: column; 35 | align-items: center; 36 | `; 37 | -------------------------------------------------------------------------------- /src/components/auth/SignUpForm/SignUpForm.styles.tsx: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { FormTitle } from '@app/components/layouts/AuthLayout/AuthLayout.styles'; 3 | 4 | export const Title = styled(FormTitle)` 5 | margin-bottom: 1.875rem; 6 | `; 7 | 8 | export const HiddenInput = styled.div` 9 | display: none; 10 | `; 11 | -------------------------------------------------------------------------------- /src/components/blocked-pubkeys/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BlockedPubkeys'; 2 | -------------------------------------------------------------------------------- /src/components/charts/VisitorsPieChart.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BaseCard } from '@app/components/common/BaseCard/BaseCard'; 3 | import { useTranslation } from 'react-i18next'; 4 | import { PieChart } from '../common/charts/PieChart'; 5 | import useChartData from '@app/hooks/useChartData'; // Import the custom hook 6 | 7 | export const VisitorsPieChart: React.FC = () => { 8 | const { t } = useTranslation(); 9 | const { chartData, isLoading } = useChartData(); // Use the custom hook to get data 10 | 11 | const name = t('charts.visitorsFrom'); 12 | 13 | return ( 14 | 15 | {isLoading || !chartData ? ( 16 |

{t('common.loading')}

17 | ) : ( 18 | 19 | )} 20 |
21 | ); 22 | }; 23 | 24 | export default VisitorsPieChart; 25 | -------------------------------------------------------------------------------- /src/components/common/BaseAlert/BaseAlert.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Alert as AntAlert } from 'antd'; 3 | 4 | export const Alert = styled(AntAlert)` 5 | color: var(--black); 6 | 7 | .ant-alert-message { 8 | color: var(--black); 9 | } 10 | `; 11 | -------------------------------------------------------------------------------- /src/components/common/BaseAlert/BaseAlert.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import type { AlertProps } from 'antd'; 3 | import * as S from './BaseAlert.styles'; 4 | 5 | export type BaseAlertProps = AlertProps; 6 | 7 | export const BaseAlert: React.FC = (props) => { 8 | return ; 9 | }; 10 | -------------------------------------------------------------------------------- /src/components/common/BaseAutoComplete/BaseAutoComplete.tsx: -------------------------------------------------------------------------------- 1 | export { AutoComplete as BaseAutoComplete } from 'antd'; 2 | export type { AutoCompleteProps as BaseAutoCompleteProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseAvatar/BaseAvatar.tsx: -------------------------------------------------------------------------------- 1 | import { Avatar, AvatarProps } from 'antd'; 2 | 3 | export type BaseAvatarProps = AvatarProps; 4 | 5 | interface BaseAvatarInterface extends React.FC { 6 | Group: typeof Avatar.Group; 7 | } 8 | 9 | export const BaseAvatar: BaseAvatarInterface = (props) => { 10 | return ; 11 | }; 12 | 13 | BaseAvatar.Group = Avatar.Group; 14 | -------------------------------------------------------------------------------- /src/components/common/BaseBadge/BaseBadge.styles.ts: -------------------------------------------------------------------------------- 1 | import { defineColorBySeverity } from '@app/utils/utils'; 2 | import { Badge as AntBadge } from 'antd'; 3 | import styled from 'styled-components'; 4 | import { NotificationType } from '../BaseNotification/BaseNotification'; 5 | 6 | interface BadgeProps { 7 | severity?: NotificationType; 8 | } 9 | 10 | export const Badge = styled(AntBadge)` 11 | color: inherit; 12 | 13 | & .ant-badge-count { 14 | background: ${(props) => defineColorBySeverity(props.severity)}; 15 | } 16 | `; 17 | -------------------------------------------------------------------------------- /src/components/common/BaseBreadcrumb/BaseBreadcrumb.tsx: -------------------------------------------------------------------------------- 1 | export { Breadcrumb as BaseBreadcrumb } from 'antd'; 2 | export type { BreadcrumbProps as BaseBreadcrumbProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseButton/BaseButton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ButtonProps as AntButtonProps, Button as AntdButton } from 'antd'; 3 | import { Severity } from '@app/interfaces/interfaces'; 4 | import * as S from './BaseButton.styles'; 5 | 6 | export const { Group: ButtonGroup } = AntdButton; 7 | 8 | export interface BaseButtonProps extends AntButtonProps { 9 | severity?: Severity; 10 | noStyle?: boolean; 11 | } 12 | 13 | export const BaseButton = React.forwardRef( 14 | ({ className, severity, noStyle, children, ...props }, ref) => ( 15 | 16 | {children} 17 | 18 | ), 19 | ); 20 | -------------------------------------------------------------------------------- /src/components/common/BaseCarousel/CarouselArrow/CarouselArrow.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { CustomArrowProps } from 'react-slick'; 3 | 4 | export const ArrowWrapper = styled.div.withConfig({ 5 | shouldForwardProp: (prop) => !['currentSlide', 'slideCount'].includes(prop), 6 | })` 7 | font-size: 1rem; 8 | 9 | color: var(--text-main-color); 10 | 11 | &:before { 12 | display: none; 13 | } 14 | 15 | &:hover, 16 | &:focus { 17 | color: var(--text-main-color); 18 | } 19 | `; 20 | -------------------------------------------------------------------------------- /src/components/common/BaseCarousel/CarouselArrow/CarouselArrow.tsx: -------------------------------------------------------------------------------- 1 | import { WithChildrenProps } from '@app/types/generalTypes'; 2 | import React from 'react'; 3 | import { CustomArrowProps } from 'react-slick'; 4 | import * as S from './CarouselArrow.styles'; 5 | 6 | export const CarouselArrow: React.FC> = ({ children, ...props }) => { 7 | return {children}; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseCascader/BaseCascader.tsx: -------------------------------------------------------------------------------- 1 | export { Cascader as BaseCascader } from 'antd'; 2 | export type { CascaderProps as BaseCascaderProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseCheckbox/BaseCheckbox.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Checkbox as AntdCheckbox } from 'antd'; 3 | 4 | const { Group } = AntdCheckbox; 5 | 6 | export const Checkbox = styled(AntdCheckbox)` 7 | & .ant-checkbox-inner { 8 | border-radius: 0.1875rem; 9 | height: 1.25rem; 10 | width: 1.25rem; 11 | border: 1px solid var(--primary-color); 12 | } 13 | 14 | .ant-checkbox-disabled.ant-checkbox-checked .ant-checkbox-inner::after { 15 | border-color: var(--disabled-color); 16 | } 17 | 18 | .ant-checkbox-disabled + span { 19 | color: var(--disabled-color); 20 | } 21 | `; 22 | export const CheckboxGroup = styled(Group)` 23 | & .ant-checkbox-inner { 24 | border-radius: 0.1875rem; 25 | height: 1.25rem; 26 | width: 1.25rem; 27 | border: 1px solid var(--primary-color); 28 | } 29 | `; 30 | -------------------------------------------------------------------------------- /src/components/common/BaseCheckbox/BaseCheckbox.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { CheckboxProps } from 'antd'; 3 | import * as S from './BaseCheckbox.styles'; 4 | 5 | export type BaseCheckboxProps = CheckboxProps; 6 | 7 | interface BaseCheckboxInterface extends React.FC { 8 | Group: typeof S.CheckboxGroup; 9 | } 10 | 11 | export const BaseCheckbox: BaseCheckboxInterface = (props) => { 12 | return ; 13 | }; 14 | 15 | BaseCheckbox.Group = S.CheckboxGroup; 16 | -------------------------------------------------------------------------------- /src/components/common/BaseCol/BaseCol.tsx: -------------------------------------------------------------------------------- 1 | export { Col as BaseCol } from 'antd'; 2 | export type { ColProps as BaseColProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseCollapse/BaseCollapse.tsx: -------------------------------------------------------------------------------- 1 | import { CollapseProps, Collapse as AntdCollapse } from 'antd'; 2 | 3 | export type BaseCollapseProps = CollapseProps; 4 | 5 | interface BaseCollapseInterface extends React.FC { 6 | Panel: typeof AntdCollapse.Panel; 7 | } 8 | 9 | export const BaseCollapse: BaseCollapseInterface = (props) => { 10 | return ; 11 | }; 12 | 13 | BaseCollapse.Panel = AntdCollapse.Panel; 14 | -------------------------------------------------------------------------------- /src/components/common/BaseDivider/BaseDivider.tsx: -------------------------------------------------------------------------------- 1 | export { Divider as BaseDivider } from 'antd'; 2 | export type { DividerProps as BaseDividerProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseDropdown/Dropdown.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { DropdownProps, Dropdown } from 'antd'; 3 | 4 | export const BaseDropdown: React.FC = ({ children, ...props }) => { 5 | return ( 6 | triggerNode} {...props}> 7 | {children} 8 | 9 | ); 10 | }; 11 | -------------------------------------------------------------------------------- /src/components/common/BaseEmpty/BaseEmpty.tsx: -------------------------------------------------------------------------------- 1 | export { Empty as BaseEmpty } from 'antd'; 2 | export type { EmptyProps as BaseEmptyProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseFeed/BaseFeed.styles.ts: -------------------------------------------------------------------------------- 1 | import { media } from '@app/styles/themes/constants'; 2 | import styled from 'styled-components'; 3 | 4 | export const NewsWrapper = styled.div` 5 | display: flex; 6 | flex-direction: column; 7 | 8 | & > div { 9 | margin-bottom: 1.25rem; 10 | 11 | @media only screen and ${media.xl} { 12 | margin-bottom: 1.5rem; 13 | } 14 | 15 | @media only screen and ${media.xxl} { 16 | margin-bottom: 2.5rem; 17 | } 18 | } 19 | `; 20 | 21 | export const SpinnerWrapper = styled.div` 22 | display: flex; 23 | width: 100%; 24 | justify-content: center; 25 | margin-top: 2rem; 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/common/BaseFeed/BaseFeed.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import InfiniteScroll from 'react-infinite-scroll-component'; 3 | import { BaseSpin } from '../BaseSpin/BaseSpin'; 4 | import * as S from './BaseFeed.styles'; 5 | 6 | export interface BaseFeedProps { 7 | next: () => void; 8 | hasMore: boolean; 9 | children: React.ReactNode[]; 10 | target?: string; 11 | } 12 | 13 | export const BaseFeed: React.FC = ({ next, hasMore, target = 'main-content', children }) => { 14 | return ( 15 | 21 | 22 | 23 | } 24 | scrollableTarget={target} 25 | > 26 | {children} 27 | 28 | ); 29 | }; 30 | -------------------------------------------------------------------------------- /src/components/common/BaseHashTag/BaseHashTag.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { CloseOutlined } from '@ant-design/icons'; 3 | import { FONT_SIZE } from '@app/styles/themes/constants'; 4 | 5 | export const RemoveTagWrapper = styled.span` 6 | padding-left: 0.3125rem; 7 | display: flex; 8 | align-items: center; 9 | padding-top: 1px; 10 | `; 11 | 12 | export const RemoveTagIcon = styled(CloseOutlined)` 13 | color: #ffffff; 14 | font-size: ${FONT_SIZE.xxs}; 15 | cursor: pointer; 16 | `; 17 | 18 | export const TagWrapper = styled.span` 19 | border-radius: 0.5rem; 20 | display: flex; 21 | justify-content: center; 22 | align-items: center; 23 | padding: 0.3125rem 0.625rem; 24 | margin: 0; 25 | font-size: ${FONT_SIZE.xs}; 26 | `; 27 | -------------------------------------------------------------------------------- /src/components/common/BaseImage/BaseImage.tsx: -------------------------------------------------------------------------------- 1 | export { Image as BaseImage } from 'antd'; 2 | export type { ImageProps as BaseImageProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseLayout/BaseLayout.tsx: -------------------------------------------------------------------------------- 1 | export { Layout as BaseLayout } from 'antd'; 2 | export type { LayoutProps as BaseLayoutProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseList/BaseList.tsx: -------------------------------------------------------------------------------- 1 | export { List as BaseList } from 'antd'; 2 | export type { ListProps as BaseListProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseMenu/BaseMenu.tsx: -------------------------------------------------------------------------------- 1 | export { Menu as BaseMenu } from 'antd'; 2 | export type { MenuProps as BaseMenuProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BasePagination/BasePagination.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Pagination as AntdPagination } from 'antd'; 3 | 4 | export const Pagination = styled(AntdPagination)` 5 | .ant-pagination-item-container .ant-pagination-item-ellipsis { 6 | color: var(--disabled-color); 7 | } 8 | 9 | .ant-pagination-disabled { 10 | .ant-pagination-item-link, 11 | .ant-pagination-item a { 12 | color: var(--disabled-color); 13 | } 14 | } 15 | 16 | &.ant-pagination.ant-pagination-disabled { 17 | .ant-pagination-item-link, 18 | .ant-pagination-item a { 19 | color: var(--disabled-color); 20 | } 21 | } 22 | & .ant-select-arrow { 23 | color: var(--disabled-color); 24 | } 25 | 26 | .ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector { 27 | color: var(--disabled-color); 28 | } 29 | `; 30 | -------------------------------------------------------------------------------- /src/components/common/BasePagination/BasePagination.tsx: -------------------------------------------------------------------------------- 1 | import { PaginationProps } from 'antd'; 2 | import * as S from './BasePagination.styles'; 3 | 4 | export type BasePaginationProps = PaginationProps; 5 | 6 | export const BasePagination: React.FC = (props) => { 7 | return ; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BasePopconfirm/BasePopconfirm.tsx: -------------------------------------------------------------------------------- 1 | export { Popconfirm as BasePopconfirm } from 'antd'; 2 | export type { PopconfirmProps as BasePopconfirmProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BasePopover/BasePopover.tsx: -------------------------------------------------------------------------------- 1 | export { Popover as BasePopover } from 'antd'; 2 | export type { PopoverProps as BasePopoverProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseProgress/BaseProgress.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ProgressProps, Progress } from 'antd'; 3 | 4 | export type BaseProgressProps = ProgressProps; 5 | 6 | export const BaseProgress: React.FC = (props) => { 7 | return ; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseRadio/BaseRadio.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Radio as AntdRadio } from 'antd'; 3 | 4 | export const Radio = styled(AntdRadio)` 5 | .ant-radio-disabled + span { 6 | color: var(--disabled-color); 7 | } 8 | `; 9 | 10 | export const RadioButton = styled(AntdRadio.Button)` 11 | &.ant-radio-button-wrapper-disabled { 12 | color: var(--disabled-color); 13 | } 14 | `; 15 | -------------------------------------------------------------------------------- /src/components/common/BaseRadio/BaseRadio.tsx: -------------------------------------------------------------------------------- 1 | import { Radio, RadioProps } from 'antd'; 2 | import * as S from './BaseRadio.styles'; 3 | 4 | export type BaseRadioProps = RadioProps; 5 | 6 | interface BaseRadioInterface extends React.FC { 7 | Group: typeof Radio.Group; 8 | Button: typeof Radio.Button; 9 | } 10 | 11 | export const BaseRadio: BaseRadioInterface = (props) => { 12 | return ; 13 | }; 14 | 15 | BaseRadio.Group = Radio.Group; 16 | BaseRadio.Button = S.RadioButton; 17 | -------------------------------------------------------------------------------- /src/components/common/BaseRate/BaseRate.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Rate as AntdRate } from 'antd'; 3 | import { FONT_SIZE } from '@app/styles/themes/constants'; 4 | 5 | export const Rate = styled(AntdRate)` 6 | font-size: ${FONT_SIZE.lg}; 7 | `; 8 | -------------------------------------------------------------------------------- /src/components/common/BaseRate/BaseRate.tsx: -------------------------------------------------------------------------------- 1 | import { RateProps } from 'antd'; 2 | import * as S from './BaseRate.styles'; 3 | 4 | export type BaseRateProps = RateProps; 5 | 6 | export const BaseRate: React.FC = (props) => { 7 | return ; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseResult/BaseResult.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Result as AntResult } from 'antd'; 3 | 4 | export const Result = styled(AntResult)` 5 | &.ant-result-success .ant-result-icon > .anticon { 6 | color: var(--success-color); 7 | } 8 | 9 | &.ant-result-info .ant-result-icon > .anticon { 10 | color: var(--primary-color); 11 | } 12 | &.ant-result-warning .ant-result-icon > .anticon { 13 | color: var(--warning-color); 14 | } 15 | &.ant-result-error .ant-result-icon > .anticon { 16 | color: var(--error-color); 17 | } 18 | 19 | .ant-result-subtitle { 20 | color: var(--breadcrumb-color); 21 | } 22 | `; 23 | -------------------------------------------------------------------------------- /src/components/common/BaseResult/BaseResult.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ResultProps } from 'antd'; 3 | import * as S from './BaseResult.styles'; 4 | 5 | export type BaseResultProps = ResultProps; 6 | 7 | export const BaseResult: React.FC = (props) => { 8 | return ; 9 | }; 10 | -------------------------------------------------------------------------------- /src/components/common/BaseRow/BaseRow.tsx: -------------------------------------------------------------------------------- 1 | export { Row as BaseRow } from 'antd'; 2 | export type { RowProps as BaseRowProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseSkeleton/BaseSkeleton.tsx: -------------------------------------------------------------------------------- 1 | export { Skeleton as BaseSkeleton } from 'antd'; 2 | export type { SkeletonProps as BaseSkeletonProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseSlider/BaseSlider.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Slider as AntdSlider } from 'antd'; 3 | 4 | export const Slider = styled(AntdSlider)` 5 | & .ant-slider-mark-text:not(.ant-slider-mark-text-active) { 6 | color: var(--subtext-color); 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseSlider/BaseSlider.tsx: -------------------------------------------------------------------------------- 1 | import { SliderSingleProps } from 'antd'; 2 | import * as S from './BaseSlider.styles'; 3 | 4 | export type BaseSliderProps = SliderSingleProps; 5 | 6 | export const BaseSlider: React.FC = (props) => { 7 | return ; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseSpace/BaseSpace.tsx: -------------------------------------------------------------------------------- 1 | export { Space as BaseSpace } from 'antd'; 2 | export type { SpaceProps as BaseSpaceProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseSpin/BaseSpin.tsx: -------------------------------------------------------------------------------- 1 | export { Spin as BaseSpin } from 'antd'; 2 | export type { SpinProps as BaseSpinProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseSteps/BaseSteps.tsx: -------------------------------------------------------------------------------- 1 | import { StepsProps } from 'antd'; 2 | import * as S from './BaseSteps.styles'; 3 | 4 | export type BaseStepsProps = StepsProps; 5 | 6 | export const BaseSteps: React.FC = ({ children, ...otherProps }) => { 7 | return {children}; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseSwitch/BaseSwitch.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Switch as AntdSwitch } from 'antd'; 3 | 4 | export const Switch = styled(AntdSwitch)` 5 | &.ant-switch[aria-checked='false'] { 6 | background-image: linear-gradient(to right, var(--disabled-color), var(--disabled-color)), 7 | linear-gradient(to right, var(--background-color), var(--background-color)); 8 | } 9 | &.ant-switch[aria-checked='false'].balanceSwitch { 10 | background-image: linear-gradient(to right, #f2a900, #f2a900), 11 | linear-gradient(to right, var(--background-color), var(--background-color)); 12 | } 13 | &.ant-switch[aria-checked='false'].modeSwitch { 14 | background-image: linear-gradient(to right, red, red), 15 | linear-gradient(to right, var(--background-color), var(--background-color)); 16 | } 17 | `; 18 | -------------------------------------------------------------------------------- /src/components/common/BaseSwitch/BaseSwitch.tsx: -------------------------------------------------------------------------------- 1 | import { SwitchProps } from 'antd'; 2 | import * as S from './BaseSwitch.styles'; 3 | 4 | export type BaseSwitchProps = SwitchProps; 5 | 6 | export const BaseSwitch: React.FC = (props) => { 7 | return ; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseTable/BaseTable.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-explicit-any */ 2 | import React from 'react'; 3 | import { TableProps } from 'antd'; 4 | import * as S from './BaseTable.styles'; 5 | import { TooltipProps } from 'antd/lib/tooltip'; 6 | 7 | export type BaseTableProps = TableProps; 8 | 9 | const customSorterTooltip: TooltipProps = { 10 | title: 'Click to sort', // Static title 11 | placement: 'top', 12 | overlayClassName: 'custom-tooltip-class', 13 | }; 14 | 15 | // TODO make generic! 16 | export const BaseTable: React.FC> = (props) => { 17 | return ; 18 | }; 19 | -------------------------------------------------------------------------------- /src/components/common/BaseTabs/BaseTabs.styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | import { Tabs as AntdTabs } from 'antd'; 3 | 4 | export const Tabs = styled(AntdTabs)` 5 | .ant-tabs-tab.ant-tabs-tab-disabled { 6 | color: var(--disabled-color); 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseTabs/BaseTabs.tsx: -------------------------------------------------------------------------------- 1 | import { TabsProps } from 'antd'; 2 | import * as S from './BaseTabs.styles'; 3 | 4 | export type BaseTabsProps = TabsProps; 5 | 6 | export const BaseTabs: React.FC = ({ children, ...props }) => { 7 | return {children}; 8 | }; 9 | -------------------------------------------------------------------------------- /src/components/common/BaseTag/BaseTag.tsx: -------------------------------------------------------------------------------- 1 | export { Tag as BaseTag } from 'antd'; 2 | export type { TagProps as BaseTagProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseTooltip/BaseTooltip.tsx: -------------------------------------------------------------------------------- 1 | export { Tooltip as BaseTooltip } from 'antd'; 2 | export type { TooltipProps as BaseTooltipProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseTypography/BaseTypography.tsx: -------------------------------------------------------------------------------- 1 | export { Typography as BaseTypography } from 'antd'; 2 | export type { TypographyProps as BaseTypographyProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/BaseUpload/BaseUpload.tsx: -------------------------------------------------------------------------------- 1 | export { Upload as BaseUpload } from 'antd'; 2 | export type { UploadProps as BaseUploadProps } from 'antd'; 3 | -------------------------------------------------------------------------------- /src/components/common/CalendarSwitch/CalendarSwitch.styles.ts: -------------------------------------------------------------------------------- 1 | import { FONT_SIZE, media } from '@app/styles/themes/constants'; 2 | import styled from 'styled-components'; 3 | import { BaseTypography } from '../BaseTypography/BaseTypography'; 4 | 5 | export const CalendarSwitch = styled.div` 6 | display: flex; 7 | justify-content: space-between; 8 | align-items: center; 9 | `; 10 | export const Text = styled(BaseTypography.Text)` 11 | font-weight: bold; 12 | font-size: ${FONT_SIZE.xs}; 13 | 14 | @media only screen and ${media.md} { 15 | font-size: ${FONT_SIZE.lg}; 16 | } 17 | `; 18 | 19 | export const ButtonGroup = styled.div` 20 | display: flex; 21 | & > * { 22 | margin-left: 0.1rem; 23 | margin-right: 0.1rem; 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /src/components/common/CopyToClipboard/CopyToClipboard.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { CopyOutlined } from '@ant-design/icons'; 3 | import CopyToClipboard from 'react-copy-to-clipboard'; 4 | import { Button, message } from 'antd'; 5 | interface CopyToClipboardProps { 6 | textToCopy: string; 7 | } 8 | 9 | const ClipboardCopy: React.FC = ({ textToCopy }) => { 10 | const copied = () => { 11 | message.success('Copied to clipboard'); 12 | }; 13 | const onCopy = () => { 14 | //display Copied to clipboard 15 | copied(); 16 | }; 17 | return ( 18 | 19 |