mirror of
https://github.com/JonnyBro/JaBa.git
synced 2024-11-24 14:14:59 +05:00
v3.2.8
Статистика пользователя и сервера на сайте Удалён лишний файл Отключена комадна someone Фикс currentURL в переменных страниц Обновлена локализация
This commit is contained in:
parent
373c861a10
commit
b0deb2e447
27 changed files with 520 additions and 156 deletions
|
@ -63,6 +63,7 @@ class Profile extends Command {
|
|||
})
|
||||
})
|
||||
.setImage("attachment://achievements.png")
|
||||
.addField(this.client.customEmojis.link + " " + message.translate("economy/profile:LINK"), `[${message.translate("economy/profile:LINK_TEXT")}](https://jaba.pp.ua/user/${member.user.id}/${message.guild.id})`)
|
||||
.addField(message.translate("economy/profile:BIO"), userData.bio ? userData.bio : message.translate("economy/profile:NO_BIO"))
|
||||
.addField(message.translate("economy/profile:CASH"), `**${memberData.money}** ${message.getNoun(memberData.money, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
|
||||
.addField(message.translate("economy/profile:BANK"), `**${memberData.bankSold}** ${message.getNoun(memberData.bankSold, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`, true)
|
||||
|
|
|
@ -41,13 +41,14 @@ class Serverinfo extends Command {
|
|||
.setThumbnail(guild.iconURL({
|
||||
dynamic: true
|
||||
}))
|
||||
.addField(this.client.customEmojis.link + " " + message.translate("general/serverinfo:LINK"), `[${message.translate("general/serverinfo:LINK_TEXT")}](https://jaba.pp.ua/stats/${guild.id})`)
|
||||
.addField(this.client.customEmojis.title + message.translate("common:NAME"), guild.name, true)
|
||||
.addField(this.client.customEmojis.calendar + message.translate("common:CREATION"), message.printDate(guild.createdAt), true)
|
||||
.addField(this.client.customEmojis.users + message.translate("common:MEMBERS"),
|
||||
`${guild.members.cache.filter(m => !m.user.bot).size} ${message.getNoun(guild.members.cache.filter(m => !m.user.bot).size, message.translate("misc:NOUNS:MEMBERS:1"), message.translate("misc:NOUNS:MEMBERS:2"), message.translate("misc:NOUNS:MEMBERS:5"))}` +
|
||||
"\n" + `${guild.members.cache.filter(m => m.user.bot).size} ${message.getNoun(guild.members.cache.filter(m => m.user.bot).size, message.translate("misc:NOUNS:BOTS:1"), message.translate("misc:NOUNS:BOTS:2"), message.translate("misc:NOUNS:BOTS:5"))}`, true
|
||||
)
|
||||
.addField(this.client.customEmojis.afk + message.translate("general/serverinfo:AFK_CHANNEL"), guild.afkChannel.toString() || message.translate("general/serverinfo:NO_AFK_CHANNEL"), true)
|
||||
.addField(this.client.customEmojis.afk + message.translate("general/serverinfo:AFK_CHANNEL"), guild.afkChannel ? guild.afkChannel.toString() : message.translate("general/serverinfo:NO_AFK_CHANNEL"), true)
|
||||
.addField(this.client.customEmojis.id + message.translate("common:ID"), guild.id, true)
|
||||
.addField(this.client.customEmojis.crown + message.translate("common:OWNER"), owner.toString(), true)
|
||||
.addField(this.client.customEmojis.boost + message.translate("general/serverinfo:BOOSTS"), guild.premiumSubscriptionCount.toString() || "0", true)
|
||||
|
|
|
@ -6,7 +6,7 @@ class Someone extends Command {
|
|||
super(client, {
|
||||
name: "someone",
|
||||
dirname: __dirname,
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
guildOnly: true,
|
||||
aliases: ["somebody"],
|
||||
memberPermissions: [],
|
||||
|
|
|
@ -46,9 +46,8 @@ class Stats extends Command {
|
|||
.addField(message.translate("general/stats:CREDITS_TITLE"), message.translate("general/stats:CREDITS_CONTENT", {
|
||||
donators: ["**`Добрый Спецназ#8801`** - Тестер, генератор идей"].join("\n"),
|
||||
translators: ["**`Jonny_Bro#4226`** (:flag_ru:)"].join("\n")
|
||||
}));
|
||||
|
||||
statsEmbed.addField(this.client.customEmojis.link + " " + message.translate("general/stats:LINKS_TITLE"), message.translate("misc:STATS_FOOTER", {
|
||||
}))
|
||||
.addField(this.client.customEmojis.link + " " + message.translate("general/stats:LINKS_TITLE"), message.translate("misc:STATS_FOOTER", {
|
||||
dashboardLink: "https://jaba.pp.ua/",
|
||||
docsLink: "https://jaba.pp.ua/docs/",
|
||||
donateLink: "https://qiwi.com/n/JONNYBRO/",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
const Command = require("../../base/Command");
|
||||
|
||||
class Eval extends Command {
|
||||
|
@ -16,7 +17,7 @@ class Eval extends Command {
|
|||
});
|
||||
}
|
||||
|
||||
async run(message) {
|
||||
async run(message, data) {
|
||||
const content = message.content.split(" ").slice(1).join(" ");
|
||||
const result = new Promise((resolve) => resolve(eval(content)));
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ module.exports.load = async(client) => {
|
|||
discordAPIRouter = require("./routes/discord"),
|
||||
logoutRouter = require("./routes/logout"),
|
||||
profileRouter = require("./routes/profile"),
|
||||
userRouter = require("./routes/user"),
|
||||
guildStatsRouter = require("./routes/guild-stats"),
|
||||
guildManagerRouter = require("./routes/guild-manager"),
|
||||
docsManagerRouter = require("./routes/docs");
|
||||
|
@ -52,6 +53,7 @@ module.exports.load = async(client) => {
|
|||
.use("/manage", guildManagerRouter)
|
||||
.use("/stats", guildStatsRouter)
|
||||
.use("/profile", profileRouter)
|
||||
.use("/user", userRouter)
|
||||
.use("/", mainRouter)
|
||||
.use("/docs", docsManagerRouter)
|
||||
.use(CheckAuth, function(req, res) {
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
### JaBa v3.2.7
|
||||
* Добавлено
|
||||
* Статистика сервера на сайте ([пример](https://jaba.pp.ua/stats/651412418202959872)).
|
||||
* Профиль пользователя определённого сервера на сайте ([пример](https://jaba.pp.ua/user/281361531411890186/651412418202959872))
|
||||
Ссылки на статистику сервера и профиль пользователя можно найти в *serverinfo* и *profile (@пользователь)* соответственно.
|
||||
|
||||
* Изменения
|
||||
* Отключены команда *someone* и тэг *@someone*.
|
||||
|
||||
### JaBa v3.2.7
|
||||
* Добавлено
|
||||
* Некоторая информация о вашем профиле на сайте, на страницах серверов и в настройках.
|
||||
|
@ -15,7 +24,6 @@
|
|||
* Команда *setafk* и ответ бота автоматически удаляются через 10 секунд.
|
||||
* Новые карточки при входе и выходе пользователей
|
||||
(Я не дизайнер, не бейте :().
|
||||
* Обновлена локализация для карточек.
|
||||
|
||||
### JaBa v3.2.5
|
||||
* Изменения
|
||||
|
@ -77,7 +85,6 @@
|
|||
* Некорректное описание *seek*.
|
||||
* Некорректная работа *seek*.
|
||||
* Некорректное описание *unban*.
|
||||
* Мелкие правки в локализации.
|
||||
|
||||
### JaBa v3.1.5
|
||||
* Изменено
|
||||
|
@ -114,7 +121,7 @@
|
|||
|
||||
### JaBa v3.1
|
||||
* Изменено
|
||||
* Обновлена русская локализация, исправлены орфографические ошибки.
|
||||
* Исправлены орфографические ошибки в русской локализации.
|
||||
* Отключёна английская локализация.
|
||||
* Исправлены ошибки.
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
const express = require("express"),
|
||||
router = express.Router(),
|
||||
fs = require("fs"),
|
||||
marked = require("marked");
|
||||
|
||||
router.get("/", function (req, res) {
|
||||
var md = function (filename) {
|
||||
return marked.parse(fs.readFileSync("./dashboard/views/docs/" + filename, "utf8"));
|
||||
};
|
||||
|
||||
res.render("commands", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`,
|
||||
"md": md
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
|
@ -5,7 +5,7 @@ router.get("/", function (req, res) {
|
|||
res.render("docs", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ router.get("/:serverID", CheckAuth, async(req, res) => {
|
|||
return res.render("404", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ router.get("/:serverID", CheckAuth, async(req, res) => {
|
|||
translate: req.translate,
|
||||
bot: req.client,
|
||||
convertTime: req.convertTime,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -36,7 +36,7 @@ router.post("/:serverID", CheckAuth, async(req, res) => {
|
|||
return res.render("404", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ router.post("/:serverID", CheckAuth, async(req, res) => {
|
|||
const data = req.body;
|
||||
|
||||
if (data.language) {
|
||||
const language = req.client.languages.find((language) => language.aliases[0].toLowerCase() === data.language.toLowerCase());
|
||||
const language = req.client.languages.find((language) => language.nativeName.toLowerCase() === data.language.toLowerCase());
|
||||
if (language) guildData.language = language.name;
|
||||
if (data.prefix.length >= 1 && data.prefix.length < 2000) guildData.prefix = data.prefix;
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
const express = require("express"),
|
||||
utils = require("../utils"),
|
||||
CheckAuth = require("../auth/CheckAuth"),
|
||||
router = express.Router(),
|
||||
generator = require("colors-generator");
|
||||
router = express.Router();
|
||||
|
||||
router.get("/:serverID", CheckAuth, async (req, res) => {
|
||||
// Check if the user has the permissions to edit this guild
|
||||
|
@ -10,19 +9,19 @@ router.get("/:serverID", CheckAuth, async(req, res) => {
|
|||
if (!guild || !req.userInfos.displayedGuilds || !req.userInfos.displayedGuilds.find((g) => g.id === req.params.serverID)) {
|
||||
return res.render("404", {
|
||||
user: req.userInfos,
|
||||
language: req.language,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch guild informations
|
||||
const guildInfos = await utils.fetchGuild(guild.id, req.client, req.user.guilds);
|
||||
|
||||
const membersData = await req.client.membersData.find({ guildID: guild.id }).lean();
|
||||
const membersData = await req.client.membersData.find({
|
||||
guildID: guild.id
|
||||
}).lean();
|
||||
|
||||
const leaderboards = {
|
||||
money: sortArrayOfObjects("money", membersData),
|
||||
level: sortArrayOfObjects("level", membersData)
|
||||
money: utils.sortArrayOfObjects("money", membersData),
|
||||
level: utils.sortArrayOfObjects("level", membersData)
|
||||
};
|
||||
|
||||
for (const cat in leaderboards) {
|
||||
|
@ -36,77 +35,13 @@ router.get("/:serverID", CheckAuth, async(req, res) => {
|
|||
};
|
||||
|
||||
res.render("stats/guild", {
|
||||
stats,
|
||||
commands: getCommands(guildInfos.commands.filter((c) => c.date > Date.now()-604800000)),
|
||||
commandsUsage: getCommandsUsage(guildInfos.commands),
|
||||
user: req.userInfos,
|
||||
language: req.language,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`,
|
||||
stats,
|
||||
bot: req.client,
|
||||
guildID: guild.id,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
function getCommands(commands) {
|
||||
const aDateCommand = {};
|
||||
commands.forEach((cmd) => {
|
||||
const tDate = formatDate(new Date(cmd.date));
|
||||
if (aDateCommand[tDate]) aDateCommand[tDate]++;
|
||||
else aDateCommand[tDate] = 1;
|
||||
});
|
||||
return aDateCommand;
|
||||
}
|
||||
|
||||
function getCommandsUsage(commands) {
|
||||
const objectCount = commands.reduce((acc, curr) => {
|
||||
if (typeof acc[curr.command] == "undefined") acc[curr.command] = 1;
|
||||
else acc[curr.command] += 1;
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
const percentages = getPercentagePerKey(objectCount); // [ { key: "help", percentage: 20 } ]
|
||||
const colors = generator.generate("#86bff2", percentages.length).get();
|
||||
let i = 0;
|
||||
percentages.forEach((p) => {
|
||||
p.color = colors[i];
|
||||
i++;
|
||||
});
|
||||
|
||||
return percentages;
|
||||
}
|
||||
|
||||
function getPercentagePerKey(myArray) {
|
||||
const sum = getSum(myArray);
|
||||
const arrayWithPercentages = [];
|
||||
for (const key in myArray) {
|
||||
const val = myArray[key];
|
||||
const percentage = Math.round((val / sum) * 100);
|
||||
arrayWithPercentages.push({key, percentage});
|
||||
}
|
||||
|
||||
return arrayWithPercentages;
|
||||
}
|
||||
|
||||
function getSum(myArray) {
|
||||
let sum = 0;
|
||||
for (const key in myArray) sum += myArray[key];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
function sortArrayOfObjects(key, arr) {
|
||||
const array = arr.slice(0);
|
||||
return array.sort((a, b) => {
|
||||
return b[key] - a[key];
|
||||
});
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
let dd = date.getDate();
|
||||
let mm = date.getMonth() + 1;
|
||||
if (dd < 10) dd = `0${dd}`;
|
||||
if (mm < 10) mm = `0${mm}`;
|
||||
date = `${mm}/${dd}`;
|
||||
|
||||
return date;
|
||||
}
|
|
@ -10,7 +10,7 @@ router.get("/selector", CheckAuth, async(req, res) => {
|
|||
res.render("selector", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@ const express = require("express"),
|
|||
router.get("/", CheckAuth, async function(req, res) {
|
||||
res.render("profile", {
|
||||
user: req.userInfos,
|
||||
bot: req.client,
|
||||
translate: req.translate,
|
||||
printDate: req.printDate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}/${req.originalUrl}`
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
});
|
||||
|
||||
|
|
38
dashboard/routes/user.js
Normal file
38
dashboard/routes/user.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
const express = require("express"),
|
||||
utils = require("../utils"),
|
||||
CheckAuth = require("../auth/CheckAuth"),
|
||||
router = express.Router();
|
||||
|
||||
// Gets user page
|
||||
router.get("/:userID/:serverID", CheckAuth, async function (req, res) {
|
||||
const guild = req.client.guilds.cache.get(req.params.serverID);
|
||||
if (!guild || !req.userInfos.displayedGuilds || !req.userInfos.displayedGuilds.find((g) => g.id === req.params.serverID)) {
|
||||
return res.render("404", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
}
|
||||
|
||||
const guildData = await req.client.findOrCreateGuild({ id: guild.id });
|
||||
await utils.fetchUser({
|
||||
id: req.params.userID
|
||||
}, req.client).catch(() => {
|
||||
res.render("404", {
|
||||
user: req.userInfos,
|
||||
translate: req.translate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
});
|
||||
|
||||
res.render("user", {
|
||||
user: req.userInfos,
|
||||
guild: guildData,
|
||||
bot: req.client,
|
||||
translate: req.translate,
|
||||
printDate: req.printDate,
|
||||
currentURL: `${req.client.config.dashboard.baseURL}${req.originalUrl}`
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = router;
|
|
@ -1,18 +1,5 @@
|
|||
const { Permissions } = require("discord.js");
|
||||
|
||||
/**
|
||||
* Fetch guild informations
|
||||
* @param {string} guildID The ID of the guild to fetch
|
||||
* @param {object} client The discord client instance
|
||||
* @param {array} guilds The user guilds
|
||||
*/
|
||||
async function fetchGuild(guildID, client, guilds) {
|
||||
const guild = client.guilds.cache.get(guildID);
|
||||
const conf = await client.findOrCreateGuild({ id:guild.id });
|
||||
|
||||
return { ...guild, ...conf.toJSON(), ...guilds.find((g) => g.id === guild.id) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch user informations (stats, guilds, etc...)
|
||||
* @param {object} userData The oauth2 user informations
|
||||
|
@ -24,6 +11,7 @@ async function fetchUser(userData, client, query) {
|
|||
if (userData.guilds) {
|
||||
userData.guilds.forEach((guild) => {
|
||||
if (!client.guilds.cache.get(guild.id)) return;
|
||||
// eslint-disable-next-line no-undef
|
||||
const perms = new Permissions(BigInt(guild.permissions));
|
||||
if (perms.has(Permissions.FLAGS.MANAGE_GUILD)) guild.admin = true;
|
||||
|
||||
|
@ -36,10 +24,72 @@ async function fetchUser(userData, client, query) {
|
|||
if (userData.displayedGuilds.length < 1) delete userData.displayedGuilds;
|
||||
}
|
||||
const user = await client.users.fetch(userData.id);
|
||||
const userDb = await client.findOrCreateUser({ id: user.id }, true);
|
||||
const userInfos = { ...user.toJSON(), ...userDb, ...userData };
|
||||
const userDb = await client.findOrCreateUser({
|
||||
id: user.id
|
||||
}, true);
|
||||
const userInfos = {
|
||||
...user.toJSON(),
|
||||
...userDb,
|
||||
...userData
|
||||
};
|
||||
|
||||
return userInfos;
|
||||
}
|
||||
|
||||
module.exports = { fetchUser, fetchGuild };
|
||||
/**
|
||||
* Fetch users informations
|
||||
* @param {object} array The array of users
|
||||
* @param {object} client The discord client instance
|
||||
* @returns {object} The user informations
|
||||
*/
|
||||
async function fetchUsers(array, client) {
|
||||
return new Promise((resolve) => {
|
||||
const users = [];
|
||||
array.filter((e) => e.id).forEach((element) => {
|
||||
client.users.fetch(element.id).then((user) => {
|
||||
user.username = user.username.replace(/[\W_]+/g, " ");
|
||||
if (user.username.length > 13) {
|
||||
user.username = user.username.substr(0, 10) + "...";
|
||||
}
|
||||
users.push({
|
||||
...{
|
||||
money: element.money,
|
||||
level: element.level,
|
||||
rep: element.rep
|
||||
},
|
||||
...user.toJSON()
|
||||
});
|
||||
});
|
||||
});
|
||||
resolve(users);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch guild informations
|
||||
* @param {string} guildID The ID of the guild to fetch
|
||||
* @param {object} client The discord client instance
|
||||
* @param {array} guilds The user guilds
|
||||
* @returns {object} The guild informations
|
||||
*/
|
||||
async function fetchGuild(guildID, client, guilds) {
|
||||
const guild = client.guilds.cache.get(guildID);
|
||||
const conf = await client.findOrCreateGuild({
|
||||
id: guild.id
|
||||
});
|
||||
|
||||
return {
|
||||
...guild,
|
||||
...conf.toJSON(),
|
||||
...guilds.find((g) => g.id === guild.id)
|
||||
};
|
||||
}
|
||||
|
||||
function sortArrayOfObjects(key, arr) {
|
||||
const array = arr.slice(0);
|
||||
return array.sort((a, b) => {
|
||||
return b[key] - a[key];
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { fetchUser, fetchUsers, fetchGuild, sortArrayOfObjects };
|
|
@ -16,7 +16,7 @@
|
|||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
404 Error Page
|
||||
Ошибка 404
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1>
|
||||
500 Error Page
|
||||
Ошибка 500
|
||||
</h1>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<div class="row">
|
||||
<div class="col-md-2 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="fa fa-area-chart"></i></span>
|
||||
<span class="info-box-icon bg-red"><i class="fa fa-area-chart"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text"><%= translate("common:LEVEL") %></span>
|
||||
<span class="info-box-number"><%= memberData.level %></span>
|
||||
|
@ -42,9 +42,9 @@
|
|||
<!-- /.col -->
|
||||
<div class="col-md-2 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="fa fa-area-chart"></i></span>
|
||||
<span class="info-box-icon bg-red"><i class="fa fa-line-chart"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text"><%= translate("dashboard:EXP") %></span>
|
||||
<span class="info-box-text"><%= translate("economy/profile:EXP").substr(2) %></span>
|
||||
<span class="info-box-number"><%= memberData.exp %> / <%= 5 * (memberData.level * memberData.level) + 80 * memberData.level + 100 %></span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
|
@ -56,7 +56,7 @@
|
|||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="fa fa-money"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text"><%= translate("common:CREDITS") %> / <%= translate("economy/transactions:BANK") %></span>
|
||||
<span class="info-box-text"><%= translate("economy/profile:CASH").substr(2) %> / <%= translate("economy/profile:BANK").substr(2) %></span>
|
||||
<span class="info-box-number"><%= memberData.money %> / <%= memberData.bankSold %></span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
|
@ -66,7 +66,7 @@
|
|||
<!-- /.col -->
|
||||
<div class="col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="fa fa-refresh"></i></span>
|
||||
<span class="info-box-icon bg-yellow"><i class="fa fa-refresh"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text"><%= translate("dashboard:COOLDOWNS") %></span>
|
||||
<span class="info-box-number"><%= translate("dashboard:REP") %>: <%= user.cooldowns.rep > Date.now() ? convertTime(user.cooldowns.rep) : translate("dashboard:CAN_USE") %></span>
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
<div class="row">
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="fa fa-star-o"></i></span>
|
||||
<span class="info-box-icon bg-yellow"><i class="fa fa-star-o"></i></span>
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text"><%= translate("dashboard:REPUTATION") %></span>
|
||||
<span class="info-box-text"><%= translate("economy/profile:REPUTATION").substr(2) %></span>
|
||||
<span class="info-box-number"><%= user.rep %></span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
|
@ -42,11 +42,64 @@
|
|||
</div>
|
||||
<!-- /.row -->
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- Widget: user widget style 1 -->
|
||||
<div class="box box-widget widget-user">
|
||||
<!-- Add the bg color to the header using any of the bg-* classes -->
|
||||
<div class="widget-user-header bg-red">
|
||||
<h3 class="widget-user-username"><%= user.tag %></h3>
|
||||
</div>
|
||||
<div class="widget-user-image">
|
||||
<img class="img-circle" src="<%= user.displayAvatarURL %>" alt="User Avatar">
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="description-block">
|
||||
<span
|
||||
class="description-text"><%= user.bio || translate("economy/profile:NO_BIO") %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header">
|
||||
<%= translate("economy/profile:BIRTHDATE").substr(2) %></h5>
|
||||
<span
|
||||
class="description-text"><%= user.birthdate ? printDate(new Date(user.birthdate)) : translate("economy/profile:NO_BIRTHDATE") %></span>
|
||||
</div>
|
||||
<!-- /.description-block -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header"><%= translate("economy/profile:REGISTERED").substr(2) %></h5>
|
||||
<span
|
||||
class="description-text"><%= printDate(new Date(user.registeredAt)) %></span>
|
||||
</div>
|
||||
<!-- /.description-block -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-sm-4">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header">
|
||||
<%= translate("economy/profile:LOVER").substr(2) %></h5>
|
||||
<span
|
||||
class="description-text"><%= !user.lover ? translate("economy/profile:NO_LOVER") : bot.users.cache.get(user.lover).tag %></span>
|
||||
</div>
|
||||
<!-- /.description-block -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.widget-user -->
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<!-- general form elements -->
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title"><%= translate("economy/profile:YOUR_PROFILE") %></h3>
|
||||
<h3 class="box-title"><%= translate("common:CONFIGURATION") %></h3>
|
||||
</div>
|
||||
<!-- /.box-header -->
|
||||
<!-- form start -->
|
||||
|
@ -55,12 +108,12 @@
|
|||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="form-group">
|
||||
<label><%= translate("economy/profile:BIO") %></label>
|
||||
<label><%= translate("economy/profile:BIO").substr(2) %></label>
|
||||
<input name="bio" class="form-control"
|
||||
placeholder="<%= user.bio || translate("economy/profile:NO_BIO") %>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><%= translate("economy/profile:BIRTHDATE") %></label>
|
||||
<label><%= translate("economy/profile:BIRTHDATE").substr(2) %></label>
|
||||
<div class="input-group date">
|
||||
<div class="input-group-addon">
|
||||
<i class="fa fa-calendar"></i>
|
||||
|
|
157
dashboard/views/stats/guild.ejs
Normal file
157
dashboard/views/stats/guild.ejs
Normal file
|
@ -0,0 +1,157 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<%- include("../includes/head") %>
|
||||
|
||||
<!-- bootstrap datepicker -->
|
||||
<link rel="stylesheet" href="/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css">
|
||||
|
||||
<body class="hold-transition skin-red sidebar-mini">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- The header is the topbar -->
|
||||
<%- include("../includes/header") %>
|
||||
|
||||
<!-- The sidebar includes the menu -->
|
||||
<%- include("../includes/sidebar") %>
|
||||
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1> <%= translate("dashboard:STATS") %> <i> <%= bot.guilds.cache.get(guildID).name %> </i> <small> Dashboard v1.0 </small> </h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
<!-- Main row -->
|
||||
<div class="row">
|
||||
<!-- Left col -->
|
||||
<section class="col-lg-8 col-sm-2 connectedSortable">
|
||||
<!-- Custom tabs (Charts with tabs)-->
|
||||
<div class="nav-tabs-custom">
|
||||
<!-- Tabs within a box -->
|
||||
<ul class="nav nav-tabs pull-right">
|
||||
<li class="active"><a href="#rank-money" data-toggle="tab">
|
||||
<%= translate("common:CREDITS") %></a></li>
|
||||
<li><a href="#rank-level" data-toggle="tab">
|
||||
<%= translate("common:LEVEL") %></a></li>
|
||||
<li class="pull-left header"><i class="fa fa-trophy"></i>
|
||||
<%= "Таблица лидеров" %></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="rank-money" style="position: relative; height: 300px;">
|
||||
<div class="chart">
|
||||
<canvas id="Crank-money" style="height:230px"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane active" id="rank-level" style="position: relative; height: 300px;">
|
||||
<div class="chart">
|
||||
<canvas id="Crank-level" style="height:230px"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.nav-tabs-custom -->
|
||||
</section>
|
||||
<!-- /.col -->
|
||||
<div class="col-md-4">
|
||||
<!-- Widget: user widget style 1 -->
|
||||
<div class="box box-widget widget-user-2">
|
||||
<!-- Add the bg color to the header using any of the bg-* classes -->
|
||||
<div class="widget-user-header bg-yellow">
|
||||
<div class="widget-user-image">
|
||||
<img class="img-circle" src="<%= stats.money[0].displayAvatarURL %>"
|
||||
alt="User Avatar">
|
||||
</div>
|
||||
<!-- /.widget-user-image -->
|
||||
<h3 class="widget-user-username"><a href="/user/<%= stats.money[0].id %>/<%= guildID %>"
|
||||
style="color:white"><%= stats.money[0].username %></a></h3>
|
||||
<h5 class="widget-user-desc"><%= translate("dashboard:TOP_CREDITS") %></h5>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.widget-user -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-md-4">
|
||||
<!-- Widget: user widget style 1 -->
|
||||
<div class="box box-widget widget-user-2">
|
||||
<!-- Add the bg color to the header using any of the bg-* classes -->
|
||||
<div class="widget-user-header bg-red">
|
||||
<div class="widget-user-image">
|
||||
<img class="img-circle" src="<%= stats.level[0].displayAvatarURL %>"
|
||||
alt="User Avatar">
|
||||
</div>
|
||||
<!-- /.widget-user-image -->
|
||||
<h3 class="widget-user-username"><a href="/user/<%= stats.level[0].id %>/<%= guildID %>"
|
||||
style="color:white"><%= stats.level[0].username %></a></h3>
|
||||
<h5 class="widget-user-desc"><%= translate("dashboard:TOP_LEVEL") %></h5>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.widget-user -->
|
||||
</div>
|
||||
<!-- ./box -->
|
||||
</div>
|
||||
</section>
|
||||
<!-- /.content -->
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
<%- include("../includes/footer") %>
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
<!-- bootstrap datepicker -->
|
||||
<script src="/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js"></script>
|
||||
<!-- ChartJS -->
|
||||
<script src="/bower_components/chart.js/Chart.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
$("#datepicker").datepicker({
|
||||
autoclose: true
|
||||
});
|
||||
|
||||
/* LEADERBOARD */
|
||||
let values = ["money", "level"];
|
||||
values.forEach((value) => {
|
||||
let members = JSON.parse(`<%- JSON.stringify(stats) %>`)[value];
|
||||
let data = {
|
||||
labels: members.map(a => a.username),
|
||||
datasets: [{
|
||||
label: "Leaderboard " + value,
|
||||
fillColor: "#00a65a",
|
||||
strokeColor: "#00a65a",
|
||||
pointColor: "#00a65a",
|
||||
pointStrokeColor: "rgba(60,141,188,1)",
|
||||
pointHighlightFill: "#fff",
|
||||
pointHighlightStroke: "rgba(60,141,188,1)",
|
||||
data: members.map(a => a[value])
|
||||
}]
|
||||
},
|
||||
leaderboardCanvas = $("#Crank-" + value).get(0).getContext("2d"),
|
||||
leaderboard = new Chart(leaderboardCanvas),
|
||||
leaderboardData = data,
|
||||
leaderboardOptions = {
|
||||
scaleBeginAtZero: !0,
|
||||
scaleShowGridLines: !0,
|
||||
scaleGridLineColor: "rgba(0,0,0,.05)",
|
||||
scaleGridLineWidth: 1,
|
||||
scaleShowHorizontalLines: !0,
|
||||
scaleShowVerticalLines: !0,
|
||||
barShowStroke: !0,
|
||||
barStrokeWidth: 2,
|
||||
barValueSpacing: 5,
|
||||
barDatasetSpacing: 1,
|
||||
responsive: !0,
|
||||
maintainAspectRatio: !0
|
||||
};
|
||||
leaderboardOptions.datasetFill = false
|
||||
leaderboard.Bar(leaderboardData, leaderboardOptions);
|
||||
});
|
||||
|
||||
$(`.tab-content > div[class="tab-pane active"]`).slice(1, 23).removeClass("active");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
134
dashboard/views/user.ejs
Normal file
134
dashboard/views/user.ejs
Normal file
|
@ -0,0 +1,134 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<%- include("includes/head") %>
|
||||
|
||||
<body class="hold-transition skin-red sidebar-mini">
|
||||
|
||||
<div class="wrapper">
|
||||
|
||||
<!-- The header is the topbar -->
|
||||
<%- include("includes/header") %>
|
||||
|
||||
<!-- The sidebar includes the menu -->
|
||||
<%- include("includes/sidebar") %>
|
||||
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1> <%= user.username %> <small> Dashboard v1.0 </small> </h1>
|
||||
</section>
|
||||
|
||||
<section class="content">
|
||||
<div class="col-md-12">
|
||||
<!-- Widget: user widget style 1 -->
|
||||
<div class="box box-widget widget-user">
|
||||
<!-- Add the bg color to the header using any of the bg-* classes -->
|
||||
<div class="widget-user-header bg-red">
|
||||
<h3 class="widget-user-username"><%= user.tag %></h3>
|
||||
<i><%= bot.guilds.cache.get(guild.id).name %></i>
|
||||
<p> <i>ID: <%= guild.id %></i> </p>
|
||||
</div>
|
||||
<div class="widget-user-image">
|
||||
<img class="img-circle" src="<%= user.displayAvatarURL %>" alt="User Avatar">
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="description-block">
|
||||
<span
|
||||
class="description-text"><%= user.bio || translate("economy/profile:NO_BIO") %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header">
|
||||
<%= translate("economy/profile:BIRTHDATE").substr(2) %></h5>
|
||||
<span
|
||||
class="description-text"><%= user.birthdate ? printDate(new Date(user.birthdate)) : translate("economy/profile:NO_BIRTHDATE") %></span>
|
||||
</div>
|
||||
<!-- /.description-block -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header"><%= translate("economy/profile:REGISTERED").substr(2) %></h5>
|
||||
<span
|
||||
class="description-text"><%= printDate(new Date(user.registeredAt)) %></span>
|
||||
</div>
|
||||
<!-- /.description-block -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-sm-4">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header">
|
||||
<%= translate("economy/profile:LOVER").substr(2) %></h5>
|
||||
<span
|
||||
class="description-text"><%= !user.lover ? translate("economy/profile:NO_LOVER") : bot.users.cache.get(user.lover).tag %></span>
|
||||
</div>
|
||||
<!-- /.description-block -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.widget-user -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-red"><i class="fa fa-area-chart"></i></span>
|
||||
|
||||
<div class="info-box-content">
|
||||
<span
|
||||
class="info-box-text"><%= translate("economy/profile:LEVEL").substr(2) %></span>
|
||||
<span class="info-box-number"><%= guild.members.find(u => u.id === user.id).level %></span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
<!-- /.info-box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-green"><i class="fa fa-money"></i></span>
|
||||
|
||||
<div class="info-box-content">
|
||||
<span
|
||||
class="info-box-text"><%= translate("economy/profile:CASH").substr(2) %> / <%= translate("economy/profile:BANK").substr(2) %></span>
|
||||
<span class="info-box-number"><%= guild.members.find(u => u.id === user.id).money %> / <%= guild.members.find(u => u.id === user.id).bankSold %></span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
<!-- /.info-box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
<div class="col-md-3 col-sm-6 col-xs-12">
|
||||
<div class="info-box">
|
||||
<span class="info-box-icon bg-yellow"><i class="fa fa-star-o"></i></span>
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text"><%= translate("economy/profile:REPUTATION").substr(2) %></span>
|
||||
<span class="info-box-number"><%= user.rep %></span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
<!-- /.info-box -->
|
||||
</div>
|
||||
<!-- /.col -->
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
<!-- Footer includes credits and version -->
|
||||
<%- include("includes/footer") %>
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -33,7 +33,7 @@ module.exports = class {
|
|||
else return message.sendT("misc:HELLO_DM");
|
||||
}
|
||||
|
||||
if (message.content.includes("@someone") && message.guild) return client.commands.get("someone").run(message, null, data);
|
||||
if (message.content.includes("@someone") && message.guild && client.commands.get("someone").conf.enabled) return client.commands.get("someone").run(message, null, data);
|
||||
|
||||
if (message.guild) {
|
||||
// Gets the data of the member
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"MEMBERS": "Участники",
|
||||
"NAME": "Название",
|
||||
"CHANNELS": "Каналы",
|
||||
"ID": "ID",
|
||||
"ID": "ID сервера",
|
||||
"OWNER": "Владелец",
|
||||
"USERNAME": "Имя пользователя",
|
||||
"DISCRIMINATOR": "Тег",
|
||||
|
@ -48,7 +48,7 @@
|
|||
"PAGE": "Страница",
|
||||
"MESSAGE": "Сообщение",
|
||||
"PROFILE": "Профиль",
|
||||
"CONFIGURATION": "Конфигурация",
|
||||
"CONFIGURATION": "Настройки",
|
||||
"PREFIX": "Префикс",
|
||||
"LANGUAGE": "Язык",
|
||||
"CHANNEL": "Канал",
|
||||
|
|
|
@ -21,13 +21,14 @@
|
|||
"ENABLE_AUTOROLE": "Включить",
|
||||
"DISABLE_AUTOROLE": "Выключить",
|
||||
"SELECTOR": "Выбор серверов",
|
||||
"STATS": "Статистика",
|
||||
"MANAGE": "Управление",
|
||||
"EXP": "Опыт",
|
||||
"REPUTATION": "Очки репутации",
|
||||
"COOLDOWNS": "Откаты",
|
||||
"REP": "Команда rep",
|
||||
"WORK": "Зарплата в work",
|
||||
"ROB": "Защита от rob",
|
||||
"CAN_USE": "Можно использовать",
|
||||
"NO_DEFENCE": "Вы беспомощны"
|
||||
"NO_DEFENCE": "Вы беспомощны",
|
||||
"TOP_LEVEL": "Первый по уровню",
|
||||
"TOP_CREDITS": "Первый по кредитам"
|
||||
}
|
|
@ -4,7 +4,8 @@
|
|||
"EXAMPLES": "{{prefix}}profile\n{{prefix}}profile @Jonny_Bro#4226",
|
||||
"BOT_USER": "У ботов нет профиля!",
|
||||
"TITLE": "Профиль {{username}}",
|
||||
"YOUR_PROFILE": "Ваш профиль",
|
||||
"LINK": "Профиль",
|
||||
"LINK_TEXT": "Нажмите сюда, чтобы открыть профиль на текущем сервере!",
|
||||
"BIO": "🔖 Биография",
|
||||
"NO_BIO": "Биография отсутствует",
|
||||
"CASH": "💵 Кредиты",
|
||||
|
|
|
@ -4,5 +4,7 @@
|
|||
"EXAMPLES": "{{prefix}}serverinfo кык\n{{prefix}}serverinfo",
|
||||
"AFK_CHANNEL": "AFK канал",
|
||||
"NO_AFK_CHANNEL": "Нет AFK канала",
|
||||
"BOOSTS": "Кол-во бустов"
|
||||
"BOOSTS": "Кол-во бустов",
|
||||
"LINK": "Статистика сервера",
|
||||
"LINK_TEXT": "Нажмите сюда, чтобы открыть статистику сервера!"
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jaba",
|
||||
"version": "3.2.7",
|
||||
"version": "3.2.8",
|
||||
"description": "A very complete Discord bot (more than 100 commands) that uses the Discord.js",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
|
|
Loading…
Reference in a new issue