From ce12a054cf6bdd5e7844075d9566d9ac4f76d727 Mon Sep 17 00:00:00 2001 From: Gozarman Date: Sun, 10 Sep 2023 12:33:24 +0330 Subject: [PATCH 1/5] fix: language menu z-index --- app/dashboard/src/components/Language.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dashboard/src/components/Language.tsx b/app/dashboard/src/components/Language.tsx index 602dfe78..7f018ed3 100644 --- a/app/dashboard/src/components/Language.tsx +++ b/app/dashboard/src/components/Language.tsx @@ -37,7 +37,7 @@ export const Language: FC = ({ actions }) => { icon={} position="relative" /> - + Date: Sun, 10 Sep 2023 12:54:15 +0330 Subject: [PATCH 2/5] feat: russian language added to menu --- app/dashboard/src/components/Language.tsx | 7 +++ app/dashboard/src/locales/i18n.ts | 55 ++++++++++++----------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/app/dashboard/src/components/Language.tsx b/app/dashboard/src/components/Language.tsx index 7f018ed3..6a840109 100644 --- a/app/dashboard/src/components/Language.tsx +++ b/app/dashboard/src/components/Language.tsx @@ -59,6 +59,13 @@ export const Language: FC = ({ actions }) => { > 简体中文 + changeLanguage("ru")} + > + русский + ); diff --git a/app/dashboard/src/locales/i18n.ts b/app/dashboard/src/locales/i18n.ts index f83319f4..2ca9d346 100644 --- a/app/dashboard/src/locales/i18n.ts +++ b/app/dashboard/src/locales/i18n.ts @@ -1,13 +1,14 @@ import { joinPaths } from "@remix-run/router"; + +import fa from "date-fns/locale/fa-IR"; +import ru from "date-fns/locale/ru"; +import zh from "date-fns/locale/zh-CN"; import dayjs from "dayjs"; -import "dayjs/locale/zh-cn"; import i18n from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; import HttpApi from "i18next-http-backend"; +import { registerLocale } from "react-datepicker"; import { initReactI18next } from "react-i18next"; -import { registerLocale } from "react-datepicker"; -import es from 'date-fns/locale/es'; -import zh from 'date-fns/locale/zh-CN' declare module "i18next" { interface CustomTypeOptions { @@ -19,33 +20,37 @@ i18n .use(LanguageDetector) .use(initReactI18next) .use(HttpApi) - .init({ - debug: import.meta.env.NODE_ENV === "development", - returnNull: false, - fallbackLng: "en", - interpolation: { - escapeValue: false, - }, - react: { - useSuspense: false, - }, - load: "languageOnly", - detection: { - caches: ["localStorage", "sessionStorage", "cookie"], - }, - backend: { - loadPath: joinPaths([import.meta.env.BASE_URL, `locales/{{lng}}.json`]), + .init( + { + debug: import.meta.env.NODE_ENV === "development", + returnNull: false, + fallbackLng: "en", + interpolation: { + escapeValue: false, + }, + react: { + useSuspense: false, + }, + load: "languageOnly", + detection: { + caches: ["localStorage", "sessionStorage", "cookie"], + }, + backend: { + loadPath: joinPaths([import.meta.env.BASE_URL, `locales/{{lng}}.json`]), + }, }, - }, function(err, t) { - dayjs.locale(i18n.language); - }); + function (err, t) { + dayjs.locale(i18n.language); + } + ); i18n.on("languageChanged", (lng) => { dayjs.locale(lng); }); // DataPicker -registerLocale('es', es); -registerLocale('zh-cn', zh); +registerLocale("zh-cn", zh); +registerLocale("ru", ru); +registerLocale("fa", fa); export default i18n; From 9d9381054ed830dfe0c757db552acff7716cf7ae Mon Sep 17 00:00:00 2001 From: Gozarman Date: Sun, 10 Sep 2023 13:18:59 +0330 Subject: [PATCH 3/5] fix: donation badge --- app/dashboard/src/components/Header.tsx | 37 +++++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/app/dashboard/src/components/Header.tsx b/app/dashboard/src/components/Header.tsx index a1f1b513..c42608f9 100644 --- a/app/dashboard/src/components/Header.tsx +++ b/app/dashboard/src/components/Header.tsx @@ -24,6 +24,8 @@ import { } from "@heroicons/react/24/outline"; import { DONATION_URL, REPO_URL } from "constants/Project"; import { useDashboard } from "contexts/DashboardContext"; +import differenceInDays from "date-fns/differenceInDays"; +import isValid from "date-fns/isValid"; import { FC, ReactNode, useState } from "react"; import GitHubButton from "react-github-btn"; import { useTranslation } from "react-i18next"; @@ -63,6 +65,21 @@ const NotificationCircle = chakra(Box, { const NOTIFICATION_KEY = "marzban-menu-notification"; +export const shouldShowDonation = (): boolean => { + const date = localStorage.getItem(NOTIFICATION_KEY); + if (!date) return true; + try { + if (date && isValid(parseInt(date))) { + if (differenceInDays(new Date(), new Date(parseInt(date))) >= 7) + return true; + return false; + } + return true; + } catch (err) { + return true; + } +}; + export const Header: FC = ({ actions }) => { const { onEditingHosts, @@ -72,14 +89,14 @@ export const Header: FC = ({ actions }) => { } = useDashboard(); const { t } = useTranslation(); const { colorMode, toggleColorMode } = useColorMode(); - const [notificationsChecked, setNotificationChecked] = useState( - localStorage.getItem(NOTIFICATION_KEY) + const [showDonationNotif, setShowDonationNotif] = useState( + shouldShowDonation() ); const gBtnColor = colorMode === "dark" ? "dark_dimmed" : colorMode; const handleOnClose = () => { - localStorage.setItem(NOTIFICATION_KEY, "true"); - setNotificationChecked("true"); + localStorage.setItem(NOTIFICATION_KEY, new Date().getTime().toString()); + setShowDonationNotif(false); }; return ( @@ -91,13 +108,17 @@ export const Header: FC = ({ actions }) => { direction: "ltr", }, }} + position="relative" > {t("users")} + {showDonationNotif && ( + + )} - + = ({ actions }) => { icon={ <> - {!notificationsChecked && ( - - )} } position="relative" @@ -151,9 +169,10 @@ export const Header: FC = ({ actions }) => { fontSize="sm" icon={} position="relative" + onClick={handleOnClose} > {t("header.donation")}{" "} - {!notificationsChecked && ( + {showDonationNotif && ( )} From 31cca8f91af3ca4e401af0deb12c3526d4c17dff Mon Sep 17 00:00:00 2001 From: Gozarman Date: Sun, 10 Sep 2023 13:21:56 +0330 Subject: [PATCH 4/5] chore: TON donation address --- README-fa.md | 16 ++++++------ README-zh-cn.md | 5 ++-- README.md | 65 +++++++++++++++++++++++++------------------------ 3 files changed, 45 insertions(+), 41 deletions(-) diff --git a/README-fa.md b/README-fa.md index 2d6fa958..5c42197f 100755 --- a/README-fa.md +++ b/README-fa.md @@ -58,8 +58,8 @@ ## فهرست مطالب - [بررسی اجمالی](#بررسی-اجمالی) - - [چرا مرزبان؟](#چرا-مرزبان) - - [امکانات](#امکانات) + - [چرا مرزبان؟](#چرا-مرزبان) + - [امکانات](#امکانات) - [راهنمای نصب](#راهنمای-نصب) - [تنظیمات](#تنظیمات) - [استفاده از API](#استفاده-از-api) @@ -113,7 +113,7 @@ sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban-scripts/raw/master/ - فایل های مرزبان در پوشه `/opt/marzban` قرار می‌گیرند - فایل تنظیمات در مسیر `/opt/marzban/.env` قرار می‌گیرد ([تنظیمات](#تنظیمات) را مشاهده کنید) - فایل های مهم (اطلاعات) مرزبان در مسیر `/usr/lib/marzban` قرار می‌گیرند -- شما از طریق آدرس `http://YOUR_SERVER_IP:8000/dashboard/` می‌توانید وارد داشبورد مرزبان شوید (YOUR_SERVER_IP را با آیپی سرور خود عوض کنید) +- شما از طریق آدرس `http://YOUR_SERVER_IP:8000/dashboard/` می‌توانید وارد داشبورد مرزبان شوید (YOUR_SERVER_IP را با آیپی سرور خود عوض کنید) در مرحله بعد, باید یک ادمین سودو بسازید @@ -258,10 +258,10 @@ server { | فعالسازی حالت توسعه (development) (پیشفرض: `False`) | DEBUG | | WEBHOOK_ADDRESS | آدرس webhook که تغییرات حالت یک کاربر به آن ارسال می‌شوند. اگر این متغیر مقدار داشته باشد، ارسال پیام‌ها انجام می‌شوند. | | WEBHOOK_SECRET | متغیری که به عنوان `x-webhook-secret` در header ارسال می‌شود. (پیشفرض: `None`) | -| تعداد دفعاتی که برای ارسال یک پیام، در صورت تشخیص خطا در ارسال تلاش دوباره شود (پیشفرض `3`) | NUMBER_OF_RECURRENT_NOTIFICATIONS | -| مدت زمان بین هر ارسال دوباره پیام در صورت تشخیص خطا در ارسال به ثانیه (پیشفرض: `180`) | RECURRENT_NOTIFICATIONS_TIMEOUT | -| هنگام رسیدن مصرف کاربر به چه درصدی پیام اخطار به آدرس وبهوک ارسال شود (پیشفرض: `80`) | NOTIFY_REACHED_USAGE_PERCENT | -| چند روز مانده به انتهای سرویس پیام اخطار به آدرس وبهوک ارسال شود (پیشفرض: `3`) | NOTIFY_DAYS_LEFT | +| تعداد دفعاتی که برای ارسال یک پیام، در صورت تشخیص خطا در ارسال تلاش دوباره شود (پیشفرض `3`) | NUMBER_OF_RECURRENT_NOTIFICATIONS | +| مدت زمان بین هر ارسال دوباره پیام در صورت تشخیص خطا در ارسال به ثانیه (پیشفرض: `180`) | RECURRENT_NOTIFICATIONS_TIMEOUT | +| هنگام رسیدن مصرف کاربر به چه درصدی پیام اخطار به آدرس وبهوک ارسال شود (پیشفرض: `80`) | NOTIFY_REACHED_USAGE_PERCENT | +| چند روز مانده به انتهای سرویس پیام اخطار به آدرس وبهوک ارسال شود (پیشفرض: `3`) | NOTIFY_DAYS_LEFT | # استفاده از API @@ -336,6 +336,8 @@ Body: - شبکه ETH، BNB، MATIC: `0xFdc9ad32454FA4fc4733270FCc12ddBFb68b83F7` - شبکه بیت کوین: `bc1qpys2nefgsjjgae3g3gqy9crsv3h3rm96tlkz0v` - شبکه Dogecoin: `DJAocBAu8y6LwhDKUktLAyzV8xyoFeHH6R` +- شبکه TON: `EQAVf-7hAXHlF-jmrKE44oBwN7HGQFVBLAtrOsev5K4qR4P8` + از حمایت شما متشکرم! diff --git a/README-zh-cn.md b/README-zh-cn.md index 3e1a8068..4696cfde 100644 --- a/README-zh-cn.md +++ b/README-zh-cn.md @@ -58,8 +58,8 @@ ## 目录 - [概览](#概览) - - [为什么要使用 Marzban?](#为什么要使用-marzban) - - [特性](#特性) + - [为什么要使用 Marzban?](#为什么要使用-marzban) + - [特性](#特性) - [安装指南](#安装指南) - [配置](#配置) - [如何使用 API](#如何使用-api) @@ -305,6 +305,7 @@ Marzban 配备了一个集成的 Telegram bot,可以处理服务器管理、 - ETH、BNB、MATIC 网络:`0xFdc9ad32454FA4fc4733270FCc12ddBFb68b83F7` - 比特币网络:`bc1qpys2nefgsjjgae3g3gqy9crsv3h3rm96tlkz0v` - Dogecoin 网络:`DJAocBAu8y6LwhDKUktLAyzV8xyoFeHH6R` +- TON 网络:`EQAVf-7hAXHlF-jmrKE44oBwN7HGQFVBLAtrOsev5K4qR4P8` 感谢您的支持! diff --git a/README.md b/README.md index dfa71279..20f690b7 100755 --- a/README.md +++ b/README.md @@ -259,38 +259,38 @@ By default the app will be run on `http://localhost:8000/dashboard`. You can con > You can set settings below using environment variables or placing them in `.env` file. -| Variable | Description | -| ------------------------------- | ----------------------------------------------------------------------------------------------------- | -| SUDO_USERNAME | Superuser's username | -| SUDO_PASSWORD | Superuser's password | -| SQLALCHEMY_DATABASE_URL | Database URL ([SQLAlchemy's docs](https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls)) | -| UVICORN_HOST | Bind application to this host (default: `0.0.0.0`) | -| UVICORN_PORT | Bind application to this port (default: `8000`) | -| UVICORN_UDS | Bind application to a UNIX domain socket | -| UVICORN_SSL_CERTFILE | SSL certificate file to have application on https | -| UVICORN_SSL_KEYFILE | SSL key file to have application on https | -| XRAY_JSON | Path of Xray's json config file (default: `xray_config.json`) | -| XRAY_EXECUTABLE_PATH | Path of Xray binary (default: `/usr/local/bin/xray`) | -| XRAY_ASSETS_PATH | Path of Xray assets (default: `/usr/local/share/xray`) | -| XRAY_SUBSCRIPTION_URL_PREFIX | Prefix of subscription URLs | -| XRAY_FALLBACKS_INBOUND_TAG | Tag of the inbound that includes fallbacks, needed in the case you're using fallbacks | -| XRAY_EXCLUDE_INBOUND_TAGS | Tags of the inbounds that shouldn't be managed and included in links by application | -| CUSTOM_TEMPLATES_DIRECTORY | Customized templates directory (default: `app/templates`) | -| CLASH_SUBSCRIPTION_TEMPLATE | The template that will be used for generating clash configs (default: `clash/default.yml`) | -| SUBSCRIPTION_PAGE_TEMPLATE | The template used for generating subscription info page (default: `subscription/index.html`) | -| HOME_PAGE_TEMPLATE | Decoy page template (default: `home/index.html`) | -| TELEGRAM_API_TOKEN | Telegram bot API token (get token from [@botfather](https://t.me/botfather)) | -| TELEGRAM_ADMIN_ID | Numeric Telegram ID of admin (use [@userinfobot](https://t.me/userinfobot) to found your ID) | -| TELEGRAM_PROXY_URL | Run Telegram Bot over proxy | -| JWT_ACCESS_TOKEN_EXPIRE_MINUTES | Expire time for the Access Tokens in minutes, `0` considered as infinite (default: `1440`) | -| DOCS | Whether API documents should be available on `/docs` and `/redoc` or not (default: `False`) | -| DEBUG | Debug mode for development (default: `False`) | -| WEBHOOK_ADDRESS | Webhook address to send notifications to. Webhook notifications will be sent if this value was set. | -| WEBHOOK_SECRET | Webhook secret will be sent with each request as `x-webhook-secret` in the header (default: `None`) | -| NUMBER_OF_RECURRENT_NOTIFICATIONS | How many times to retry if an error detected in sending a notification (default: `3`) | -| RECURRENT_NOTIFICATIONS_TIMEOUT | Timeout between each retry if an error detected in sending a notification in seconds (default: `180`)| -| NOTIFY_REACHED_USAGE_PERCENT | At which percentage of usage to send the warning notification (default: `80`) | -| NOTIFY_DAYS_LEFT | When to send warning notifaction about expiration (default: `3`) | +| Variable | Description | +| --------------------------------- | ----------------------------------------------------------------------------------------------------- | +| SUDO_USERNAME | Superuser's username | +| SUDO_PASSWORD | Superuser's password | +| SQLALCHEMY_DATABASE_URL | Database URL ([SQLAlchemy's docs](https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls)) | +| UVICORN_HOST | Bind application to this host (default: `0.0.0.0`) | +| UVICORN_PORT | Bind application to this port (default: `8000`) | +| UVICORN_UDS | Bind application to a UNIX domain socket | +| UVICORN_SSL_CERTFILE | SSL certificate file to have application on https | +| UVICORN_SSL_KEYFILE | SSL key file to have application on https | +| XRAY_JSON | Path of Xray's json config file (default: `xray_config.json`) | +| XRAY_EXECUTABLE_PATH | Path of Xray binary (default: `/usr/local/bin/xray`) | +| XRAY_ASSETS_PATH | Path of Xray assets (default: `/usr/local/share/xray`) | +| XRAY_SUBSCRIPTION_URL_PREFIX | Prefix of subscription URLs | +| XRAY_FALLBACKS_INBOUND_TAG | Tag of the inbound that includes fallbacks, needed in the case you're using fallbacks | +| XRAY_EXCLUDE_INBOUND_TAGS | Tags of the inbounds that shouldn't be managed and included in links by application | +| CUSTOM_TEMPLATES_DIRECTORY | Customized templates directory (default: `app/templates`) | +| CLASH_SUBSCRIPTION_TEMPLATE | The template that will be used for generating clash configs (default: `clash/default.yml`) | +| SUBSCRIPTION_PAGE_TEMPLATE | The template used for generating subscription info page (default: `subscription/index.html`) | +| HOME_PAGE_TEMPLATE | Decoy page template (default: `home/index.html`) | +| TELEGRAM_API_TOKEN | Telegram bot API token (get token from [@botfather](https://t.me/botfather)) | +| TELEGRAM_ADMIN_ID | Numeric Telegram ID of admin (use [@userinfobot](https://t.me/userinfobot) to found your ID) | +| TELEGRAM_PROXY_URL | Run Telegram Bot over proxy | +| JWT_ACCESS_TOKEN_EXPIRE_MINUTES | Expire time for the Access Tokens in minutes, `0` considered as infinite (default: `1440`) | +| DOCS | Whether API documents should be available on `/docs` and `/redoc` or not (default: `False`) | +| DEBUG | Debug mode for development (default: `False`) | +| WEBHOOK_ADDRESS | Webhook address to send notifications to. Webhook notifications will be sent if this value was set. | +| WEBHOOK_SECRET | Webhook secret will be sent with each request as `x-webhook-secret` in the header (default: `None`) | +| NUMBER_OF_RECURRENT_NOTIFICATIONS | How many times to retry if an error detected in sending a notification (default: `3`) | +| RECURRENT_NOTIFICATIONS_TIMEOUT | Timeout between each retry if an error detected in sending a notification in seconds (default: `180`) | +| NOTIFY_REACHED_USAGE_PERCENT | At which percentage of usage to send the warning notification (default: `80`) | +| NOTIFY_DAYS_LEFT | When to send warning notifaction about expiration (default: `3`) | # API @@ -366,6 +366,7 @@ If you found Marzban useful and would like to support its development, you can m - ETH, BNB, MATIC network (ERC20, BEP20): `0xFdc9ad32454FA4fc4733270FCc12ddBFb68b83F7` - Bitcoin network: `bc1qpys2nefgsjjgae3g3gqy9crsv3h3rm96tlkz0v` - Dogecoin network: `DJAocBAu8y6LwhDKUktLAyzV8xyoFeHH6R` +- TON network: `EQAVf-7hAXHlF-jmrKE44oBwN7HGQFVBLAtrOsev5K4qR4P8` Thank you for your support! From 0665ca86e3d9613875e928a1405bd74f3038efda Mon Sep 17 00:00:00 2001 From: Gozarman Date: Sun, 10 Sep 2023 20:45:42 +0330 Subject: [PATCH 5/5] fix: russian language typo --- app/dashboard/src/components/Language.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dashboard/src/components/Language.tsx b/app/dashboard/src/components/Language.tsx index 6a840109..aa6529ed 100644 --- a/app/dashboard/src/components/Language.tsx +++ b/app/dashboard/src/components/Language.tsx @@ -64,7 +64,7 @@ export const Language: FC = ({ actions }) => { fontSize="sm" onClick={() => changeLanguage("ru")} > - русский + Русский