Release0.7

Release0.7
This commit is contained in:
Dennis 2022-02-06 21:47:16 +01:00 committed by GitHub
commit babf8a5bf8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
179 changed files with 21871 additions and 3754 deletions

View file

@ -1,46 +1,28 @@
APP_NAME=Dashboard
### --- App Settings --- ###
APP_NAME=Controlpanel.gg
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=http://localhost
#list with timezones https://www.php.net/manual/en/timezones.php
# List with timezones https://www.php.net/manual/en/timezones.php
APP_TIMEZONE=UTC
### --- App Settings End --- ###
### --- DB Settings (required) --- ###
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dashboard
DB_USERNAME=dashboarduser
DB_PASSWORD=
### --- DB Settings End --- ###
#without a pterodactyl api token, this panel won't work!
PTERODACTYL_TOKEN=
#paypal details, you only need sandbox for testing! you can do this by setting the APP_ENV to local
PAYPAL_SANDBOX_SECRET=
PAYPAL_SANDBOX_CLIENT_ID=
PAYPAL_SECRET=
PAYPAL_CLIENT_ID=
PAYPAL_EMAIL=
#set-up for extra discord verification
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
#set-up will join users automaticly to your discord
DISCORD_BOT_TOKEN=
DISCORD_GUILD_ID=
#set-up will give the verified user the given role
DISCORD_ROLE_ID=
#nesseary URL's
PTERODACTYL_URL=https://panel.controlpanel.gg
PHPMYADMIN_URL=https://mysql.controlpanel.gg #optional. remove to remove database button
DISCORD_INVITE_URL=https://discord.gg/vrUYdxG4wZ
#GOOGLE RECAPTCHA
# Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)
RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
# Mail Server Settings - (HOST -> SMTP Server)
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
@ -51,10 +33,11 @@ MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
#you can leave everything below the way it is
# Laravel Logging Settings - https://laravel.com/docs/5.7/logging - Not needed to be changed
LOG_CHANNEL=stack
LOG_LEVEL=debug
# Do not change anything below this line
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=database

4
.gitignore vendored
View file

@ -18,3 +18,7 @@ yarn-error.log
.gitignore
.env.dev
.env.testing
storage/invoices.zip
storage/app/public/logo.png
*vscode
- Kopie.env

View file

@ -4,6 +4,12 @@ When contributing to this repository, please go through the open issues to see i
Please note we have a code of conduct, please follow it in all your interactions with the project.
If you added any Strings which are displayed at the frontend please localize them (e.g. "New String" -> {{ __('New String') }}) and run the localization string generation:
```cmd
php artisan translatable:export en
```
## Pull request process
1. Give your PR a good descriptive title, so we can view immediately what the PR is about.

View file

@ -1,26 +1,32 @@
### Features
- PayPal Integration
- Email Verification
- Audit Log
- Admin Dashboard
- User/Server Management
- Store (credit system)
- Vouchers
- and so much more!
- PayPal Integration
- Stripe Integration
- Email Verification
- Audit Log
- Admin Dashboard
- User/Server Management
- Store (credit system)
- Vouchers
- and so much more!
# ControlPanel-gg
![controlpanel](https://user-images.githubusercontent.com/45005889/123518824-06b05000-d6a8-11eb-91b9-d1ed36bd2317.png)
![](https://img.shields.io/github/stars/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/forks/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/tag/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/issues/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/license/ControlPanel-gg/dashboard) ![](https://img.shields.io/discord/787829714483019826)
![](https://img.shields.io/github/stars/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/forks/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/tag/ControlPanel-gg/dashboard) [![Crowdin](https://badges.crowdin.net/controlpanelgg/localized.svg)](https://crowdin.com/project/controlpanelgg) ![](https://img.shields.io/github/issues/ControlPanel-gg/dashboard) ![](https://img.shields.io/github/license/ControlPanel-gg/dashboard) ![](https://img.shields.io/discord/787829714483019826)
## About
ControlPanel's Dashboard is a dashboard application designed to offer clients a management tool to manage their pterodactyl servers. This dashboard comes with a credit-based billing solution that credits users hourly for each server they have and suspends them if they run out of credits.
This dashboard offers an easy to use and free billing solution for all starting and experienced hosting providers. This dashboard has many customization options and added discord 0auth verification to offer a solid link between your discord server and your dashboard.
### [Installation](https://controlpanel.gg/docs/intro "Installation")
### [Updating](https://controlpanel.gg/docs/Installation/updating "Updating")
### [Discord](https://discord.gg/4Y6HjD2uyU "discord")
### [Contributing](https://controlpanel.gg/docs/Contributing/contributing "Contributing")
### [Donating](https://controlpanel.gg/docs/Contributing/donating "Donating")

View file

@ -2,11 +2,11 @@
namespace App\Classes;
use App\Models\Configuration;
use App\Models\Egg;
use App\Models\Nest;
use App\Models\Node;
use App\Models\Server;
use App\Models\Settings;
use Exception;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\Response;
@ -17,7 +17,7 @@ class Pterodactyl
/**
* @description per_page option to pull more than the default 50 from pterodactyl
*/
public CONST PER_PAGE = 200;
public const PER_PAGE = 200;
//TODO: Extend error handling (maybe logger for more errors when debugging)
@ -27,10 +27,10 @@ class Pterodactyl
public static function client()
{
return Http::withHeaders([
'Authorization' => 'Bearer ' . env('PTERODACTYL_TOKEN', false),
'Authorization' => 'Bearer ' . config("SETTINGS::SYSTEM:PTERODACTYL:TOKEN"),
'Content-type' => 'application/json',
'Accept' => 'Application/vnd.pterodactyl.v1+json',
])->baseUrl(env('PTERODACTYL_URL') . '/api');
])->baseUrl(config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/api');
}
/**
@ -48,7 +48,11 @@ class Pterodactyl
*/
public static function getEggs(Nest $nest)
{
$response = self::client()->get("/application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . self::PER_PAGE);
try {
$response = self::client()->get("/application/nests/{$nest->id}/eggs?include=nest,variables&per_page=" . self::PER_PAGE);
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response->json()['data'];
}
@ -59,7 +63,11 @@ class Pterodactyl
*/
public static function getNodes()
{
$response = self::client()->get('/application/nodes?per_page=' . self::PER_PAGE);
try {
$response = self::client()->get('/application/nodes?per_page=' . self::PER_PAGE);
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response->json()['data'];
}
@ -70,7 +78,11 @@ class Pterodactyl
*/
public static function getNests()
{
$response = self::client()->get('/application/nests?per_page=' . self::PER_PAGE);
try {
$response = self::client()->get('/application/nests?per_page=' . self::PER_PAGE);
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response->json()['data'];
}
@ -81,8 +93,13 @@ class Pterodactyl
*/
public static function getLocations()
{
$response = self::client()->get('/application/locations?per_page=' . self::PER_PAGE);
try {
$response = self::client()->get('/application/locations?per_page=' . self::PER_PAGE);
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response->json()['data'];
}
@ -124,9 +141,14 @@ class Pterodactyl
*/
public static function getAllocations(Node $node)
{
$per_page = Configuration::getValueByKey('ALLOCATION_LIMIT', 200);
$response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
$per_page = config('SETTINGS::SERVER:ALLOCATION_LIMIT', 200);
try {
$response = self::client()->get("/application/nodes/{$node->id}/allocations?per_page={$per_page}");
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response->json();
}
@ -136,7 +158,7 @@ class Pterodactyl
*/
public static function url(string $route): string
{
return env('PTERODACTYL_URL') . $route;
return config("SETTINGS::SYSTEM:PTERODACTYL:URL") . $route;
}
/**
@ -171,20 +193,29 @@ class Pterodactyl
"default" => $allocationId
]
]);
}
public static function suspendServer(Server $server)
{
$response = self::client()->post("/application/servers/$server->pterodactyl_id/suspend");
try {
$response = self::client()->post("/application/servers/$server->pterodactyl_id/suspend");
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response;
}
public static function unSuspendServer(Server $server)
{
$response = self::client()->post("/application/servers/$server->pterodactyl_id/unsuspend");
try {
$response = self::client()->post("/application/servers/$server->pterodactyl_id/unsuspend");
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response;
}
@ -195,9 +226,29 @@ class Pterodactyl
*/
public function getUser(int $pterodactylId)
{
$response = self::client()->get("/application/users/{$pterodactylId}");
try {
$response = self::client()->get("/application/users/{$pterodactylId}");
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
if ($response->failed()) return $response->json();
return $response->json()['attributes'];
}
/**
* Get serverAttributes by pterodactyl id
* @param int $pterodactylId
* @return mixed
*/
public static function getServerAttributes(string $pterodactylId)
{
try {
$response = self::client()->get("/application/servers/{$pterodactylId}?include=egg,node,nest,location");
} catch (Exception $e) {
throw self::getException();
}
if ($response->failed()) throw self::getException();
return $response->json()['attributes'];
}
}

View file

@ -0,0 +1,50 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
class Invoices
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$request->validate([
'logo' => 'nullable|max:10000|mimes:jpg,png,jpeg',
]);
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::INVOICE:COMPANY_NAME" => "company-name",
"SETTINGS::INVOICE:COMPANY_ADDRESS" => "company-address",
"SETTINGS::INVOICE:COMPANY_PHONE" => "company-phone",
"SETTINGS::INVOICE:COMPANY_MAIL" => "company-mail",
"SETTINGS::INVOICE:COMPANY_VAT" => "company-vat",
"SETTINGS::INVOICE:COMPANY_WEBSITE" => "company-web",
"SETTINGS::INVOICE:PREFIX" => "invoice-prefix",
"SETTINGS::INVOICE:ENABLED" => "enable-invoices",
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
if ($request->hasFile('logo')) {
$request->file('logo')->storeAs('public', 'logo.png');
}
return redirect(route('admin.settings.index') . '#invoices')->with('success', __('Invoice settings updated!'));
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
class Language
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
'autotranslate' => 'string',
'canClientChangeLanguage' => 'string',
'defaultLanguage' => 'required|string',
'languages' => 'required|array',
'languages.*' => 'required|string',
'datatable-language' => 'required|string',
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#language')->with('error', __('Language settings have not been updated!'))->withErrors($validator);
}
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::LOCALE:DEFAULT" => "defaultLanguage",
"SETTINGS::LOCALE:DYNAMIC" => "autotranslate",
"SETTINGS::LOCALE:CLIENTS_CAN_CHANGE" => "canClientChangeLanguage",
"SETTINGS::LOCALE:AVAILABLE" => "languages",
"SETTINGS::LOCALE:DATATABLES" => "datatable-language"
];
foreach ($values as $key => $value) {
$param = $request->get($value);
if (is_array($param)) {
$param = implode(",", $param);
}
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
Session::remove("locale");
}
return redirect(route('admin.settings.index') . '#language')->with('success', __('Language settings updated!'));
}
}

View file

@ -0,0 +1,85 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class Misc
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
'favicon' => 'nullable|max:10000|mimes:ico',
'discord-bot-token' => 'nullable|string',
'discord-client-id' => 'nullable|string',
'discord-client-secret' => 'nullable|string',
'discord-guild-id' => 'nullable|string',
'discord-invite-url' => 'nullable|string',
'discord-role-id' => 'nullable|string',
'recaptcha-site-key' => 'nullable|string',
'recaptcha-secret-key' => 'nullable|string',
'enable-recaptcha' => 'nullable|string',
'mailservice' => 'nullable|string',
'mailhost' => 'nullable|string',
'mailport' => 'nullable|string',
'mailusername' => 'nullable|string',
'mailpassword' => 'nullable|string',
'mailencryption' => 'nullable|string',
'mailfromadress' => 'nullable|string',
'mailfromname' => 'nullable|string',
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#misc')->with('error', __('Misc settings have not been updated!'))->withErrors($validator)
->withInput();
}
if ($request->hasFile('icon')) {
$request->file('icon')->storeAs('public', 'icon.png');
}
if ($request->hasFile('favicon')) {
$request->file('favicon')->storeAs('public', 'favicon.ico');
}
$values = [
"SETTINGS::DISCORD:BOT_TOKEN" => "discord-bot-token",
"SETTINGS::DISCORD:CLIENT_ID" => "discord-client-id",
"SETTINGS::DISCORD:CLIENT_SECRET" => "discord-client-secret",
"SETTINGS::DISCORD:GUILD_ID" => "discord-guild-id",
"SETTINGS::DISCORD:INVITE_URL" => "discord-invite-url",
"SETTINGS::DISCORD:ROLE_ID" => "discord-role-id",
"SETTINGS::RECAPTCHA:SITE_KEY" => "recaptcha-site-key",
"SETTINGS::RECAPTCHA:SECRET_KEY" => "recaptcha-secret-key",
"SETTINGS::RECAPTCHA:ENABLED" => "enable-recaptcha",
"SETTINGS::MAIL:MAILER" => "mailservice",
"SETTINGS::MAIL:HOST" => "mailhost",
"SETTINGS::MAIL:PORT" => "mailport",
"SETTINGS::MAIL:USERNAME" => "mailusername",
"SETTINGS::MAIL:PASSWORD" => "mailpassword",
"SETTINGS::MAIL:ENCRYPTION" => "mailencryption",
"SETTINGS::MAIL:FROM_ADDRESS" => "mailfromadress",
"SETTINGS::MAIL:FROM_NAME" => "mailfromname",
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
return redirect(route('admin.settings.index') . '#misc')->with('success', __('Misc settings updated!'));
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class Payments
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
"paypal-client_id" => "nullable|string",
"paypal-client-secret" => "nullable|string",
"paypal-sandbox-secret" => "nullable|string",
"stripe-secret-key" => "nullable|string",
"stripe-endpoint-secret" => "nullable|string",
"stripe-test-secret-key" => "nullable|string",
"stripe-test-endpoint-secret" => "nullable|string",
"stripe-methods" => "nullable|string",
"sales-tax" => "nullable|numeric",
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#payment')->with('error', __('Payment settings have not been updated!'))->withErrors($validator)
->withInput();
}
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"SETTINGS::PAYMENTS:PAYPAL:SECRET" => "paypal-client-secret",
"SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID" => "paypal-client-id",
"SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET" => "paypal-sandbox-secret",
"SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID" => "paypal-sandbox-id",
"SETTINGS::PAYMENTS:STRIPE:SECRET" => "stripe-secret",
"SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET" => "stripe-endpoint-secret",
"SETTINGS::PAYMENTS:STRIPE:TEST_SECRET" => "stripe-test-secret",
"SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET" => "stripe-endpoint-test-secret",
"SETTINGS::PAYMENTS:STRIPE:METHODS" => "stripe-methods",
"SETTINGS::PAYMENTS:SALES_TAX" => "sales-tax"
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
return redirect(route('admin.settings.index') . '#payment')->with('success', __('Payment settings updated!'));
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace App\Classes\Settings;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class System
{
public function __construct()
{
return;
}
public function updateSettings(Request $request)
{
$validator = Validator::make($request->all(), [
"register-ip-check" => "string",
"server-create-charge-first-hour" => "string",
"credits-display-name" => "required|string",
"allocation-limit" => "required|min:0|integer",
"force-email-verification" => "string",
"force-discord-verification" => "string",
"initial-credits" => "required|min:0|integer",
"initial-server-limit" => "required|min:0|integer",
"credits-reward-amount-discord" => "required|min:0|integer",
"credits-reward-amount-email" => "required|min:0|integer",
"server-limit-discord" => "required|min:0|integer",
"server-limit-email" => "required|min:0|integer",
"pterodactyl-api-key" => "required|string",
"pterodactyl-url" => "required|string",
]);
if ($validator->fails()) {
return redirect(route('admin.settings.index') . '#system')->with('error', __('System settings have not been updated!'))->withErrors($validator)
->withInput();
}
$values = [
"SETTINGS::SYSTEM:REGISTER_IP_CHECK" => "register-ip-check",
"SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR" => "server-create-charge-first-hour",
"SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME" => "credits-display-name",
"SETTINGS::SERVER:ALLOCATION_LIMIT" => "allocation-limit",
"SETTINGS::USER:FORCE_DISCORD_VERIFICATION" => "force-discord-verification",
"SETTINGS::USER:FORCE_EMAIL_VERIFICATION" => "force-email-verification",
"SETTINGS::USER:INITIAL_CREDITS" => "initial-credits",
"SETTINGS::USER:INITIAL_SERVER_LIMIT" => "initial-server-limit",
"SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD" => "credits-reward-amount-discord",
"SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL" => "credits-reward-amount-email",
"SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD" => "server-limit-discord",
"SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL" => "server-limit-email",
"SETTINGS::MISC:PHPMYADMIN:URL" => "phpmyadmin-url",
"SETTINGS::SYSTEM:PTERODACTYL:URL" => "pterodactyl-url",
"SETTINGS::SYSTEM:PTERODACTYL:TOKEN" => "pterodactyl-api-key",
];
foreach ($values as $key => $value) {
$param = $request->get($value);
Settings::where('key', $key)->updateOrCreate(['key' => $key], ['value' => $param]);
Cache::forget("setting" . ':' . $key);
}
return redirect(route('admin.settings.index') . '#system')->with('success', __('System settings updated!'));
}
}

View file

@ -52,7 +52,7 @@ class ApplicationApiController extends Controller
'memo' => $request->input('memo')
]);
return redirect()->route('admin.api.index')->with('success', 'api key created!');
return redirect()->route('admin.api.index')->with('success', __('api key created!'));
}
/**
@ -94,7 +94,7 @@ class ApplicationApiController extends Controller
$applicationApi->update($request->all());
return redirect()->route('admin.api.index')->with('success', 'api key updated!');
return redirect()->route('admin.api.index')->with('success', __('api key updated!'));
}
/**
@ -106,7 +106,7 @@ class ApplicationApiController extends Controller
public function destroy(ApplicationApi $applicationApi)
{
$applicationApi->delete();
return redirect()->back()->with('success', 'api key has been removed!');
return redirect()->back()->with('success', __('api key has been removed!'));
}
/**
@ -121,11 +121,11 @@ class ApplicationApiController extends Controller
return datatables($query)
->addColumn('actions', function (ApplicationApi $apiKey) {
return '
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.api.edit', $apiKey->token) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<a data-content="'.__("Edit").'" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.api.edit', $apiKey->token) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.api.destroy', $apiKey->token) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="'.__("Delete").'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})

View file

@ -1,123 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Configuration;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class ConfigurationController extends Controller
{
/**
* Display a listing of the resource.
*
* @return Application|Factory|View|Response
*/
public function index()
{
return view('admin.configurations.index');
}
/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param Configuration $configuration
* @return Response
*/
public function show(Configuration $configuration)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param Configuration $configuration
* @return Response
*/
public function edit(Configuration $configuration)
{
//
}
/**
* Update the specified resource in storage.
*
* @param Request $request
* @param Configuration $configuration
* @return Response
*/
public function update(Request $request, Configuration $configuration)
{
//
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function updatevalue(Request $request)
{
$configuration = Configuration::findOrFail($request->input('key'));
$request->validate([
'key' => 'required|string|max:191',
'value' => 'required|string|max:191',
]);
$configuration->update($request->all());
return redirect()->route('admin.configurations.index')->with('success', 'configuration has been updated!');
}
/**
* Remove the specified resource from storage.
*
* @param Configuration $configuration
* @return Response
*/
public function destroy(Configuration $configuration)
{
//
}
public function datatable()
{
$query = Configuration::query();
return datatables($query)
->addColumn('actions', function (Configuration $configuration) {
return '<button data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" onclick="configuration.parse(\'' . $configuration->key . '\',\'' . $configuration->value . '\',\'' . $configuration->type . '\')" data-content="Edit" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></button> ';
})
->editColumn('created_at', function (Configuration $configuration) {
return $configuration->created_at ? $configuration->created_at->diffForHumans() : '';
})
->rawColumns(['actions'])
->make();
}
}

View file

@ -2,7 +2,8 @@
namespace App\Http\Controllers\Admin;
use App\Models\PaypalProduct;
use App\Models\CreditProduct;
use App\Models\Settings;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
@ -12,7 +13,7 @@ use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Illuminate\Validation\Rule;
class PaypalProductController extends Controller
class CreditProductController extends Controller
{
/**
* Display a listing of the resource.
@ -21,11 +22,16 @@ class PaypalProductController extends Controller
*/
public function index(Request $request)
{
$isPaypalSetup = false;
if (env('PAYPAL_SECRET') && env('PAYPAL_CLIENT_ID')) $isPaypalSetup = true;
$isPaymentSetup = false;
return view('admin.store.index' , [
'isPaypalSetup' => $isPaypalSetup
if (
env('APP_ENV') == 'local' ||
config("SETTINGS::PAYMENTS:PAYPAL:SECRET") && config("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID") ||
config("SETTINGS::PAYMENTS:STRIPE:SECRET") && config("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET") && config("SETTINGS::PAYMENTS:STRIPE:METHODS")
) $isPaymentSetup = true;
return view('admin.store.index', [
'isPaymentSetup' => $isPaymentSetup
]);
}
@ -60,18 +66,18 @@ class PaypalProductController extends Controller
]);
$disabled = !is_null($request->input('disabled'));
PaypalProduct::create(array_merge($request->all(), ['disabled' => $disabled]));
CreditProduct::create(array_merge($request->all(), ['disabled' => $disabled]));
return redirect()->route('admin.store.index')->with('success', 'Store item has been created!');
return redirect()->route('admin.store.index')->with('success', __('Store item has been created!'));
}
/**
* Display the specified resource.
*
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return Response
*/
public function show(PaypalProduct $paypalProduct)
public function show(CreditProduct $creditProduct)
{
//
}
@ -79,14 +85,14 @@ class PaypalProductController extends Controller
/**
* Show the form for editing the specified resource.
*
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return Application|Factory|View|Response
*/
public function edit(PaypalProduct $paypalProduct)
public function edit(CreditProduct $creditProduct)
{
return view('admin.store.edit', [
'currencyCodes' => config('currency_codes'),
'paypalProduct' => $paypalProduct
'creditProduct' => $creditProduct
]);
}
@ -94,10 +100,10 @@ class PaypalProductController extends Controller
* Update the specified resource in storage.
*
* @param Request $request
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return RedirectResponse
*/
public function update(Request $request, PaypalProduct $paypalProduct)
public function update(Request $request, CreditProduct $creditProduct)
{
$request->validate([
"disabled" => "nullable",
@ -110,70 +116,70 @@ class PaypalProductController extends Controller
]);
$disabled = !is_null($request->input('disabled'));
$paypalProduct->update(array_merge($request->all(), ['disabled' => $disabled]));
$creditProduct->update(array_merge($request->all(), ['disabled' => $disabled]));
return redirect()->route('admin.store.index')->with('success', 'Store item has been updated!');
return redirect()->route('admin.store.index')->with('success', __('Store item has been updated!'));
}
/**
* @param Request $request
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return RedirectResponse
*/
public function disable(Request $request, PaypalProduct $paypalProduct)
public function disable(Request $request, CreditProduct $creditProduct)
{
$paypalProduct->update(['disabled' => !$paypalProduct->disabled]);
$creditProduct->update(['disabled' => !$creditProduct->disabled]);
return redirect()->route('admin.store.index')->with('success', 'Product has been updated!');
return redirect()->route('admin.store.index')->with('success', __('Product has been updated!'));
}
/**
* Remove the specified resource from storage.
*
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return RedirectResponse
*/
public function destroy(PaypalProduct $paypalProduct)
public function destroy(CreditProduct $creditProduct)
{
$paypalProduct->delete();
return redirect()->back()->with('success', 'Store item has been removed!');
$creditProduct->delete();
return redirect()->back()->with('success', __('Store item has been removed!'));
}
public function dataTable()
{
$query = PaypalProduct::query();
$query = CreditProduct::query();
return datatables($query)
->addColumn('actions', function (PaypalProduct $paypalProduct) {
->addColumn('actions', function (CreditProduct $creditProduct) {
return '
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.store.edit', $paypalProduct->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<a data-content="' . __("Edit") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.store.edit', $creditProduct->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.store.destroy', $paypalProduct->id) . '">
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.store.destroy', $creditProduct->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="' . __("Delete") . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})
->addColumn('disabled', function (PaypalProduct $paypalProduct) {
$checked = $paypalProduct->disabled == false ? "checked" : "";
->addColumn('disabled', function (CreditProduct $creditProduct) {
$checked = $creditProduct->disabled == false ? "checked" : "";
return '
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.store.disable', $paypalProduct->id) . '">
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.store.disable', $creditProduct->id) . '">
' . csrf_field() . '
' . method_field("PATCH") . '
<div class="custom-control custom-switch">
<input ' . $checked . ' name="disabled" onchange="this.form.submit()" type="checkbox" class="custom-control-input" id="switch' . $paypalProduct->id . '">
<label class="custom-control-label" for="switch' . $paypalProduct->id . '"></label>
<input ' . $checked . ' name="disabled" onchange="this.form.submit()" type="checkbox" class="custom-control-input" id="switch' . $creditProduct->id . '">
<label class="custom-control-label" for="switch' . $creditProduct->id . '"></label>
</div>
</form>
';
})
->editColumn('created_at', function (PaypalProduct $paypalProduct) {
return $paypalProduct->created_at ? $paypalProduct->created_at->diffForHumans() : '';
->editColumn('created_at', function (CreditProduct $creditProduct) {
return $creditProduct->created_at ? $creditProduct->created_at->diffForHumans() : '';
})
->editColumn('price', function (PaypalProduct $paypalProduct) {
return $paypalProduct->formatToCurrency($paypalProduct->price);
->editColumn('price', function (CreditProduct $creditProduct) {
return $creditProduct->formatToCurrency($creditProduct->price);
})
->rawColumns(['actions', 'disabled'])
->make();

View file

@ -0,0 +1,70 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Invoice;
use Illuminate\Http\Request;
use Throwable;
use ZipArchive;
class InvoiceController extends Controller
{
public function downloadAllInvoices()
{
$zip = new ZipArchive;
$zip_safe_path = storage_path('invoices.zip');
$res = $zip->open($zip_safe_path, ZipArchive::CREATE | ZipArchive::OVERWRITE);
$result = $dthis::rglob(storage_path('app/invoice/*'));
if ($res === TRUE) {
$zip->addFromString("1. Info.txt", __("Created at") . " " . now()->format("d.m.Y"));
foreach ($result as $file) {
if (file_exists($file) && is_file($file)) {
$zip->addFile($file, basename($file));
}
}
$zip->close();
}
return response()->download($zip_safe_path);
}
/**
* @param $pattern
* @param $flags
* @return array|false
*/
public function rglob($pattern, $flags = 0)
{
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
$files = array_merge($files, $this::rglob($dir . '/' . basename($pattern), $flags));
}
return $files;
}
/**
* @param $paymentID
* @param $date
*/
public function downloadSingleInvoice(Request $request)
{
$id = $request->id;
try {
$query = Invoice::where('payment_id', '=', $id)->firstOrFail();
} catch (Throwable $e) {
return redirect()->back()->with("error", __("Error!"));
}
$invoice_path = storage_path('app/invoice/' . $query->invoice_user . '/' . $query->created_at->format("Y") . '/' . $query->invoice_name . '.pdf');
if (!file_exists($invoice_path)) {
return redirect()->back()->with("error", __("Error!"));
}
return response()->download($invoice_path);
}
}

View file

@ -4,11 +4,12 @@ namespace App\Http\Controllers\Admin;
use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\InvoiceSettings;
use App\Models\Payment;
use App\Models\PaypalProduct;
use App\Models\Product;
use App\Models\CreditProduct;
use App\Models\Settings;
use App\Models\User;
use App\Notifications\InvoiceNotification;
use App\Notifications\ConfirmPaymentNotification;
use Exception;
use Illuminate\Contracts\Foundation\Application;
@ -18,12 +19,20 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use LaravelDaily\Invoices\Classes\Buyer;
use LaravelDaily\Invoices\Classes\InvoiceItem;
use LaravelDaily\Invoices\Classes\Party;
use LaravelDaily\Invoices\Invoice;
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\ProductionEnvironment;
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
use PayPalHttp\HttpException;
use Stripe\Stripe;
use Symfony\Component\Intl\Currencies;
class PaymentController extends Controller
{
@ -40,25 +49,25 @@ class PaymentController extends Controller
/**
* @param Request $request
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return Application|Factory|View
*/
public function checkOut(Request $request, PaypalProduct $paypalProduct)
public function checkOut(Request $request, CreditProduct $creditProduct)
{
return view('store.checkout')->with([
'product' => $paypalProduct,
'taxvalue' => $paypalProduct->getTaxValue(),
'taxpercent' => $paypalProduct->getTaxPercent(),
'total' => $paypalProduct->getTotalPrice()
'product' => $creditProduct,
'taxvalue' => $creditProduct->getTaxValue(),
'taxpercent' => $creditProduct->getTaxPercent(),
'total' => $creditProduct->getTotalPrice()
]);
}
/**
* @param Request $request
* @param PaypalProduct $paypalProduct
* @param CreditProduct $creditProduct
* @return RedirectResponse
*/
public function pay(Request $request, PaypalProduct $paypalProduct)
public function PaypalPay(Request $request, CreditProduct $creditProduct)
{
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
@ -67,33 +76,33 @@ class PaymentController extends Controller
"purchase_units" => [
[
"reference_id" => uniqid(),
"description" => $paypalProduct->description,
"description" => $creditProduct->description,
"amount" => [
"value" => $paypalProduct->getTotalPrice(),
'currency_code' => strtoupper($paypalProduct->currency_code),
'breakdown' =>[
"value" => $creditProduct->getTotalPrice(),
'currency_code' => strtoupper($creditProduct->currency_code),
'breakdown' => [
'item_total' =>
[
'currency_code' => strtoupper($paypalProduct->currency_code),
'value' => $paypalProduct->price,
],
[
'currency_code' => strtoupper($creditProduct->currency_code),
'value' => $creditProduct->price,
],
'tax_total' =>
[
'currency_code' => strtoupper($paypalProduct->currency_code),
'value' => $paypalProduct->getTaxValue(),
]
[
'currency_code' => strtoupper($creditProduct->currency_code),
'value' => $creditProduct->getTaxValue(),
]
]
]
]
],
"application_context" => [
"cancel_url" => route('payment.cancel'),
"return_url" => route('payment.success', ['product' => $paypalProduct->id]),
"cancel_url" => route('payment.Cancel'),
"return_url" => route('payment.PaypalSuccess', ['product' => $creditProduct->id]),
'brand_name' => config('app.name', 'Laravel'),
'shipping_preference' => 'NO_SHIPPING'
]
];
@ -107,7 +116,6 @@ class PaymentController extends Controller
echo $ex->statusCode;
dd(json_decode($ex->getMessage()));
}
}
/**
@ -116,8 +124,8 @@ class PaymentController extends Controller
protected function getPayPalClient()
{
$environment = env('APP_ENV') == 'local'
? new SandboxEnvironment($this->getClientId(), $this->getClientSecret())
: new ProductionEnvironment($this->getClientId(), $this->getClientSecret());
? new SandboxEnvironment($this->getPaypalClientId(), $this->getPaypalClientSecret())
: new ProductionEnvironment($this->getPaypalClientId(), $this->getPaypalClientSecret());
return new PayPalHttpClient($environment);
}
@ -125,26 +133,27 @@ class PaymentController extends Controller
/**
* @return string
*/
protected function getClientId()
protected function getPaypalClientId()
{
return env('APP_ENV') == 'local' ? env('PAYPAL_SANDBOX_CLIENT_ID') : env('PAYPAL_CLIENT_ID');
return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID") : config("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID");
}
/**
* @return string
*/
protected function getClientSecret()
protected function getPaypalClientSecret()
{
return env('APP_ENV') == 'local' ? env('PAYPAL_SANDBOX_SECRET') : env('PAYPAL_SECRET');
return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET") : config("SETTINGS::PAYMENTS:PAYPAL:SECRET");
}
/**
* @param Request $laravelRequest
*/
public function success(Request $laravelRequest)
public function PaypalSuccess(Request $laravelRequest)
{
/** @var PaypalProduct $paypalProduct */
$paypalProduct = PaypalProduct::findOrFail($laravelRequest->input('product'));
/** @var CreditProduct $creditProduct */
$creditProduct = CreditProduct::findOrFail($laravelRequest->input('product'));
/** @var User $user */
$user = Auth::user();
@ -156,15 +165,15 @@ class PaymentController extends Controller
if ($response->statusCode == 201 || $response->statusCode == 200) {
//update credits
$user->increment('credits', $paypalProduct->quantity);
$user->increment('credits', $creditProduct->quantity);
//update server limit
if (Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => Configuration::getValueByKey('SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
}
}
//update role
if ($user->role == 'member') {
$user->update(['role' => 'client']);
@ -174,34 +183,38 @@ class PaymentController extends Controller
$payment = Payment::create([
'user_id' => $user->id,
'payment_id' => $response->result->id,
'payer_id' => $laravelRequest->input('PayerID'),
'payment_method' => 'paypal',
'type' => 'Credits',
'status' => $response->result->status,
'amount' => $paypalProduct->quantity,
'price' => $paypalProduct->price,
'tax_value' => $paypalProduct->getTaxValue(),
'tax_percent' => $paypalProduct->getTaxPercent(),
'total_price' => $paypalProduct->getTotalPrice(),
'currency_code' => $paypalProduct->currency_code,
'payer' => json_encode($response->result->payer),
'status' => 'paid',
'amount' => $creditProduct->quantity,
'price' => $creditProduct->price,
'tax_value' => $creditProduct->getTaxValue(),
'tax_percent' => $creditProduct->getTaxPercent(),
'total_price' => $creditProduct->getTotalPrice(),
'currency_code' => $creditProduct->currency_code,
'credit_product_id' => $creditProduct->id,
]);
//payment notification
$user->notify(new ConfirmPaymentNotification($payment));
event(new UserUpdateCreditsEvent($user));
//only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid', $creditProduct->currency_code);
}
//redirect back to home
return redirect()->route('home')->with('success', 'Your credit balance has been increased!');
return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
}
// If call returns body in response, you can get the deserialized version from the result attribute of the response
if (env('APP_ENV') == 'local') {
dd($response);
} else {
abort(500);
}
} catch (HttpException $ex) {
if (env('APP_ENV') == 'local') {
echo $ex->statusCode;
@ -209,20 +222,361 @@ class PaymentController extends Controller
} else {
abort(422);
}
}
}
/**
* @param Request $request
*/
public function cancel(Request $request)
public function Cancel(Request $request)
{
return redirect()->route('store.index')->with('success', 'Payment was Canceled');
}
/**
* @param Request $request
* @param CreditProduct $creditProduct
* @return RedirectResponse
*/
public function StripePay(Request $request, CreditProduct $creditProduct)
{
$stripeClient = $this->getStripeClient();
$request = $stripeClient->checkout->sessions->create([
'line_items' => [
[
'price_data' => [
'currency' => $creditProduct->currency_code,
'product_data' => [
'name' => $creditProduct->display,
'description' => $creditProduct->description,
],
'unit_amount_decimal' => round($creditProduct->price * 100, 2),
],
'quantity' => 1,
],
[
'price_data' => [
'currency' => $creditProduct->currency_code,
'product_data' => [
'name' => 'Product Tax',
'description' => $creditProduct->getTaxPercent() . "%",
],
'unit_amount_decimal' => round($creditProduct->getTaxValue(), 2) * 100,
],
'quantity' => 1,
]
],
'mode' => 'payment',
"payment_method_types" => str_getcsv(config("SETTINGS::PAYMENTS:STRIPE:METHODS")),
'success_url' => route('payment.StripeSuccess', ['product' => $creditProduct->id]) . '&session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => route('payment.Cancel'),
]);
return redirect($request->url, 303);
}
/**
* @param Request $request
*/
public function StripeSuccess(Request $request)
{
/** @var CreditProduct $creditProduct */
$creditProduct = CreditProduct::findOrFail($request->input('product'));
/** @var User $user */
$user = Auth::user();
$stripeClient = $this->getStripeClient();
try {
//get stripe data
$paymentSession = $stripeClient->checkout->sessions->retrieve($request->input('session_id'));
$paymentIntent = $stripeClient->paymentIntents->retrieve($paymentSession->payment_intent);
//get DB entry of this payment ID if existing
$paymentDbEntry = Payment::where('payment_id', $paymentSession->payment_intent)->count();
// check if payment is 100% completed and payment does not exist in db already
if ($paymentSession->status == "complete" && $paymentIntent->status == "succeeded" && $paymentDbEntry == 0) {
//update credits
$user->increment('credits', $creditProduct->quantity);
//update server limit
if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
}
}
//update role
if ($user->role == 'member') {
$user->update(['role' => 'client']);
}
//store paid payment
$payment = Payment::create([
'user_id' => $user->id,
'payment_id' => $paymentSession->payment_intent,
'payment_method' => 'stripe',
'type' => 'Credits',
'status' => 'paid',
'amount' => $creditProduct->quantity,
'price' => $creditProduct->price,
'tax_value' => $creditProduct->getTaxValue(),
'total_price' => $creditProduct->getTotalPrice(),
'tax_percent' => $creditProduct->getTaxPercent(),
'currency_code' => $creditProduct->currency_code,
'credit_product_id' => $creditProduct->id,
]);
//payment notification
$user->notify(new ConfirmPaymentNotification($payment));
event(new UserUpdateCreditsEvent($user));
//only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid', $creditProduct->currency_code);
}
//redirect back to home
return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
} else {
if ($paymentIntent->status == "processing") {
//store processing payment
$payment = Payment::create([
'user_id' => $user->id,
'payment_id' => $paymentSession->payment_intent,
'payment_method' => 'stripe',
'type' => 'Credits',
'status' => 'processing',
'amount' => $creditProduct->quantity,
'price' => $creditProduct->price,
'tax_value' => $creditProduct->getTaxValue(),
'total_price' => $creditProduct->getTotalPrice(),
'tax_percent' => $creditProduct->getTaxPercent(),
'currency_code' => $creditProduct->currency_code,
'credit_product_id' => $creditProduct->id,
]);
//only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid', $creditProduct->currency_code);
}
//redirect back to home
return redirect()->route('home')->with('success', __('Your payment is being processed!'));
}
if ($paymentDbEntry == 0 && $paymentIntent->status != "processing") {
$stripeClient->paymentIntents->cancel($paymentIntent->id);
//redirect back to home
return redirect()->route('home')->with('success', __('Your payment has been canceled!'));
} else {
abort(402);
}
}
} catch (HttpException $ex) {
if (env('APP_ENV') == 'local') {
echo $ex->statusCode;
dd($ex->getMessage());
} else {
abort(422);
}
}
}
/**
* @param Request $request
*/
protected function handleStripePaymentSuccessHook($paymentIntent)
{
try {
// Get payment db entry
$payment = Payment::where('payment_id', $paymentIntent->id)->first();
$user = User::where('id', $payment->user_id)->first();
if ($paymentIntent->status == 'succeeded' && $payment->status == 'processing') {
// Increment User Credits
$user->increment('credits', $payment->amount);
//update server limit
if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
$user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
}
}
//update role
if ($user->role == 'member') {
$user->update(['role' => 'client']);
}
//update payment db entry status
$payment->update(['status' => 'paid']);
//payment notification
$user->notify(new ConfirmPaymentNotification($payment));
event(new UserUpdateCreditsEvent($user));
//only create invoice if SETTINGS::INVOICE:ENABLED is true
if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
$this->createInvoice($user, $payment, 'paid', strtoupper($paymentIntent->currency));
}
}
} catch (HttpException $ex) {
abort(422);
}
}
/**
* @param Request $request
*/
public function StripeWebhooks(Request $request)
{
\Stripe\Stripe::setApiKey($this->getStripeSecret());
try {
$payload = @file_get_contents('php://input');
$sig_header = $request->header('Stripe-Signature');
$event = null;
$event = \Stripe\Webhook::constructEvent(
$payload,
$sig_header,
$this->getStripeEndpointSecret()
);
} catch (\UnexpectedValueException $e) {
// Invalid payload
abort(400);
} catch (\Stripe\Exception\SignatureVerificationException $e) {
// Invalid signature
abort(400);
}
// Handle the event
switch ($event->type) {
case 'payment_intent.succeeded':
$paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
$this->handleStripePaymentSuccessHook($paymentIntent);
break;
default:
echo 'Received unknown event type ' . $event->type;
}
}
/**
* @return \Stripe\StripeClient
*/
protected function getStripeClient()
{
return new \Stripe\StripeClient($this->getStripeSecret());
}
/**
* @return string
*/
protected function getStripeSecret()
{
return env('APP_ENV') == 'local'
? config("SETTINGS::PAYMENTS:STRIPE:TEST_SECRET")
: config("SETTINGS::PAYMENTS:STRIPE:SECRET");
}
/**
* @return string
*/
protected function getStripeEndpointSecret()
{
return env('APP_ENV') == 'local'
? config("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET")
: config("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET");
}
protected function createInvoice($user, $payment, $paymentStatus, $currencyCode)
{
$creditProduct = CreditProduct::where('id', $payment->credit_product_id)->first();
//create invoice
$lastInvoiceID = \App\Models\Invoice::where("invoice_name", "like", "%" . now()->format('mY') . "%")->count("id");
$newInvoiceID = $lastInvoiceID + 1;
$logoPath = storage_path('app/public/logo.png');
$seller = new Party([
'name' => config("SETTINGS::INVOICE:COMPANY_NAME"),
'phone' => config("SETTINGS::INVOICE:COMPANY_PHONE"),
'address' => config("SETTINGS::INVOICE:COMPANY_ADDRESS"),
'vat' => config("SETTINGS::INVOICE:COMPANY_VAT"),
'custom_fields' => [
'E-Mail' => config("SETTINGS::INVOICE:COMPANY_MAIL"),
"Web" => config("SETTINGS::INVOICE:COMPANY_WEBSITE")
],
]);
$customer = new Buyer([
'name' => $user->name,
'custom_fields' => [
'E-Mail' => $user->email,
'Client ID' => $user->id,
],
]);
$item = (new InvoiceItem())
->title($creditProduct->description)
->pricePerUnit($creditProduct->price);
$notes = [
__("Payment method") . ": " . $payment->payment_method,
];
$notes = implode("<br>", $notes);
$invoice = Invoice::make()
->template('controlpanel')
->name(__("Invoice"))
->buyer($customer)
->seller($seller)
->discountByPercent(0)
->taxRate(floatval($creditProduct->getTaxPercent()))
->shipping(0)
->addItem($item)
->status(__($paymentStatus))
->series(now()->format('mY'))
->delimiter("-")
->sequence($newInvoiceID)
->serialNumberFormat(config("SETTINGS::INVOICE:PREFIX") . '{DELIMITER}{SERIES}{SEQUENCE}')
->currencyCode($currencyCode)
->currencySymbol(Currencies::getSymbol($currencyCode))
->notes($notes);
if (file_exists($logoPath)) {
$invoice->logo($logoPath);
}
//Save the invoice in "storage\app\invoice\USER_ID\YEAR"
$invoice->filename = $invoice->getSerialNumber() . '.pdf';
$invoice->render();
Storage::disk("local")->put("invoice/" . $user->id . "/" . now()->format('Y') . "/" . $invoice->filename, $invoice->output);
\App\Models\Invoice::create([
'invoice_user' => $user->id,
'invoice_name' => $invoice->getSerialNumber(),
'payment_id' => $payment->payment_id,
]);
//Send Invoice per Mail
$user->notify(new InvoiceNotification($invoice, $user, $payment));
}
/**
* @return JsonResponse|mixed
@ -242,12 +596,21 @@ class PaymentController extends Controller
->editColumn('tax_value', function (Payment $payment) {
return $payment->formatToCurrency($payment->tax_value);
})
->editColumn('tax_percent', function (Payment $payment) {
return $payment->tax_percent . ' %';
})
->editColumn('total_price', function (Payment $payment) {
return $payment->formatToCurrency($payment->total_price);
})
->editColumn('created_at', function (Payment $payment) {
return $payment->created_at ? $payment->created_at->diffForHumans() : '';
})
->make();
->addColumn('actions', function (Payment $payment) {
return ' <a data-content="' . __("Download") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.invoices.downloadSingleInvoice', "id=" . $payment->payment_id) . '" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-file-download"></i></a>
';
})
->rawColumns(['actions'])
->make(true);
}
}

View file

@ -3,12 +3,10 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Egg;
use App\Models\Location;
use App\Models\Nest;
use App\Models\Node;
use App\Models\Configuration;
use App\Models\Product;
use App\Models\Settings;
use Exception;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
@ -16,7 +14,6 @@ use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class ProductController extends Controller
{
@ -37,14 +34,15 @@ class ProductController extends Controller
*/
public function create()
{
return view('admin.products.create' , [
return view('admin.products.create', [
'locations' => Location::with('nodes')->get(),
'nests' => Nest::with('eggs')->get(),
]);
}
public function clone(Request $request , Product $product){
return view('admin.products.create' , [
public function clone(Request $request, Product $product)
{
return view('admin.products.create', [
'product' => $product,
'locations' => Location::with('nodes')->get(),
'nests' => Nest::with('eggs')->get(),
@ -84,7 +82,7 @@ class ProductController extends Controller
$product->eggs()->attach($request->input('eggs'));
$product->nodes()->attach($request->input('nodes'));
return redirect()->route('admin.products.index')->with('success', 'Product has been created!');
return redirect()->route('admin.products.index')->with('success', __('Product has been created!'));
}
/**
@ -97,7 +95,7 @@ class ProductController extends Controller
{
return view('admin.products.show', [
'product' => $product,
'minimum_credits' => Configuration::getValueByKey("MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER"),
'minimum_credits' => config("SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER"),
]);
}
@ -152,7 +150,7 @@ class ProductController extends Controller
$product->eggs()->attach($request->input('eggs'));
$product->nodes()->attach($request->input('nodes'));
return redirect()->route('admin.products.index')->with('success', 'Product has been updated!');
return redirect()->route('admin.products.index')->with('success', __('Product has been updated!'));
}
/**
@ -181,7 +179,7 @@ class ProductController extends Controller
}
$product->delete();
return redirect()->back()->with('success', 'Product has been removed!');
return redirect()->back()->with('success', __('Product has been removed!'));
}
@ -196,14 +194,14 @@ class ProductController extends Controller
return datatables($query)
->addColumn('actions', function (Product $product) {
return '
<a data-content="Show" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.products.show', $product->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
<a data-content="Clone" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.products.clone', $product->id) . '" class="btn btn-sm text-white btn-primary mr-1"><i class="fas fa-clone"></i></a>
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.products.edit', $product->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<a data-content="' . __("Show") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.products.show', $product->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
<a data-content="' . __("Clone") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.products.clone', $product->id) . '" class="btn btn-sm text-white btn-primary mr-1"><i class="fas fa-clone"></i></a>
<a data-content="' . __("Edit") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.products.edit', $product->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.products.destroy', $product->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="' . __("Delete") . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})

View file

@ -6,6 +6,7 @@ use App\Classes\Pterodactyl;
use App\Classes\PterodactylWrapper;
use App\Http\Controllers\Controller;
use App\Models\Server;
use App\Models\Settings;
use Exception;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
@ -92,9 +93,9 @@ class ServerController extends Controller
{
try {
$server->delete();
return redirect()->route('admin.servers.index')->with('success', 'Server removed');
return redirect()->route('admin.servers.index')->with('success', __('Server removed'));
} catch (Exception $e) {
return redirect()->route('admin.servers.index')->with('error', 'An exception has occurred while trying to remove a resource "' . $e->getMessage() . '"');
return redirect()->route('admin.servers.index')->with('error', __('An exception has occurred while trying to remove a resource "') . $e->getMessage() . '"');
}
}
@ -102,14 +103,15 @@ class ServerController extends Controller
* @param Server $server
* @return RedirectResponse
*/
public function toggleSuspended(Server $server){
public function toggleSuspended(Server $server)
{
try {
$server->isSuspended() ? $server->unSuspend() : $server->suspend();
} catch (Exception $exception) {
return redirect()->back()->with('error', $exception->getMessage());
}
return redirect()->back()->with('success', 'Server has been updated!');
return redirect()->back()->with('success', __('Server has been updated!'));
}
/**
@ -134,18 +136,18 @@ class ServerController extends Controller
->addColumn('actions', function (Server $server) {
$suspendColor = $server->isSuspended() ? "btn-success" : "btn-warning";
$suspendIcon = $server->isSuspended() ? "fa-play-circle" : "fa-pause-circle";
$suspendText = $server->isSuspended() ? "Unsuspend" : "Suspend";
$suspendText = $server->isSuspended() ? __("Unsuspend") : __("Suspend");
return '
<form class="d-inline" method="post" action="' . route('admin.servers.togglesuspend', $server->id) . '">
' . csrf_field() . '
<button data-content="'.$suspendText.'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm '.$suspendColor.' text-white mr-1"><i class="far '.$suspendIcon.'"></i></button>
<button data-content="' . $suspendText . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm ' . $suspendColor . ' text-white mr-1"><i class="far ' . $suspendIcon . '"></i></button>
</form>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.servers.destroy', $server->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="' . __("Delete") . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
@ -161,7 +163,7 @@ class ServerController extends Controller
return $server->suspended ? $server->suspended->diffForHumans() : '';
})
->editColumn('name', function (Server $server) {
return '<a class="text-info" target="_blank" href="' . env('PTERODACTYL_URL', 'http://localhost') . '/admin/servers/view/' . $server->pterodactyl_id . '">' . $server->name . '</a>';
return '<a class="text-info" target="_blank" href="' . config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/admin/servers/view/' . $server->pterodactyl_id . '">' . $server->name . '</a>';
})
->rawColumns(['user', 'actions', 'status', 'name'])
->make();

View file

@ -3,6 +3,7 @@
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Settings;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
@ -18,25 +19,68 @@ class SettingsController extends Controller
*/
public function index()
{
return view('admin.settings.index');
//Get all tabs as laravel view paths
$tabs = [];
foreach (glob(resource_path('views/admin/settings/tabs/*.blade.php')) as $filename) {
$tabs[] = 'admin.settings.tabs.' . basename($filename, '.blade.php');
}
//Generate a html list item for each tab based on tabs file basename, set first tab as active
$tabListItems = [];
foreach ($tabs as $tab) {
$tabName = str_replace('admin.settings.tabs.', '', $tab);
$tabListItems[] = '<li class="nav-item">
<a class="nav-link ' . (empty($tabListItems) ? 'active' : '') . '" data-toggle="pill" href="#' . $tabName . '">
' . __(ucfirst($tabName)) . '
</a></li>';
}
return view('admin.settings.index', [
'tabs' => $tabs,
'tabListItems' => $tabListItems,
]);
}
public function updateIcons(Request $request)
public function updatevalue(Request $request)
{
$setting = Settings::findOrFail($request->input('key'));
$request->validate([
'icon' => 'nullable|max:10000|mimes:jpg,png,jpeg',
'favicon' => 'nullable|max:10000|mimes:ico',
'key' => 'required|string|max:191',
'value' => 'required|string|max:191',
]);
if ($request->hasFile('icon')) {
$request->file('icon')->storeAs('public', 'icon.png');
}
$setting->update($request->all());
if ($request->hasFile('favicon')) {
$request->file('favicon')->storeAs('public', 'favicon.ico');
}
return redirect()->route('admin.settings.index')->with('success', 'Icons updated!');
return redirect()->route('admin.settings.index')->with('success', __('configuration has been updated!'));
}
/**
* Remove the specified resource from storage.
*
* @param Settings $setting
* @return Response
*/
public function destroy(Settings $setting)
{
//
}
public function datatable()
{
$query = Settings::where('key', 'like', '%SYSTEM%')
->orWhere('key', 'like', '%USER%')
->orWhere('key', 'like', '%SERVER%');
return datatables($query)
->addColumn('actions', function (Settings $setting) {
return '<button data-content="' . __("Edit") . '" data-toggle="popover" data-trigger="hover" data-placement="top" onclick="configuration.parse(\'' . $setting->key . '\',\'' . $setting->value . '\',\'' . $setting->type . '\')" data-content="Edit" data-trigger="hover" data-toggle="tooltip" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></button> ';
})
->editColumn('created_at', function (Settings $setting) {
return $setting->created_at ? $setting->created_at->diffForHumans() : '';
})
->rawColumns(['actions'])
->make();
}
}

View file

@ -50,7 +50,7 @@ class UsefulLinkController extends Controller
]);
UsefulLink::create($request->all());
return redirect()->route('admin.usefullinks.index')->with('success', 'link has been created!');
return redirect()->route('admin.usefullinks.index')->with('success', __('link has been created!'));
}
/**
@ -94,7 +94,7 @@ class UsefulLinkController extends Controller
]);
$usefullink->update($request->all());
return redirect()->route('admin.usefullinks.index')->with('success', 'link has been updated!');
return redirect()->route('admin.usefullinks.index')->with('success', __('link has been updated!'));
}
/**
@ -106,7 +106,7 @@ class UsefulLinkController extends Controller
public function destroy(UsefulLink $usefullink)
{
$usefullink->delete();
return redirect()->back()->with('success', 'product has been removed!');
return redirect()->back()->with('success', __('product has been removed!'));
}
public function dataTable()
@ -116,12 +116,12 @@ class UsefulLinkController extends Controller
return datatables($query)
->addColumn('actions', function (UsefulLink $link) {
return '
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.usefullinks.edit', $link->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<a data-content="'.__("Edit").'" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.usefullinks.edit', $link->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.usefullinks.destroy', $link->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="'.__("Delete").'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})

View file

@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
use App\Classes\Pterodactyl;
use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller;
use App\Models\Settings;
use App\Models\User;
use App\Notifications\DynamicNotification;
use Spatie\QueryBuilder\QueryBuilder;
@ -115,7 +116,7 @@ class UserController extends Controller
if (isset($this->pterodactyl->getUser($request->input('pterodactyl_id'))['errors'])) {
throw ValidationException::withMessages([
'pterodactyl_id' => ["User does not exists on pterodactyl's panel"]
'pterodactyl_id' => [__("User does not exists on pterodactyl's panel")]
]);
}
@ -145,7 +146,7 @@ class UserController extends Controller
public function destroy(User $user)
{
$user->delete();
return redirect()->back()->with('success', 'user has been removed!');
return redirect()->back()->with('success', __('user has been removed!'));
}
/**
@ -218,21 +219,22 @@ class UserController extends Controller
$all = $data["all"] ?? false;
$users = $all ? User::all() : User::whereIn("id", $data["users"])->get();
Notification::send($users, new DynamicNotification($data["via"], $database, $mail));
return redirect()->route('admin.users.notifications')->with('success', 'Notification sent!');
return redirect()->route('admin.users.notifications')->with('success', __('Notification sent!'));
}
/**
* @param User $user
* @return RedirectResponse
*/
public function toggleSuspended(User $user){
public function toggleSuspended(User $user)
{
try {
!$user->isSuspended() ? $user->suspend() : $user->unSuspend();
} catch (Exception $exception) {
return redirect()->back()->with('error', $exception->getMessage());
}
return redirect()->back()->with('success', 'User has been updated!');
return redirect()->back()->with('success', __('User has been updated!'));
}
/**
@ -265,19 +267,19 @@ class UserController extends Controller
->addColumn('actions', function (User $user) {
$suspendColor = $user->isSuspended() ? "btn-success" : "btn-warning";
$suspendIcon = $user->isSuspended() ? "fa-play-circle" : "fa-pause-circle";
$suspendText = $user->isSuspended() ? "Unsuspend" : "Suspend";
$suspendText = $user->isSuspended() ? __("Unsuspend") : __("Suspend");
return '
<a data-content="Login as user" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
<a data-content="Show" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<a data-content="' . __("Login as User") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.loginas', $user->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-sign-in-alt"></i></a>
<a data-content="' . __("Show") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.show', $user->id) . '" class="btn btn-sm text-white btn-warning mr-1"><i class="fas fa-eye"></i></a>
<a data-content="' . __("Edit") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.users.edit', $user->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" method="post" action="' . route('admin.users.togglesuspend', $user->id) . '">
' . csrf_field() . '
<button data-content="'.$suspendText.'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm '.$suspendColor.' text-white mr-1"><i class="far '.$suspendIcon.'"></i></button>
<button data-content="' . $suspendText . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm ' . $suspendColor . ' text-white mr-1"><i class="far ' . $suspendIcon . '"></i></button>
</form>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.users.destroy', $user->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="' . __("Delete") . '" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})
@ -300,7 +302,7 @@ class UserController extends Controller
return '<span class="badge ' . $badgeColor . '">' . $user->role . '</span>';
})
->editColumn('name', function (User $user) {
return '<a class="text-info" target="_blank" href="' . env('PTERODACTYL_URL', 'http://localhost') . '/admin/users/view/' . $user->pterodactyl_id . '">' . $user->name . '</a>';
return '<a class="text-info" target="_blank" href="' . config("SETTINGS::SYSTEM:PTERODACTYL:URL") . '/admin/users/view/' . $user->pterodactyl_id . '">' . $user->name . '</a>';
})
->orderColumn('last_seen', function ($query, $order) {
$query->orderBy('last_seen', $order);

View file

@ -55,7 +55,7 @@ class VoucherController extends Controller
Voucher::create($request->except('_token'));
return redirect()->route('admin.vouchers.index')->with('success', 'voucher has been created!');
return redirect()->route('admin.vouchers.index')->with('success', __('voucher has been created!'));
}
/**
@ -101,7 +101,7 @@ class VoucherController extends Controller
$voucher->update($request->except('_token'));
return redirect()->route('admin.vouchers.index')->with('success', 'voucher has been updated!');
return redirect()->route('admin.vouchers.index')->with('success', __('voucher has been updated!'));
}
/**
@ -113,7 +113,7 @@ class VoucherController extends Controller
public function destroy(Voucher $voucher)
{
$voucher->delete();
return redirect()->back()->with('success', 'voucher has been removed!');
return redirect()->back()->with('success', __('voucher has been removed!'));
}
public function users(Voucher $voucher)
@ -140,19 +140,19 @@ class VoucherController extends Controller
#extra validations
if ($voucher->getStatus() == 'USES_LIMIT_REACHED') throw ValidationException::withMessages([
'code' => 'This voucher has reached the maximum amount of uses'
'code' => __('This voucher has reached the maximum amount of uses')
]);
if ($voucher->getStatus() == 'EXPIRED') throw ValidationException::withMessages([
'code' => 'This voucher has expired'
'code' => __('This voucher has expired')
]);
if (!$request->user()->vouchers()->where('id', '=', $voucher->id)->get()->isEmpty()) throw ValidationException::withMessages([
'code' => 'You already redeemed this voucher code'
'code' => __('You already redeemed this voucher code')
]);
if ($request->user()->credits + $voucher->credits >= 99999999) throw ValidationException::withMessages([
'code' => "You can't redeem this voucher because you would exceed the " . CREDITS_DISPLAY_NAME . " limit"
'code' => "You can't redeem this voucher because you would exceed the limit of " . CREDITS_DISPLAY_NAME
]);
#redeem voucher
@ -161,7 +161,7 @@ class VoucherController extends Controller
event(new UserUpdateCreditsEvent($request->user()));
return response()->json([
'success' => "{$voucher->credits} " . CREDITS_DISPLAY_NAME . " have been added to your balance!"
'success' => "{$voucher->credits} " . CREDITS_DISPLAY_NAME ." ". __("have been added to your balance!")
]);
}
@ -189,19 +189,19 @@ class VoucherController extends Controller
return datatables($query)
->addColumn('actions', function (Voucher $voucher) {
return '
<a data-content="Users" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.users', $voucher->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-users"></i></a>
<a data-content="Edit" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.edit', $voucher->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<a data-content="'.__("Users").'" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.users', $voucher->id) . '" class="btn btn-sm btn-primary mr-1"><i class="fas fa-users"></i></a>
<a data-content="'.__("Edit").'" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.vouchers.edit', $voucher->id) . '" class="btn btn-sm btn-info mr-1"><i class="fas fa-pen"></i></a>
<form class="d-inline" onsubmit="return submitResult();" method="post" action="' . route('admin.vouchers.destroy', $voucher->id) . '">
' . csrf_field() . '
' . method_field("DELETE") . '
<button data-content="Delete" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
<button data-content="'.__("Delete").'" data-toggle="popover" data-trigger="hover" data-placement="top" class="btn btn-sm btn-danger mr-1"><i class="fas fa-trash"></i></button>
</form>
';
})
->addColumn('status', function (Voucher $voucher) {
$color = 'success';
if ($voucher->getStatus() != 'VALID') $color = 'danger';
if ($voucher->getStatus() != __('VALID')) $color = 'danger';
return '<span class="badge badge-' . $color . '">' . $voucher->getStatus() . '</span>';
})
->editColumn('uses', function (Voucher $voucher) {

View file

@ -5,8 +5,8 @@ namespace App\Http\Controllers\Api;
use App\Classes\Pterodactyl;
use App\Events\UserUpdateCreditsEvent;
use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\DiscordUser;
use App\Models\Settings;
use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
@ -88,10 +88,25 @@ class UserController extends Controller
"role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])],
]);
$user->update($request->all());
event(new UserUpdateCreditsEvent($user));
//Update Users Password on Pterodactyl
//Username,Mail,First and Lastname are required aswell
$response = Pterodactyl::client()->patch('/application/users/' . $user->pterodactyl_id, [
"username" => $request->name,
"first_name" => $request->name,
"last_name" => $request->name,
"email" => $request->email,
]);
if ($response->failed()) {
throw ValidationException::withMessages([
'pterodactyl_error_message' => $response->toException()->getMessage(),
'pterodactyl_error_status' => $response->toException()->getCode()
]);
}
$user->update($request->all());
return $user;
}
@ -166,6 +181,53 @@ class UserController extends Controller
return $user;
}
/**
* Suspends the user
*
* @param Request $request
* @param int $id
* @return bool
* @throws ValidationException
*/
public function suspend(Request $request, int $id)
{
$discordUser = DiscordUser::find($id);
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
if ($user->isSuspended()) {
throw ValidationException::withMessages([
'error' => 'The user is already suspended',
]);
}
$user->suspend();
return $user;
}
/**
* Unsuspend the user
*
* @param Request $request
* @param int $id
* @return bool
* @throws ValidationException
*/
public function unsuspend(Request $request, int $id)
{
$discordUser = DiscordUser::find($id);
$user = $discordUser ? $discordUser->user : User::findOrFail($id);
if (!$user->isSuspended()) {
throw ValidationException::withMessages([
'error' => "You cannot unsuspend an User who is not suspended."
]);
}
$user->unSuspend();
return $user;
}
/**
* @throws ValidationException
*/
@ -180,8 +242,8 @@ class UserController extends Controller
$user = User::create([
'name' => $request->input('name'),
'email' => $request->input('email'),
'credits' => Configuration::getValueByKey('INITIAL_CREDITS', 150),
'server_limit' => Configuration::getValueByKey('INITIAL_SERVER_LIMIT', 1),
'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
'password' => Hash::make($request->input('password')),
]);
@ -208,6 +270,8 @@ class UserController extends Controller
'pterodactyl_id' => $response->json()['attributes']['id']
]);
$user->sendEmailVerificationNotification();
return $user;
}

View file

@ -41,17 +41,25 @@ class LoginController extends Controller
public function login(Request $request)
{
$request->validate([
$validationRules = [
$this->username() => 'required|string',
'password' => 'required|string',
'g-recaptcha-response' => ['required','recaptcha'],
]);
];
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
$validationRules['g-recaptcha-response'] = ['required', 'recaptcha'];
}
$request->validate($validationRules);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
if (
method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)
) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);

View file

@ -4,7 +4,7 @@ namespace App\Http\Controllers\Auth;
use App\Classes\Pterodactyl;
use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\Settings;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\RegistersUsers;
@ -12,6 +12,7 @@ use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class RegisterController extends Controller
{
@ -53,30 +54,28 @@ class RegisterController extends Controller
*/
protected function validator(array $data)
{
if (Configuration::getValueByKey('REGISTER_IP_CHECK', 'true') == 'true') {
$validationRules = [
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
];
if (config('SETTINGS::RECAPTCHA:ENABLED') == 'true') {
$validationRules['g-recaptcha-response'] = ['required', 'recaptcha'];
}
if (config('SETTINGS::SYSTEM:REGISTER_IP_CHECK', 'true') == 'true') {
//check if ip has already made an account
$data['ip'] = session()->get('ip') ?? request()->ip();
if (User::where('ip', '=', request()->ip())->exists()) session()->put('ip', request()->ip());
$validationRules['ip'] = ['unique:users'];
return Validator::make($data, $validationRules, [
'ip.unique' => "You have already made an account! Please contact support if you think this is incorrect."
return Validator::make($data, [
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'g-recaptcha-response' => ['recaptcha'],
'ip' => ['unique:users'],
], [
'ip.unique' => "You have already made an account with us! Please contact support if you think this is incorrect."
]);
}
return Validator::make($data, [
'name' => ['required', 'string', 'max:30', 'min:4', 'alpha_num', 'unique:users'],
'email' => ['required', 'string', 'email', 'max:64', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'g-recaptcha-response' => ['recaptcha'],
]);
return Validator::make($data, $validationRules);
}
/**
@ -90,8 +89,8 @@ class RegisterController extends Controller
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'credits' => Configuration::getValueByKey('INITIAL_CREDITS', 150),
'server_limit' => Configuration::getValueByKey('INITIAL_SERVER_LIMIT', 1),
'credits' => config('SETTINGS::USER:INITIAL_CREDITS', 150),
'server_limit' => config('SETTINGS::USER:INITIAL_SERVER_LIMIT', 1),
'password' => Hash::make($data['password']),
]);
@ -108,13 +107,17 @@ class RegisterController extends Controller
if ($response->failed()) {
$user->delete();
return $user;
throw ValidationException::withMessages([
'ptero_registration_error' => [__('Account already exists on Pterodactyl. Please contact the Support!')],
]);
}
$user->update([
'pterodactyl_id' => $response->json()['attributes']['id']
]);
return $user;
}
}

View file

@ -3,8 +3,8 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\Configuration;
use App\Models\DiscordUser;
use App\Models\Settings;
use App\Models\User;
use App\Models\Voucher;
use Illuminate\Support\Facades\Auth;
@ -15,7 +15,7 @@ class SocialiteController extends Controller
{
public function redirect()
{
$scopes = !empty(env('DISCORD_BOT_TOKEN')) && !empty(env('DISCORD_GUILD_ID')) ? ['guilds.join'] : [];
$scopes = !empty(config("SETTINGS::DISCORD:BOT_TOKEN")) && !empty(config("SETTINGS::DISCORD:GUILD_ID")) ? ['guilds.join'] : [];
return Socialite::driver('discord')
->scopes($scopes)
@ -31,17 +31,17 @@ class SocialiteController extends Controller
/** @var User $user */
$user = Auth::user();
$discord = Socialite::driver('discord')->user();
$botToken = env('DISCORD_BOT_TOKEN');
$guildId = env('DISCORD_GUILD_ID');
$roleId = env('DISCORD_ROLE_ID');
$botToken = config("SETTINGS::DISCORD:BOT_TOKEN");
$guildId = config("SETTINGS::DISCORD:GUILD_ID");
$roleId = config("SETTINGS::DISCORD:ROLE_ID");
//save / update discord_users
if (is_null($user->discordUser)) {
//create discord user in db
DiscordUser::create(array_merge($discord->user, ['user_id' => Auth::user()->id]));
//update user
Auth::user()->increment('credits', Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD'));
Auth::user()->increment('server_limit', Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD'));
Auth::user()->increment('credits', config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'));
Auth::user()->increment('server_limit', config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD'));
Auth::user()->update(['discord_verified_at' => now()]);
} else {
$user->discordUser->update($discord->user);
@ -55,18 +55,22 @@ class SocialiteController extends Controller
'Authorization' => 'Bot ' . $botToken,
'Content-Type' => 'application/json',
]
)->put("https://discord.com/api/guilds/{$guildId}/members/{$discord->id}",
['access_token' => $discord->token]);
)->put(
"https://discord.com/api/guilds/{$guildId}/members/{$discord->id}",
['access_token' => $discord->token]
);
//give user a role in the discord server
if (!empty($roleId)){
if (!empty($roleId)) {
$response = Http::withHeaders(
[
'Authorization' => 'Bot ' . $botToken,
'Content-Type' => 'application/json',
]
)->put("https://discord.com/api/guilds/{$guildId}/members/{$discord->id}/roles/{$roleId}",
['access_token' => $discord->token]);
)->put(
"https://discord.com/api/guilds/{$guildId}/members/{$discord->id}/roles/{$roleId}",
['access_token' => $discord->token]
);
}
}

View file

@ -2,10 +2,7 @@
namespace App\Http\Controllers;
use App\Models\Egg;
use App\Models\Product;
use App\Models\UsefulLink;
use App\Models\Configuration;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -15,7 +12,6 @@ class HomeController extends Controller
const TIME_LEFT_BG_SUCCESS = "bg-success";
const TIME_LEFT_BG_WARNING = "bg-warning";
const TIME_LEFT_BG_DANGER = "bg-danger";
const TIME_LEFT_OUT_OF_CREDITS_TEXT = "You ran out of Credits";
public function __construct()
{
@ -51,8 +47,8 @@ class HomeController extends Controller
*/
public function getTimeLeftBoxUnit(float $daysLeft, float $hoursLeft)
{
if ($daysLeft > 1) return 'days';
return $hoursLeft < 1 ? null : "hours";
if ($daysLeft > 1) return __('days');
return $hoursLeft < 1 ? null : __("hours");
}
/**
@ -66,7 +62,7 @@ class HomeController extends Controller
public function getTimeLeftBoxText(float $daysLeft, float $hoursLeft)
{
if ($daysLeft > 1) return strval(number_format($daysLeft, 0));
return ($hoursLeft < 1 ? $this::TIME_LEFT_OUT_OF_CREDITS_TEXT : strval($hoursLeft));
return ($hoursLeft < 1 ? __("You ran out of Credits") : strval($hoursLeft));
}
/** Show the application dashboard. */
@ -85,13 +81,13 @@ class HomeController extends Controller
$bg = $this->getTimeLeftBoxBackground($daysLeft);
$boxText = $this->getTimeLeftBoxText($daysLeft, $hoursLeft);
$unit = $daysLeft < 1 ? ($hoursLeft < 1 ? null : "hours") : "days";
$unit = $daysLeft < 1 ? ($hoursLeft < 1 ? null : __("hours")) : __("days");
}
// RETURN ALL VALUES
return view('home')->with([
'useage' => $usage,
'usage' => $usage,
'credits' => $credits,
'useful_links' => UsefulLink::all()->sortBy('id'),
'bg' => $bg,
@ -99,6 +95,4 @@ class HomeController extends Controller
'unit' => $unit
]);
}
}

View file

@ -2,15 +2,14 @@
namespace App\Http\Controllers;
use App\Models\Configuration;
use App\Classes\Pterodactyl;
use App\Models\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class ProfileController extends Controller
{
@ -19,9 +18,9 @@ class ProfileController extends Controller
{
return view('profile.index')->with([
'user' => Auth::user(),
'credits_reward_after_verify_discord' => Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD'),
'force_email_verification' => Configuration::getValueByKey('FORCE_EMAIL_VERIFICATION'),
'force_discord_verification' => Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION'),
'credits_reward_after_verify_discord' => config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD'),
'force_email_verification' => config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION'),
'force_discord_verification' => config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION'),
]);
}
@ -37,15 +36,15 @@ class ProfileController extends Controller
$user = User::findOrFail($id);
//update password if necessary
if (!is_null($request->input('new_password'))){
if (!is_null($request->input('new_password'))) {
//validate password request
$request->validate([
'current_password' => [
'required' ,
'required',
function ($attribute, $value, $fail) use ($user) {
if (!Hash::check($value, $user->password)) {
$fail('The '.$attribute.' is invalid.');
$fail('The ' . $attribute . ' is invalid.');
}
},
],
@ -53,21 +52,38 @@ class ProfileController extends Controller
'new_password_confirmation' => 'required|same:new_password'
]);
//Update Users Password on Pterodactyl
//Username,Mail,First and Lastname are required aswell
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
"password" => $request->input('new_password'),
"username" => $request->input('name'),
"first_name" => $request->input('name'),
"last_name" => $request->input('name'),
"email" => $request->input('email'),
]);
if ($response->failed()) {
throw ValidationException::withMessages([
'pterodactyl_error_message' => $response->toException()->getMessage(),
'pterodactyl_error_status' => $response->toException()->getCode()
]);
}
//update password
$user->update([
'password' => Hash::make($request->input('new_password')),
]);
}
//validate request
$request->validate([
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,'.$id.',id',
'email' => 'required|email|max:64|unique:users,email,'.$id.',id',
'name' => 'required|min:4|max:30|alpha_num|unique:users,name,' . $id . ',id',
'email' => 'required|email|max:64|unique:users,email,' . $id . ',id',
'avatar' => 'nullable'
]);
//update avatar
if(!is_null($request->input('avatar'))){
if (!is_null($request->input('avatar'))) {
$avatar = json_decode($request->input('avatar'));
if ($avatar->input->size > 3000000) abort(500);
@ -80,12 +96,28 @@ class ProfileController extends Controller
]);
}
//update name and email on Pterodactyl
$response = Pterodactyl::client()->patch('/application/users/'.$user->pterodactyl_id, [
"username" => $request->input('name'),
"first_name" => $request->input('name'),
"last_name" => $request->input('name'),
"email" => $request->input('email'),
]);
if ($response->failed()) {
throw ValidationException::withMessages([
'pterodactyl_error_message' => $response->toException()->getMessage(),
'pterodactyl_error_status' => $response->toException()->getCode()
]);
}
//update name and email
$user->update([
'name' => $request->input('name'),
'email' => $request->input('email'),
]);
$user->sendEmailVerificationNotification();
return redirect()->route('profile.index')->with('success' , 'Profile updated');
return redirect()->route('profile.index')->with('success', __('Profile updated'));
}
}

View file

@ -3,13 +3,13 @@
namespace App\Http\Controllers;
use App\Classes\Pterodactyl;
use App\Models\Configuration;
use App\Models\Egg;
use App\Models\Location;
use App\Models\Nest;
use App\Models\Node;
use App\Models\Product;
use App\Models\Server;
use App\Models\Settings;
use App\Notifications\ServerCreationError;
use Exception;
use Illuminate\Database\Eloquent\Builder;
@ -24,8 +24,35 @@ class ServerController extends Controller
/** Display a listing of the resource. */
public function index()
{
$servers = Auth::user()->servers;
//Get and set server infos each server
foreach ($servers as $server) {
//Get server infos from ptero
$serverAttributes = Pterodactyl::getServerAttributes($server->pterodactyl_id);
$serverRelationships = $serverAttributes['relationships'];
$serverLocationAttributes = $serverRelationships['location']['attributes'];
//Set server infos
$server->location = $serverLocationAttributes['long'] ?
$serverLocationAttributes['long'] :
$serverLocationAttributes['short'];
$server->egg = $serverRelationships['egg']['attributes']['name'];
$server->nest = $serverRelationships['nest']['attributes']['name'];
$server->node = $serverRelationships['node']['attributes']['name'];
//get productname by product_id for server
$product = Product::find($server->product_id);
$server->product = $product;
}
return view('servers.index')->with([
'servers' => Auth::user()->Servers
'servers' => $servers
]);
}
@ -71,7 +98,7 @@ class ServerController extends Controller
{
//limit validation
if (Auth::user()->servers()->count() >= Auth::user()->server_limit) {
return redirect()->route('servers.index')->with('error', 'Server limit reached!');
return redirect()->route('servers.index')->with('error', __('Server limit reached!'));
}
// minimum credits
@ -80,7 +107,7 @@ class ServerController extends Controller
if (
Auth::user()->credits <
($product->minimum_credits == -1
? Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
? config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)
: $product->minimum_credits)
) {
return redirect()->route('servers.index')->with('error', "You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product!");
@ -88,13 +115,13 @@ class ServerController extends Controller
}
//Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_EMAIL_VERIFICATION', 'false') === 'true' && !Auth::user()->hasVerifiedEmail()) {
return redirect()->route('profile.index')->with('error', "You are required to verify your email address before you can create a server.");
if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', 'false') === 'true' && !Auth::user()->hasVerifiedEmail()) {
return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can create a server."));
}
//Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION', 'false') === 'true' && !Auth::user()->discordUser) {
return redirect()->route('profile.index')->with('error', "You are required to link your discord account before you can create a server.");
if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', 'false') === 'true' && !Auth::user()->discordUser) {
return redirect()->route('profile.index')->with('error', __("You are required to link your discord account before you can create a server."));
}
return null;
@ -134,19 +161,20 @@ class ServerController extends Controller
$response = Pterodactyl::createServer($server, $egg, $allocationId);
if ($response->failed()) return $this->serverCreationFailed($response, $server);
$serverAttributes = $response->json()['attributes'];
//update server with pterodactyl_id
$server->update([
'pterodactyl_id' => $response->json()['attributes']['id'],
'identifier' => $response->json()['attributes']['identifier']
'pterodactyl_id' => $serverAttributes['id'],
'identifier' => $serverAttributes['identifier']
]);
if (Configuration::getValueByKey('SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
if (config('SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR', 'true') == 'true') {
if ($request->user()->credits >= $server->product->getHourlyPrice()) {
$request->user()->decrement('credits', $server->product->getHourlyPrice());
}
}
return redirect()->route('servers.index')->with('success', 'Server created');
return redirect()->route('servers.index')->with('success', __('Server created'));
}
/**
@ -159,7 +187,7 @@ class ServerController extends Controller
$server->delete();
Auth::user()->notify(new ServerCreationError($server));
return redirect()->route('servers.index')->with('error', 'No allocations satisfying the requirements for automatic deployment on this node were found.');
return redirect()->route('servers.index')->with('error', __('No allocations satisfying the requirements for automatic deployment on this node were found.'));
}
/**
@ -180,9 +208,9 @@ class ServerController extends Controller
{
try {
$server->delete();
return redirect()->route('servers.index')->with('success', 'Server removed');
return redirect()->route('servers.index')->with('success', __('Server removed'));
} catch (Exception $e) {
return redirect()->route('servers.index')->with('error', 'An exception has occurred while trying to remove a resource "' . $e->getMessage() . '"');
return redirect()->route('servers.index')->with('error', __('An exception has occurred while trying to remove a resource "') . $e->getMessage() . '"');
}
}
}

View file

@ -2,8 +2,8 @@
namespace App\Http\Controllers;
use App\Models\Configuration;
use App\Models\PaypalProduct;
use App\Models\CreditProduct;
use App\Models\Settings;
use Illuminate\Support\Facades\Auth;
class StoreController extends Controller
@ -11,24 +11,27 @@ class StoreController extends Controller
/** Display a listing of the resource. */
public function index()
{
$isPaypalSetup = false;
if (env('PAYPAL_SECRET') && env('PAYPAL_CLIENT_ID')) $isPaypalSetup = true;
if (env('APP_ENV', 'local') == 'local') $isPaypalSetup = true;
$isPaymentSetup = false;
if (
env('APP_ENV') == 'local' ||
config("SETTINGS::PAYMENTS:PAYPAL:SECRET") && config("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID") ||
config("SETTINGS::PAYMENTS:STRIPE:SECRET") && config("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET") && config("SETTINGS::PAYMENTS:STRIPE:METHODS")
) $isPaymentSetup = true;
//Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_EMAIL_VERIFICATION', false) === 'true' && !Auth::user()->hasVerifiedEmail()) {
return redirect()->route('profile.index')->with('error', "You are required to verify your email address before you can purchase credits.");
if (config('SETTINGS::USER:FORCE_EMAIL_VERIFICATION', false) === 'true' && !Auth::user()->hasVerifiedEmail()) {
return redirect()->route('profile.index')->with('error', __("You are required to verify your email address before you can purchase credits."));
}
//Required Verification for creating an server
if (Configuration::getValueByKey('FORCE_DISCORD_VERIFICATION', false) === 'true' && !Auth::user()->discordUser) {
return redirect()->route('profile.index')->with('error', "You are required to link your discord account before you can purchase ".CREDITS_DISPLAY_NAME.".");
if (config('SETTINGS::USER:FORCE_DISCORD_VERIFICATION', false) === 'true' && !Auth::user()->discordUser) {
return redirect()->route('profile.index')->with('error', __("You are required to link your discord account before you can purchase Credits"));
}
return view('store.index')->with([
'products' => PaypalProduct::where('disabled', '=', false)->orderBy('price', 'asc')->get(),
'isPaypalSetup' => $isPaypalSetup
'products' => CreditProduct::where('disabled', '=', false)->orderBy('price', 'asc')->get(),
'isPaymentSetup' => $isPaymentSetup,
]);
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class TranslationController extends Controller
{
/**
*
* Change session locale
* @param Request $request
* @return Response
*/
public function changeLocale(Request $request)
{
Session::put('locale', $request->inputLocale);
return redirect()->back();
}
}

View file

@ -4,7 +4,7 @@ namespace App\Http;
use App\Http\Middleware\ApiAuthToken;
use App\Http\Middleware\CheckSuspended;
use App\Http\Middleware\CreditsDisplayName;
use App\Http\Middleware\GlobalNames;
use App\Http\Middleware\isAdmin;
use App\Http\Middleware\LastSeen;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
@ -43,13 +43,14 @@ class Kernel extends HttpKernel
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
LastSeen::class,
CreditsDisplayName::class,
GlobalNames::class,
\App\Http\Middleware\SetLocale::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
CreditsDisplayName::class
GlobalNames::class
],
];

View file

@ -1,23 +0,0 @@
<?php
namespace App\Http\Middleware;
use App\Models\Configuration;
use Closure;
use Illuminate\Http\Request;
class CreditsDisplayName
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
define('CREDITS_DISPLAY_NAME' , Configuration::getValueByKey('CREDITS_DISPLAY_NAME' , 'Credits'));
return $next($request);
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Http\Middleware;
use App\Models\Configuration;
use App\Models\Settings;
use Closure;
use Illuminate\Http\Request;
class GlobalNames
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
define('CREDITS_DISPLAY_NAME', config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME', 'Credits'));
$unsupported_lang_array = explode(',', config("app.unsupported_locales"));
$unsupported_lang_array = array_map('strtolower', $unsupported_lang_array);
define('UNSUPPORTED_LANGS', $unsupported_lang_array);
return $next($request);
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace App\Http\Middleware;
use App\Models\Settings;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
class SetLocale
{
/**
*
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (Session::has('locale')) {
$locale = Session::get('locale', config("SETTINGS::LOCALE:DEFAULT"));
} else {
if (config("SETTINGS::LOCALE:DYNAMIC") !== "true") {
$locale = config("SETTINGS::LOCALE:DEFAULT");
} else {
$locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2);
if (!in_array($locale, explode(',', config("SETTINGS::LOCALE:AVAILABLE")))) {
$locale = config("SETTINGS::LOCALE:DEFAULT");
}
}
}
App::setLocale($locale);
return $next($request);
}
}

View file

@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware
* @var array
*/
protected $except = [
//
'payment/StripeWebhooks'
];
}

View file

@ -3,11 +3,10 @@
namespace App\Listeners;
use App\Events\UserUpdateCreditsEvent;
use App\Models\Configuration;
use App\Models\Server;
use App\Models\Settings;
use Exception;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class UnsuspendServers implements ShouldQueue
{
@ -20,11 +19,11 @@ class UnsuspendServers implements ShouldQueue
*/
public function handle(UserUpdateCreditsEvent $event)
{
if ($event->user->credits > Configuration::getValueByKey('MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER' , 50)){
/** @var Server $server */
foreach ($event->user->servers as $server){
if ($server->isSuspended()) $server->unSuspend();
}
}
if ($event->user->credits > config('SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER', 50)) {
/** @var Server $server */
foreach ($event->user->servers as $server) {
if ($server->isSuspended()) $server->unSuspend();
}
}
}
}

View file

@ -2,9 +2,7 @@
namespace App\Listeners;
use App\Models\Configuration;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use App\Models\Settings;
class Verified
{
@ -26,7 +24,7 @@ class Verified
*/
public function handle($event)
{
$event->user->increment('server_limit' , Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL'));
$event->user->increment('credits' , Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL'));
$event->user->increment('server_limit', config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL'));
$event->user->increment('credits', config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL'));
}
}

View file

@ -8,7 +8,7 @@ use NumberFormatter;
use Spatie\Activitylog\Traits\LogsActivity;
use App\Models\Configuration;
class PaypalProduct extends Model
class CreditProduct extends Model
{
use LogsActivity;
/**
@ -33,53 +33,53 @@ class PaypalProduct extends Model
{
parent::boot();
static::creating(function (PaypalProduct $paypalProduct) {
static::creating(function (CreditProduct $creditProduct) {
$client = new Client();
$paypalProduct->{$paypalProduct->getKeyName()} = $client->generateId($size = 21);
$creditProduct->{$creditProduct->getKeyName()} = $client->generateId($size = 21);
});
}
/**
* @param mixed $value
* @param string $locale
*
*
* @return float
*/
public function formatToCurrency($value,$locale = 'en_US')
public function formatToCurrency($value, $locale = 'en_US')
{
$formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);
return $formatter->formatCurrency($value, $this->currency_code);
}
/**
* @description Returns the tax in % taken from the Configuration
*
* @return int
*/
* @description Returns the tax in % taken from the Configuration
*
* @return int
*/
public function getTaxPercent()
{
$tax = Configuration::getValueByKey("SALES_TAX");
$tax = config("SETTINGS::PAYMENTS:SALES_TAX");
return $tax < 0 ? 0 : $tax;
}
/**
* @description Returns the tax as Number
*
* @return float
*/
* @description Returns the tax as Number
*
* @return float
*/
public function getTaxValue()
{
return $this->price*$this->getTaxPercent()/100;
return number_format($this->price * $this->getTaxPercent() / 100, 2);
}
/**
* @description Returns the full price of a Product including tax
*
* @return float
*/
public function getTotalPrice()
* @description Returns the full price of a Product including tax
*
* @return float
*/
public function getTotalPrice()
{
return $this->price+($this->getTaxValue());
return number_format($this->price + $this->getTaxValue(), 2);
}
}

18
app/Models/Invoice.php Normal file
View file

@ -0,0 +1,18 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
use HasFactory;
protected $fillable = [
'invoice_name',
'invoice_user',
'payment_id'
];
}

View file

@ -23,8 +23,7 @@ class Payment extends Model
'id',
'user_id',
'payment_id',
'payer_id',
'payer',
'payment_method',
'status',
'type',
'amount',
@ -33,6 +32,7 @@ class Payment extends Model
'total_price',
'tax_percent',
'currency_code',
'credit_product_id',
];
public static function boot()
@ -57,10 +57,10 @@ class Payment extends Model
/**
* @param mixed $value
* @param string $locale
*
*
* @return float
*/
public function formatToCurrency($value,$locale = 'en_US')
public function formatToCurrency($value, $locale = 'en_US')
{
$formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);
return $formatter->formatCurrency($value, $this->currency_code);

View file

@ -6,11 +6,13 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class Configuration extends Model
class Settings extends Model
{
use HasFactory;
public const CACHE_TAG = 'configuration';
protected $table = 'settings';
public const CACHE_TAG = 'setting';
public $primaryKey = 'key';
@ -28,8 +30,8 @@ class Configuration extends Model
{
parent::boot();
static::updated(function (Configuration $configuration) {
Cache::forget(self::CACHE_TAG .':'. $configuration->key);
static::updated(function (Settings $settings) {
Cache::forget(self::CACHE_TAG .':'. $settings->key);
});
}
@ -41,8 +43,8 @@ class Configuration extends Model
public static function getValueByKey(string $key, $default = null)
{
return Cache::rememberForever(self::CACHE_TAG .':'. $key, function () use ($default, $key) {
$configuration = self::find($key);
return $configuration ? $configuration->value : $default;
$settings = self::find($key);
return $settings ? $settings->value : $default;
});
}
}

View file

@ -86,10 +86,10 @@ class Voucher extends Model
{
if ($this->users()->count() >= $this->uses) return 'USES_LIMIT_REACHED';
if (!is_null($this->expires_at)) {
if ($this->expires_at->isPast()) return 'EXPIRED';
if ($this->expires_at->isPast()) return __('EXPIRED');
}
return 'VALID';
return __('VALID');
}
/**

View file

@ -10,6 +10,9 @@ use Illuminate\Notifications\Notification;
class ConfirmPaymentNotification extends Notification implements ShouldQueue
{
//THIS IS BASICALLY NOT USED ANYMORE WITH INVOICENOTIFICATION IN PLACE
use Queueable;
private Payment $payment;
@ -44,7 +47,7 @@ class ConfirmPaymentNotification extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Payment Confirmation')
->subject(__('Payment Confirmation'))
->markdown('mail.payment.confirmed' , ['payment' => $this->payment]);
}
@ -57,8 +60,8 @@ class ConfirmPaymentNotification extends Notification implements ShouldQueue
public function toArray($notifiable)
{
return [
'title' => "Payment Confirmed!",
'content' => "Payment Confirmed!",
'title' => __("Payment Confirmed!"),
'content' => __("Payment Confirmed!"),
];
}
}

View file

@ -0,0 +1,69 @@
<?php
namespace App\Notifications;
use App\Models\Payment;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use LaravelDaily\Invoices\Invoice;
class InvoiceNotification extends Notification
{
use Queueable;
/**
* @var invoice
* * @var invoice
* * @var invoice
*/
private $invoice;
private $user;
private $payment;
/**
* Create a new notification instance.
*
* @param Invoice $invoice
*/
public function __construct(Invoice $invoice, User $user, Payment $payment)
{
$this->invoice = $invoice;
$this->user = $user;
$this->payment = $payment;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->subject(__('Your Payment was successful!'))
->greeting(__('Hello').',')
->line(__("Your payment was processed successfully!"))
->line(__('Status').': ' . $this->payment->status)
->line(__('Price').': ' . $this->payment->formatToCurrency($this->payment->total_price))
->line(__('Type').': ' . $this->payment->type)
->line(__('Amount').': ' . $this->payment->amount)
->line(__('Balance').': ' . number_format($this->user->credits,2))
->line(__('User ID').': ' . $this->payment->user_id)
->attach(storage_path('app/invoice/' . $this->user->id . '/' . now()->format('Y') . '/' . $this->invoice->filename));
}
}

View file

@ -46,7 +46,7 @@ class ServerCreationError extends Notification
public function toArray($notifiable)
{
return [
'title' => "Server Creation Error",
'title' => __("Server Creation Error"),
'content' => "
<p>Hello <strong>{$this->server->User->name}</strong>, An unexpected error has occurred...</p>
<p>There was a problem creating your server on our pterodactyl panel. There are likely no allocations or rooms left on the selected node. Please contact one of our support members through our discord server to get this resolved asap!</p>

View file

@ -2,7 +2,6 @@
namespace App\Notifications;
use App\Models\Configuration;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@ -42,11 +41,11 @@ class ServersSuspendedNotification extends Notification implements ShouldQueue
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Your servers have been suspended!')
->greeting('Your servers have been suspended!')
->line("To automatically re-enable your server/s, you need to purchase more credits.")
->action('Purchase credits', route('store.index'))
->line('If you have any questions please let us know.');
->subject(__('Your servers have been suspended!'))
->greeting(__('Your servers have been suspended!'))
->line(__("To automatically re-enable your server/s, you need to purchase more credits."))
->action(__('Purchase credits'), route('store.index'))
->line(__('If you have any questions please let us know.'));
}
/**
@ -58,12 +57,12 @@ class ServersSuspendedNotification extends Notification implements ShouldQueue
public function toArray($notifiable)
{
return [
'title' => "Servers suspended!",
'title' => __('Your servers have been suspended!'),
'content' => "
<h5>Your servers have been suspended!</h5>
<p>To automatically re-enable your server/s, you need to purchase more credits.</p>
<p>If you have any questions please let us know.</p>
<p>Regards,<br />" . config('app.name', 'Laravel') . "</p>
<h5>". __('Your servers have been suspended!')."</h5>
<p>". __("To automatically re-enable your server/s, you need to purchase more credits.")."</p>
<p>". __('If you have any questions please let us know.')."</p>
<p>". __('Regards').",<br />" . config('app.name', 'Laravel') . "</p>
",
];
}

View file

@ -2,7 +2,7 @@
namespace App\Notifications;
use App\Models\Configuration;
use App\Models\Settings;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@ -38,25 +38,25 @@ class WelcomeMessage extends Notification implements ShouldQueue
return ['database'];
}
public function AdditionalLines()
{
{
$AdditionalLine = "";
if(Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail address will grant you ".Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_EMAIL')." additional " . Configuration::getValueByKey('CREDITS_DISPLAY_NAME') . ". <br />";
}
if(Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail will also increase your Server Limit by " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . ". <br />";
}
$AdditionalLine .="<br />";
if(Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "You can also verify your discord account to get another " . Configuration::getValueByKey('CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " " . Configuration::getValueByKey('CREDITS_DISPLAY_NAME') . ". <br />";
}
if(Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "Verifying your Discord account will also increase your Server Limit by " . Configuration::getValueByKey('SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') . ". <br />";
}
return $AdditionalLine;
$AdditionalLine = "";
if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail address will grant you " . config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL') . " additional " . config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') . ". <br />";
}
if (config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') != 0) {
$AdditionalLine .= "Verifying your e-mail will also increase your Server Limit by " . config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL') . ". <br />";
}
$AdditionalLine .= "<br />";
if (config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "You can also verify your discord account to get another " . config('SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD') . " " . config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME') . ". <br />";
}
if (config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') != 0) {
$AdditionalLine .= "Verifying your Discord account will also increase your Server Limit by " . config('SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD') . ". <br />";
}
return $AdditionalLine;
}
/**
* Get the array representation of the notification.
*
@ -66,13 +66,13 @@ class WelcomeMessage extends Notification implements ShouldQueue
public function toArray($notifiable)
{
return [
'title' => "Getting started!",
'title' => __("Getting started!"),
'content' => "
<p>Hello <strong>{$this->user->name}</strong>, Welcome to our dashboard!</p>
<h5>Verification</h5>
<p>You can verify your e-mail address and link/verify your Discord account.</p>
<p>
".$this->AdditionalLines()."
" . $this->AdditionalLines() . "
</p>
<h5>Information</h5>
<p>This dashboard can be used to create and delete servers.<br /> These servers can be used and managed on our pterodactyl panel.<br /> If you have any questions, please join our Discord server and #create-a-ticket.</p>

View file

@ -2,11 +2,12 @@
namespace App\Providers;
use App\Models\Settings;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
use Spatie\QueryBuilder\QueryBuilderRequest;
class AppServiceProvider extends ServiceProvider
{
@ -31,14 +32,11 @@ class AppServiceProvider extends ServiceProvider
Schema::defaultStringLength(191);
Validator::extend('multiple_date_format', function ($attribute, $value, $parameters, $validator) {
$ok = true;
$result = [];
// iterate through all formats
foreach ($parameters as $parameter) {
//validate with laravels standard date format validation
$result[] = $validator->validateDateFormat($attribute, $value, [$parameter]);
}
@ -51,5 +49,60 @@ class AppServiceProvider extends ServiceProvider
return $ok;
});
//only run if the installer has been executed
if (file_exists(base_path()."/install.lock")) {
$settings = Settings::all();
// Set all configs from database
foreach ($settings as $setting) {
config([$setting->key => $setting->value]);
}
// Set Mail Config
//only update config if mail settings have changed in DB
if (
config('mail.default') != config('SETTINGS:MAIL:MAILER') ||
config('mail.mailers.smtp.host') != config('SETTINGS:MAIL:HOST') ||
config('mail.mailers.smtp.port') != config('SETTINGS:MAIL:PORT') ||
config('mail.mailers.smtp.username') != config('SETTINGS:MAIL:USERNAME') ||
config('mail.mailers.smtp.password') != config('SETTINGS:MAIL:PASSWORD') ||
config('mail.mailers.smtp.encryption') != config('SETTINGS:MAIL:ENCRYPTION') ||
config('mail.from.address') != config('SETTINGS:MAIL:FROM_ADDRESS') ||
config('mail.from.name') != config('SETTINGS:MAIL:FROM_NAME')
) {
config(['mail.default' => config('SETTINGS::MAIL:MAILER')]);
config(['mail.mailers.smtp' => [
'transport' => 'smtp',
'host' => config('SETTINGS::MAIL:HOST'),
'port' => config('SETTINGS::MAIL:PORT'),
'encryption' => config('SETTINGS::MAIL:ENCRYPTION'),
'username' => config('SETTINGS::MAIL:USERNAME'),
'password' => config('SETTINGS::MAIL:PASSWORD'),
'timeout' => null,
'auth_mode' => null,
]]);
config(['mail.from' => ['address' => config('SETTINGS::MAIL:FROM_ADDRESS'), 'name' => config('SETTINGS::MAIL:FROM_NAME')]]);
Artisan::call('queue:restart');
}
// Set Recaptcha API Config
//only update config if recaptcha settings have changed in DB
if (
config('recaptcha.api_site_key') != config('SETTINGS::RECAPTCHA:SITE_KEY') ||
config('recaptcha.api_secret_key') != config('SETTINGS::RECAPTCHA:SECRET_KEY')
) {
config(['recaptcha.api_site_key' => config('SETTINGS::RECAPTCHA:SITE_KEY')]);
config(['recaptcha.api_secret_key' => config('SETTINGS::RECAPTCHA:SECRET_KEY')]);
Artisan::call('config:clear');
Artisan::call('cache:clear');
}
// Set Discord-API Config
config(['services.discord.client_id' => config('SETTINGS::DISCORD:CLIENT_ID')]);
config(['services.discord.client_secret' => config('SETTINGS::DISCORD:CLIENT_SECRET')]);
}
}
}

View file

@ -1,7 +1,7 @@
{
"name": "laravel/laravel",
"name": "cpgg/dashboard",
"type": "project",
"description": "The Laravel Framework.",
"description": "A billing and control panel made for Pterodactyl.",
"keywords": [
"framework",
"laravel"
@ -16,15 +16,19 @@
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"hidehalo/nanoid-php": "^1.1",
"kkomelin/laravel-translatable-string-exporter": "^1.14",
"laravel/framework": "^8.12",
"laravel/tinker": "^2.5",
"laravel/ui": "^3.2",
"laraveldaily/laravel-invoices": "^2.0",
"paypal/paypal-checkout-sdk": "^1.0",
"paypal/rest-api-sdk-php": "^1.14",
"socialiteproviders/discord": "^4.1",
"spatie/laravel-activitylog": "^3.16",
"spatie/laravel-query-builder": "^3.6",
"spatie/laravel-validation-rules": "^3.0",
"stripe/stripe-php": "^7.107",
"symfony/intl": "^6.0",
"yajra/laravel-datatables-oracle": "~9.0"
},
"require-dev": {

3113
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,10 @@
<?php
use App\Models\Settings;
return [
'version' => '0.6.2',
'version' => '0.7',
/*
|--------------------------------------------------------------------------
| Application Name
@ -70,6 +72,7 @@ return [
'timezone' => env('APP_TIMEZONE', 'UTC'),
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
@ -81,7 +84,21 @@ return [
|
*/
'locale' => 'en',
'locale' =>"en",
/*
|--------------------------------------------------------------------------
| Available Languages
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'available_locales' => array_map('basename', preg_replace('/\\.[^.\\s]{3,4}$/', '', glob(resource_path()."/lang/*.json", GLOB_BRACE))),
/*
|--------------------------------------------------------------------------
@ -178,6 +195,9 @@ return [
App\Providers\RouteServiceProvider::class,
Yajra\DataTables\DataTablesServiceProvider::class,
KKomelin\TranslatableStringExporter\Providers\ExporterServiceProvider::class,
],
/*

97
config/invoices.php Normal file
View file

@ -0,0 +1,97 @@
<?php
return [
'date' => [
/*
* Carbon date format
*/
'format' => 'Y-m-d',
/*
* Due date for payment since invoice's date.
*/
'pay_until_days' => 7,
],
'serial_number' => [
'series' => 'AA',
'sequence' => 1,
/*
* Sequence will be padded accordingly, for ex. 00001
*/
'sequence_padding' => 5,
'delimiter' => '.',
/*
* Supported tags {SERIES}, {DELIMITER}, {SEQUENCE}
* Example: AA.00001
*/
'format' => '{SERIES}{DELIMITER}{SEQUENCE}',
],
'currency' => [
'code' => 'eur',
/*
* Usually cents
* Used when spelling out the amount and if your currency has decimals.
*
* Example: Amount in words: Eight hundred fifty thousand sixty-eight EUR and fifteen ct.
*/
'fraction' => 'ct.',
'symbol' => '€',
/*
* Example: 19.00
*/
'decimals' => 2,
/*
* Example: 1.99
*/
'decimal_point' => '.',
/*
* By default empty.
* Example: 1,999.00
*/
'thousands_separator' => '',
/*
* Supported tags {VALUE}, {SYMBOL}, {CODE}
* Example: 1.99
*/
'format' => '{VALUE} {SYMBOL}',
],
'paper' => [
// A4 = 210 mm x 297 mm = 595 pt x 842 pt
'size' => 'a4',
'orientation' => 'portrait',
],
'disk' => 'local',
'seller' => [
/*
* Class used in templates via $invoice->seller
*
* Must implement LaravelDaily\Invoices\Contracts\PartyContract
* or extend LaravelDaily\Invoices\Classes\Party
*/
'class' => \LaravelDaily\Invoices\Classes\Seller::class,
/*
* Default attributes for Seller::class
*/
'attributes' => [
'name' => 'Towne, Smith and Ebert',
'address' => '89982 Pfeffer Falls Damianstad, CO 66972-8160',
'code' => '41-1985581',
'vat' => '123456789',
'phone' => '760-355-3930',
'custom_fields' => [
/*
* Custom attributes for Seller::class
*
* Used to display additional info on Seller section in invoice
* attribute => value
*/
'SWIFT' => 'BANK101',
],
],
],
];

View file

@ -45,31 +45,22 @@ return [
'auth_mode' => null,
],
'ses' => [
'transport' => 'ses',
],
'mailgun' => [
'transport' => 'mailgun',
],
'postmark' => [
'transport' => 'postmark',
],
'sendmail' => [
'transport' => 'sendmail',
'path' => '/usr/sbin/sendmail -bs',
],
'log' => [
'transport' => 'log',
'channel' => env('MAIL_LOG_CHANNEL'),
],
'array' => [
'transport' => 'array',
],
// 'ses' => [
// 'transport' => 'ses',
// ],
//
// 'mailgun' => [
// 'transport' => 'mailgun',
// ],
//
// 'postmark' => [
// 'transport' => 'postmark',
// ],
//
// 'sendmail' => [
// 'transport' => 'sendmail',
// 'path' => '/usr/sbin/sendmail -bs',
// ],
],
/*

View file

View file

@ -19,7 +19,7 @@ class CreatePaypalProductsTable extends Migration
$table->decimal('price')->default(0);
$table->unsignedInteger('quantity');
$table->string('description');
$table->string('currency_code' , 3);
$table->string('currency_code', 3);
$table->boolean('disabled')->default(true);
$table->timestamps();
});

View file

@ -21,7 +21,6 @@ class CreateConfigurationsTable extends Migration
$table->timestamps();
});
}
/**
* Reverse the migrations.
*

View file

@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDisplayToPaypalProductsTable extends Migration
class AddDisplayToPayPalProductsTable extends Migration
{
/**
* Run the migrations.

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateInvoices extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('invoices', function (Blueprint $table) {
$table->id();
$table->string('invoice_name');
$table->string('invoice_user');
$table->string('payment_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('invoices');
}
}

View file

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class UpdateToPaymentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('payments', function (Blueprint $table) {
$table->string('payment_method');
$table->dropColumn('payer');
$table->dropColumn('payer_id');
$table->string('credit_product_id');
});
DB::statement('UPDATE payments SET payment_method="paypal"');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('payments', function (Blueprint $table) {
$table->dropColumn('payment_method');
$table->string('payer_id')->nullable();
$table->text('payer')->nullable();
$table->dropColumn('credit_product_id');
});
}
}

View file

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class RenamePaypalProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::rename('paypal_products', 'credit_products');
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::rename('credit_products', 'paypal_products');
}
}

View file

@ -0,0 +1,61 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
class RenameConfigurationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::rename('configurations', 'settings');
DB::table('settings')->where('key', 'INITIAL_CREDITS')->update(['key' => 'SETTINGS::USER:INITIAL_CREDITS']);
DB::table('settings')->where('key', 'INITIAL_SERVER_LIMIT')->update(['key' => 'SETTINGS::USER:INITIAL_SERVER_LIMIT']);
DB::table('settings')->where('key', 'CREDITS_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('settings')->where('key', 'SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('settings')->where('key', 'CREDITS_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('settings')->where('key', 'SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('settings')->where('key', 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER')->update(['key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER']);
DB::table('settings')->where('key', 'SERVER_LIMIT_AFTER_IRL_PURCHASE')->update(['key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE']);
DB::table('settings')->where('key', 'FORCE_EMAIL_VERIFICATION')->update(['key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION']);
DB::table('settings')->where('key', 'FORCE_DISCORD_VERIFICATION')->update(['key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION']);
DB::table('settings')->where('key', 'REGISTER_IP_CHECK')->update(['key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK']);
DB::table('settings')->where('key', 'CREDITS_DISPLAY_NAME')->update(['key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME']);
DB::table('settings')->where('key', 'ALLOCATION_LIMIT')->update(['key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT']);
DB::table('settings')->where('key', 'SERVER_CREATE_CHARGE_FIRST_HOUR')->update(['key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR']);
DB::table('settings')->where('key', 'SALES_TAX')->update(['key' => 'SETTINGS::PAYMENTS:SALES_TAX']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::rename('settings', 'configurations');
DB::table('configurations')->where('key', 'SETTINGS::USER:INITIAL_CREDITS')->update(['key' => 'INITIAL_CREDITS']);
DB::table('configurations')->where('key', 'SETTINGS::USER:INITIAL_SERVER_LIMIT')->update(['key' => 'INITIAL_SERVER_LIMIT']);
DB::table('configurations')->where('key', 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'CREDITS_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('configurations')->where('key', 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL')->update(['key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL']);
DB::table('configurations')->where('key', 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'CREDITS_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('configurations')->where('key', 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD')->update(['key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD']);
DB::table('configurations')->where('key', 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER')->update(['key' => 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER']);
DB::table('configurations')->where('key', 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')->update(['key' => 'SERVER_LIMIT_AFTER_IRL_PURCHASE']);
DB::table('configurations')->where('key', 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION')->update(['key' => 'FORCE_EMAIL_VERIFICATION']);
DB::table('configurations')->where('key', 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION')->update(['key' => 'FORCE_DISCORD_VERIFICATION']);
DB::table('configurations')->where('key', 'SETTINGS::SYSTEM:REGISTER_IP_CHECK')->update(['key' => 'REGISTER_IP_CHECK']);
DB::table('configurations')->where('key', 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR')->update(['key' => 'SERVER_CREATE_CHARGE_FIRST_HOUR']);
DB::table('configurations')->where('key', 'SETTINGS::SERVER:ALLOCATION_LIMIT')->update(['key' => 'ALLOCATION_LIMIT']);
DB::table('configurations')->where('key', 'SETTINGS::SERVER:CREDITS_DISPLAY_NAME')->update(['key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME']);
DB::table('configurations')->where('key', 'SETTINGS::PAYMENTS:SALES_TAX')->update(['key' => 'SALES_TAX']);
}
}

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class UpdateSettingsTableAllowNullable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
//allow value column in settings table to be nullable
Schema::table('settings', function (Blueprint $table) {
$table->string('value')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//disallow value column in settings table to be nullable
Schema::table('settings', function (Blueprint $table) {
$table->string('value')->nullable(false)->change();
});
}
}

View file

@ -2,7 +2,7 @@
namespace Database\Seeders;
use Database\Seeders\Seeds\ConfigurationSeeder;
use Database\Seeders\Seeds\SettingsSeeder;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
@ -15,7 +15,7 @@ class DatabaseSeeder extends Seeder
public function run()
{
$this->call([
ConfigurationSeeder::class,
SettingsSeeder::class,
]);
}

View file

@ -3,7 +3,7 @@
namespace Database\Seeders;
use Database\Seeders\Seeds\ProductSeeder;
use Database\Seeders\Seeds\PaypalProductSeeder;
use Database\Seeders\Seeds\CreditProductSeeder;
use Database\Seeders\Seeds\ApplicationApiSeeder;
use Database\Seeders\Seeds\UsefulLinksSeeder;
use Illuminate\Database\Seeder;
@ -19,7 +19,7 @@ class ExampleItemsSeeder extends Seeder
{
$this->call([
ProductSeeder::class,
PaypalProductSeeder::class,
CreditProductSeeder::class,
ApplicationApiSeeder::class,
UsefulLinksSeeder::class
]);

View file

@ -1,149 +0,0 @@
<?php
namespace Database\Seeders\Seeds;
use App\Models\Configuration;
use Illuminate\Database\Seeder;
class ConfigurationSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//initials
Configuration::firstOrCreate([
'key' => 'INITIAL_CREDITS',
], [
'value' => '250',
'type' => 'integer',
'description' => 'The initial amount of credits the user starts with.'
]);
Configuration::firstOrCreate([
'key' => 'INITIAL_SERVER_LIMIT',
], [
'value' => '1',
'type' => 'integer',
'description' => 'The initial server limit the user starts with.'
]);
//verify email event
Configuration::firstOrCreate([
'key' => 'CREDITS_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '250',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their email account.'
]);
Configuration::firstOrCreate([
'key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their email account.'
]);
//verify discord event
Configuration::firstOrCreate([
'key' => 'CREDITS_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '375',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their discord account.'
]);
Configuration::firstOrCreate([
'key' => 'SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their discord account.'
]);
//other
Configuration::firstOrCreate([
'key' => 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
], [
'value' => '50',
'type' => 'integer',
'description' => 'The minimum amount of credits the user would need to make a server.'
]);
//purchasing
Configuration::firstOrCreate([
'key' => 'SERVER_LIMIT_AFTER_IRL_PURCHASE',
], [
'value' => '10',
'type' => 'integer',
'description' => 'updates the users server limit to this amount (unless the user already has a higher server limit) after making a purchase with real money, set to 0 to ignore this.',
]);
//force email and discord verification
Configuration::firstOrCreate([
'key' => 'FORCE_EMAIL_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to verify the email adress before creating a server / buying credits.'
]);
Configuration::firstOrCreate([
'key' => 'FORCE_DISCORD_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to link an Discord Account before creating a server / buying credits.'
]);
//disable ip check on register
Configuration::firstOrCreate([
'key' => 'REGISTER_IP_CHECK',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Prevent users from making multiple accounts using the same IP address'
]);
//per_page on allocations request
Configuration::firstOrCreate([
'key' => 'ALLOCATION_LIMIT',
], [
'value' => '200',
'type' => 'integer',
'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!'
]);
//credits display name
Configuration::firstOrCreate([
'key' => 'CREDITS_DISPLAY_NAME',
], [
'value' => 'Credits',
'type' => 'string',
'description' => 'Set the display name of your currency :)'
]);
//credits display name
Configuration::firstOrCreate([
'key' => 'SERVER_CREATE_CHARGE_FIRST_HOUR',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Charges the first hour worth of credits upon creating a server.'
]);
//sales tax
Configuration::firstOrCreate([
'key' => 'SALES_TAX',
], [
'value' => '0',
'type' => 'integer',
'description' => 'The %-value of tax that will be added to the product price on checkout'
]);
}
}

View file

@ -2,10 +2,10 @@
namespace Database\Seeders\Seeds;
use App\Models\PaypalProduct;
use App\Models\CreditProduct;
use Illuminate\Database\Seeder;
class PaypalProductSeeder extends Seeder
class CreditProductSeeder extends Seeder
{
/**
* Run the database seeds.
@ -14,7 +14,7 @@ class PaypalProductSeeder extends Seeder
*/
public function run()
{
PaypalProduct::create([
CreditProduct::create([
'type' => 'Credits',
'display' => '350',
'description' => 'Adds 350 credits to your account',
@ -24,7 +24,7 @@ class PaypalProductSeeder extends Seeder
'disabled' => false,
]);
PaypalProduct::create([
CreditProduct::create([
'type' => 'Credits',
'display' => '875 + 125',
'description' => 'Adds 1000 credits to your account',
@ -34,7 +34,7 @@ class PaypalProductSeeder extends Seeder
'disabled' => false,
]);
PaypalProduct::create([
CreditProduct::create([
'type' => 'Credits',
'display' => '1750 + 250',
'description' => 'Adds 2000 credits to your account',
@ -44,7 +44,7 @@ class PaypalProductSeeder extends Seeder
'disabled' => false,
]);
PaypalProduct::create([
CreditProduct::create([
'type' => 'Credits',
'display' => '3500 + 500',
'description' => 'Adds 4000 credits to your account',

View file

@ -0,0 +1,469 @@
<?php
namespace Database\Seeders\Seeds;
use App\Models\Settings;
use Illuminate\Database\Seeder;
class SettingsSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
//initials
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:INITIAL_CREDITS',
], [
'value' => '250',
'type' => 'integer',
'description' => 'The initial amount of credits the user starts with.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:NITIAL_SERVER_LIMIT',
], [
'value' => '1',
'type' => 'integer',
'description' => 'The initial server limit the user starts with.'
]);
//verify email event
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '250',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their email account.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_EMAIL',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their email account.'
]);
//verify discord event
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:CREDITS_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '375',
'type' => 'integer',
'description' => 'Increase in credits after the user has verified their discord account.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:SERVER_LIMIT_REWARD_AFTER_VERIFY_DISCORD',
], [
'value' => '2',
'type' => 'integer',
'description' => 'Increase in server limit after the user has verified their discord account.'
]);
//other
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER',
], [
'value' => '50',
'type' => 'integer',
'description' => 'The minimum amount of credits the user would need to make a server.'
]);
//purchasing
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE',
], [
'value' => '10',
'type' => 'integer',
'description' => 'updates the users server limit to this amount (unless the user already has a higher server limit) after making a purchase with real money, set to 0 to ignore this.',
]);
//force email and discord verification
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:FORCE_EMAIL_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to verify the email adress before creating a server / buying credits.'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::USER:FORCE_DISCORD_VERIFICATION',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Force an user to link an Discord Account before creating a server / buying credits.'
]);
//disable ip check on register
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:REGISTER_IP_CHECK',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Prevent users from making multiple accounts using the same IP address'
]);
//per_page on allocations request
Settings::firstOrCreate([
'key' => 'SETTINGS::SERVER:ALLOCATION_LIMIT',
], [
'value' => '200',
'type' => 'integer',
'description' => 'The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!'
]);
//credits display name
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME',
], [
'value' => 'Credits',
'type' => 'string',
'description' => 'Set the display name of your currency :)'
]);
//credits display name
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:SERVER_CREATE_CHARGE_FIRST_HOUR',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Charges the first hour worth of credits upon creating a server.'
]);
//sales tax
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:SALES_TAX',
], [
'value' => '0',
'type' => 'integer',
'description' => 'The %-value of tax that will be added to the product price on checkout'
]);
//Invoices enabled
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:ENABLED',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'Enables or disables the invoice feature for payments'
]);
//Invoice company name
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_NAME',
], [
'value' => '',
'type' => 'string',
'description' => 'The name of the Company on the Invoices'
]);
//Invoice company address
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_ADDRESS',
], [
'value' => '',
'type' => 'string',
'description' => 'The address of the Company on the Invoices'
]);
//Invoice company phone
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_PHONE',
], [
'value' => '',
'type' => 'string',
'description' => 'The phone number of the Company on the Invoices'
]);
//Invoice company mail
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_MAIL',
], [
'value' => '',
'type' => 'string',
'description' => 'The email address of the Company on the Invoices'
]);
//Invoice VAT
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_VAT',
], [
'value' => '',
'type' => 'string',
'description' => 'The VAT-Number of the Company on the Invoices'
]);
//Invoice Website
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:COMPANY_WEBSITE',
], [
'value' => '',
'type' => 'string',
'description' => 'The Website of the Company on the Invoices'
]);
//Invoice Website
Settings::firstOrCreate([
'key' => 'SETTINGS::INVOICE:PREFIX',
], [
'value' => 'INV',
'type' => 'string',
'description' => 'The invoice prefix'
]);
//Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:DEFAULT',
], [
'value' => 'en',
'type' => 'string',
'description' => 'The default Language the dashboard will be shown in'
]);
//Dynamic locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:DYNAMIC',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'If this is true, the Language will change to the Clients browserlanguage or default.'
]);
//User can change Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:CLIENTS_CAN_CHANGE',
], [
'value' => 'false',
'type' => 'boolean',
'description' => 'If this is true, the clients will be able to change their Locale.'
]);
//Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:AVAILABLE',
], [
'value' => '',
'type' => 'string',
'description' => 'The available languages'
]);
//Locale
Settings::firstOrCreate([
'key' => 'SETTINGS::LOCALE:DATATABLES',
], [
'value' => 'en-gb',
'type' => 'string',
'description' => 'The Language of the Datatables. Grab the Language-Codes from here https://datatables.net/plug-ins/i18n/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SECRET',
], [
'value' => env('PAYPAL_SECRET', ''),
'type' => 'string',
'description' => 'Your PayPal Secret-Key ( https://developer.paypal.com/docs/integration/direct/rest/)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID',
], [
'value' => env('PAYPAL_CLIENT_ID', ''),
'type' => 'string',
'description' => 'Your PayPal Client_ID'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET',
], [
'value' => env('PAYPAL_SANDBOX_SECRET', ''),
'type' => 'string',
'description' => 'Your PayPal SANDBOX Secret-Key used for testing '
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID',
], [
'value' => env('PAYPAL_SANDBOX_CLIENT_ID', ''),
'type' => 'string',
'description' => 'Your PayPal SANDBOX Client-ID used for testing '
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:SECRET',
], [
'value' => env('STRIPE_SECRET', ''),
'type' => 'string',
'description' => 'Your Stripe Secret-Key ( https://dashboard.stripe.com/account/apikeys )'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET',
], [
'value' => env('STRIPE_ENDPOINT_SECRET', ''),
'type' => 'string',
'description' => 'Your Stripe endpoint secret-key'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:TEST_SECRET',
], [
'value' => env('STRIPE_TEST_SECRET', ''),
'type' => 'string',
'description' => 'Your Stripe test secret-key'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET',
], [
'value' => env('STRIPE_ENDPOINT_TEST_SECRET', ''),
'type' => 'string',
'description' => 'Your Stripe endpoint test secret-key'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::PAYMENTS:STRIPE:METHODS',
], [
'value' => env('STRIPE_METHODS', 'card,sepa_debit'),
'type' => 'string',
'description' => 'Comma seperated list of payment methods that are enabled (https://stripe.com/docs/payments/payment-methods/integration-options)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:CLIENT_ID',
], [
'value' => env('DISCORD_CLIENT_ID', ''),
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:CLIENT_SECRET',
], [
'value' => env('DISCORD_CLIENT_SECRET', ''),
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:BOT_TOKEN',
], [
'value' => env('DISCORD_BOT_TOKEN', ''),
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:GUILD_ID',
], [
'value' => env('DISCORD_GUILD_ID', ''),
'type' => 'string',
'description' => 'Discord API Credentials - https://discordapp.com/developers/applications/'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:ROLE_ID',
], [
'value' => env('DISCORD_ROLE_ID', ''),
'type' => 'string',
'description' => 'Discord role that will be assigned to users when they register'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::DISCORD:INVITE_URL',
], [
'value' => env('DISCORD_INVITE_URL', ''),
'type' => 'string',
'description' => 'The invite URL to your Discord Server'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN',
], [
'value' => env('PTERODACTYL_TOKEN', ''),
'type' => 'string',
'description' => 'Admin API Token from Pterodactyl Panel - necessary for the Panel to work. The Key needs all read&write permissions!'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::SYSTEM:PTERODACTYL:URL',
], [
'value' => env('PTERODACTYL_URL', ''),
'type' => 'string',
'description' => 'The URL to your Pterodactyl Panel. Must not end with a / '
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MISC:PHPMYADMIN:URL',
], [
'value' => env('PHPMYADMIN_URL', ''),
'type' => 'string',
'description' => 'The URL to your PHPMYADMIN Panel. Must not end with a /, remove to remove database button'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::RECAPTCHA:SITE_KEY',
], [
'value' => env('RECAPTCHA_SITE_KEY', '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'),
'type' => 'string',
'description' => 'Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::RECAPTCHA:SECRET_KEY',
], [
'value' => env('RECAPTCHA_SECRET_KEY', '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe'),
'type' => 'string',
'description' => 'Google Recaptcha API Credentials - https://www.google.com/recaptcha/admin - reCaptcha V2 (not v3)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::RECAPTCHA:ENABLED',
], [
'value' => 'true',
'type' => 'boolean',
'description' => 'Enables or disables the ReCaptcha feature on the registration/login page'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:MAILER',
], [
'value' => env('MAIL_MAILER', 'smtp'),
'type' => 'string',
'description' => 'Selected Mailer (smtp, mailgun, sendgrid, mailtrap)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:HOST',
], [
'value' => env('MAIL_HOST', 'localhost'),
'type' => 'string',
'description' => 'Mailer Host Adress'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:PORT',
], [
'value' => env('MAIL_PORT', '25'),
'type' => 'string',
'description' => 'Mailer Server Port'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:USERNAME',
], [
'value' => env('MAIL_USERNAME', ''),
'type' => 'string',
'description' => 'Mailer Username'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:PASSWORD',
], [
'value' => env('MAIL_PASSWORD', ''),
'type' => 'string',
'description' => 'Mailer Password'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:ENCRYPTION',
], [
'value' => env('MAIL_ENCRYPTION', 'tls'),
'type' => 'string',
'description' => 'Mailer Encryption (tls, ssl)'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:FROM_ADDRESS',
], [
'value' => env('MAIL_FROM_ADDRESS', ''),
'type' => 'string',
'description' => 'Mailer From Address'
]);
Settings::firstOrCreate([
'key' => 'SETTINGS::MAIL:FROM_NAME',
], [
'value' => env('APP_NAME', 'Controlpanel'),
'type' => 'string',
'description' => 'Mailer From Name'
]);
}
}

2
package-lock.json generated
View file

@ -1,5 +1,5 @@
{
"name": "bitsec-dashboard",
"name": "controllpanelgg",
"lockfileVersion": 2,
"requires": true,
"packages": {

29
public/css/app.css vendored

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

48
public/install/dotenv.php Normal file
View file

@ -0,0 +1,48 @@
<?php
namespace DevCoder;
class DotEnv
{
/**
* The directory where the .env file can be located.
*
* @var string
*/
protected $path;
public function __construct(string $path)
{
if (!file_exists($path)) {
throw new \InvalidArgumentException(sprintf('%s does not exist', $path));
}
$this->path = $path;
}
public function load(): void
{
if (!is_readable($this->path)) {
throw new \RuntimeException(sprintf('%s file is not readable', $this->path));
}
$lines = file($this->path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
if (strpos(trim($line), '#') === 0) {
continue;
}
list($name, $value) = explode('=', $line, 2);
$name = trim($name);
$value = trim($value);
if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) {
putenv(sprintf('%s=%s', $name, $value));
$_ENV[$name] = $value;
$_SERVER[$name] = $value;
}
}
}
}

281
public/install/forms.php Normal file
View file

@ -0,0 +1,281 @@
<?php
use DevCoder\DotEnv;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
require 'dotenv.php';
require 'phpmailer/Exception.php';
require 'phpmailer/PHPMailer.php';
require 'phpmailer/SMTP.php';
(new DotEnv(dirname(__FILE__, 3) . "/.env"))->load();
include("functions.php");
if (isset($_POST['checkDB'])) {
$values = [
//SETTINGS::VALUE => REQUEST-VALUE (coming from the html-form)
"DB_HOST" => "databasehost",
"DB_DATABASE" => "database",
"DB_USERNAME" => "databaseuser",
"DB_PASSWORD" => "databaseuserpass",
"DB_PORT" => "databaseport",
"DB_CONNECTION" => "databasedriver"
];
$db = new mysqli($_POST["databasehost"], $_POST["databaseuser"], $_POST["databaseuserpass"], $_POST["database"], $_POST["databaseport"]);
if ($db->connect_error) {
header("LOCATION: index.php?step=2&message=Could not connect to the Database");
die();
}
foreach ($values as $key => $value) {
$param = $_POST[$value];
# if ($key == "DB_PASSWORD") {
# $param = '"' . $_POST[$value] . '"';
# }
setEnvironmentValue($key, $param);
}
header("LOCATION: index.php?step=2.5");
}
if (isset($_POST['checkGeneral'])) {
$appname = '"' . $_POST['name'] . '"';
$appurl = $_POST['url'];
if (substr($appurl, -1) === "/") {
$appurl = substr_replace($appurl, "", -1);
}
setEnvironmentValue("APP_NAME", $appname);
setEnvironmentValue("APP_URL", $url);
header("LOCATION: index.php?step=4");
}
if (isset($_POST['feedDB'])) {
$logs = "";
#$logs .= run_console(putenv('COMPOSER_HOME=' . dirname(__FILE__, 3) . '/vendor/bin/composer'));
#$logs .= run_console('composer install --no-dev --optimize-autoloader');
$logs .= run_console('php artisan migrate --seed --force');
$logs .= run_console('php artisan db:seed --class=ExampleItemsSeeder --force');
$logs .= run_console('php artisan key:generate --force');
$logs .= run_console('php artisan storage:link');
$logsfile = fopen("logs.txt", "w") or die("Unable to open file!");
fwrite($logsfile, $logs);
fclose($logsfile);
if (strpos(getEnvironmentValue("APP_KEY"), 'base64') !== false) {
header("LOCATION: index.php?step=3");
} else {
header("LOCATION: index.php?step=2.5&message=There was an error. Please check install/logs.txt !");
}
}
if (isset($_POST['checkSMTP'])) {
try {
$mail = new PHPMailer(true);
//Server settings
$mail->isSMTP(); // Send using SMTP
$mail->Host = $_POST['host']; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = $_POST['user']; // SMTP username
$mail->Password = $_POST['pass']; // SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
$mail->Port = $_POST['port']; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS`
//Recipients
$mail->setFrom($_POST['user'], $_POST['user']);
$mail->addAddress($_POST['user'], $_POST['user']); // Add a recipient
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'It Worked!';
$mail->Body = "Your E-Mail Settings are correct!";
$mail->send();
} catch (Exception $e) {
header("LOCATION: index.php?step=4&message=Something wasnt right when sending the E-Mail!");
die();
}
$db = new mysqli(getEnvironmentValue("DB_HOST"), getEnvironmentValue("DB_USERNAME"), getEnvironmentValue("DB_PASSWORD"), getEnvironmentValue("DB_DATABASE"), getEnvironmentValue("DB_PORT"));
if ($db->connect_error) {
header("LOCATION: index.php?step=4&message=Could not connect to the Database");
die();
}
$values = [
"SETTINGS::MAIL:MAILER" => $_POST["method"],
"SETTINGS::MAIL:HOST" => $_POST["host"],
"SETTINGS::MAIL:PORT" => $_POST["port"],
"SETTINGS::MAIL:USERNAME" => $_POST["user"],
"SETTINGS::MAIL:PASSWORD" => $_POST["pass"],
"SETTINGS::MAIL:ENCRYPTION" => $_POST["encryption"],
"SETTINGS::MAIL:FROM_ADDRESS" => $_POST["user"]
];
foreach ($values as $key => $value) {
$query = "UPDATE `" . getEnvironmentValue("DB_DATABASE") . "`.`settings` SET `value` = '$value' WHERE (`key` = '$key')";
$db->query($query);
}
header("LOCATION: index.php?step=5");
}
if (isset($_POST['checkPtero'])) {
$url = $_POST['url'];
$key = $_POST['key'];
if (substr($url, -1) === "/") {
$url = substr_replace($url, "", -1);
}
$pteroURL = $url . "/api/application/users";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $pteroURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Accept: application/json",
"Content-Type: application/json",
"Authorization: Bearer " . $key
));
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch); // Close the connection
if (!is_array($result) or in_array($result["errors"][0]["code"], $result)) {
header("LOCATION: index.php?step=5&message=Couldnt connect to Pterodactyl. Make sure your API key has all read and write permissions!");
die();
} else {
$query1 = "UPDATE `" . getEnvironmentValue("DB_DATABASE") . "`.`settings` SET `value` = '$url' WHERE (`key` = 'SETTINGS::SYSTEM:PTERODACTYL:URL')";
$query2 = "UPDATE `" . getEnvironmentValue("DB_DATABASE") . "`.`settings` SET `value` = '$key' WHERE (`key` = 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN')";
$db = new mysqli(getEnvironmentValue("DB_HOST"), getEnvironmentValue("DB_USERNAME"), getEnvironmentValue("DB_PASSWORD"), getEnvironmentValue("DB_DATABASE"), getEnvironmentValue("DB_PORT"));
if ($db->connect_error) {
header("LOCATION: index.php?step=5&message=Could not connect to the Database");
die();
}
if ($db->query($query1) && $db->query($query2)) {
header("LOCATION: index.php?step=6");
} else {
header("LOCATION: index.php?step=5&message=Something went wrong when communicating with the Database!");
}
}
}
if (isset($_POST['createUser'])) {
$db = new mysqli(getEnvironmentValue("DB_HOST"), getEnvironmentValue("DB_USERNAME"), getEnvironmentValue("DB_PASSWORD"), getEnvironmentValue("DB_DATABASE"), getEnvironmentValue("DB_PORT"));
if ($db->connect_error) {
header("LOCATION: index.php?step=6&message=Could not connect to the Database");
die();
}
$name = $_POST['user'];
$mail = $_POST['email'];
$pteroID = $_POST['pteroID'];
$pass = $_POST['pass'];
$repass = $_POST['repass'];
$key = $db->query("SELECT `value` FROM `" . getEnvironmentValue("DB_DATABASE") . "`.`settings` WHERE `key` = 'SETTINGS::SYSTEM:PTERODACTYL:TOKEN'")->fetch_assoc();
$pterobaseurl = $db->query("SELECT `value` FROM `" . getEnvironmentValue("DB_DATABASE") . "`.`settings` WHERE `key` = 'SETTINGS::SYSTEM:PTERODACTYL:URL'")->fetch_assoc();
$pteroURL = $pterobaseurl["value"] . "/api/application/users/" . $pteroID;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $pteroURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Accept: application/json",
"Content-Type: application/json",
"Authorization: Bearer " . $key["value"]
));
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch); // Close the connection
if ($result["attributes"]["email"] !== $mail) {
header("LOCATION: index.php?step=6&message=The Email is not the same as the one used on Pterodactyl");
die();
}
if ($pass !== $repass) {
header("LOCATION: index.php?step=6&message=The Passwords did not match!");
die();
}
$pass = password_hash($pass, PASSWORD_DEFAULT);
$pteroURL = $pterobaseurl["value"] . "/api/application/users/" . $pteroID;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $pteroURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Accept: application/json",
"Content-Type: application/json",
"Authorization: Bearer " . $key["value"]
));
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
"email" => $mail,
"username" => $name,
"first_name" => $name,
"last_name" => $name,
"password" => $pass
));
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch); // Close the connection
if (!is_array($result) or in_array($result["errors"][0]["code"], $result)) {
header("LOCATION: index.php?step=5&message=Couldnt connect to Pterodactyl. Make sure your API key has all read and write permissions!");
die();
}
$query1 = "INSERT INTO `" . getEnvironmentValue("DB_DATABASE") . "`.`users` (`name`, `role`, `credits`, `server_limit`, `pterodactyl_id`, `email`, `password`, `created_at`) VALUES ('$name', 'admin', '250', '1', '$pteroID', '$mail', '$pass', CURRENT_TIMESTAMP)";
if ($db->query($query1)) {
header("LOCATION: index.php?step=7");
} else {
header("LOCATION: index.php?step=6&message=Something went wrong when communicating with the Database!");
}
}
?>

View file

@ -0,0 +1,133 @@
<?php
$required_extentions = array("openssl", "gd", "mysql", "PDO", "mbstring", "tokenizer", "bcmath", "xml", "curl", "zip", "fpm");
$requirements = [
"php" => "7.4",
"mysql" => "5.7.22",
];
function checkPhpVersion()
{
global $requirements;
if (version_compare(phpversion(), $requirements["php"], '>=')) {
return "OK";
}
return "not OK";
}
function checkWriteable()
{
return is_writable("../../.env");
}
function checkHTTPS()
{
return
(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| $_SERVER['SERVER_PORT'] == 443;
}
function getMySQLVersion()
{
global $requirements;
$output = shell_exec('mysql -V');
preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
$versionoutput = $version[0] ?? "0";
return (intval($versionoutput) > intval($requirements["mysql"]) ? "OK" : $versionoutput);
}
function getZipVersion()
{
$output = shell_exec('zip -v');
preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
$versionoutput = $version[0] ?? 0;
return ($versionoutput != 0 ? "OK" : "not OK");
}
function getGitVersion()
{
$output = shell_exec('git --version');
preg_match('@[0-9]+\.[0-9]+\.[0-9]+@', $output, $version);
$versionoutput = $version[0] ?? 0;
return ($versionoutput != 0 ? "OK" : "not OK");
}
function getTarVersion()
{
$output = shell_exec('tar --version');
preg_match('@[0-9]+\.[0-9]+@', $output, $version);
$versionoutput = $version[0] ?? 0;
return ($versionoutput != 0 ? "OK" : "not OK");
}
function checkExtensions()
{
global $required_extentions;
$not_ok = [];
$extentions = get_loaded_extensions();
foreach ($required_extentions as $ext) {
if (!preg_grep("/^(?=.*" . $ext . ").*$/", $extentions))
array_push($not_ok, $ext);
}
return $not_ok;
}
function setEnvironmentValue($envKey, $envValue)
{
$envFile = dirname(__FILE__, 3) . "/.env";
$str = file_get_contents($envFile);
$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
$str = substr($str, 0, -1);
$fp = fopen($envFile, 'w');
fwrite($fp, $str);
fclose($fp);
}
function getEnvironmentValue($envKey)
{
$envFile = dirname(__FILE__, 3) . "/.env";
$str = file_get_contents($envFile);
$str .= "\n"; // In case the searched variable is in the last line without \n
$keyPosition = strpos($str, "{$envKey}=");
$endOfLinePosition = strpos($str, PHP_EOL, $keyPosition);
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
$value = substr($oldLine, strpos($oldLine, "=") + 1);
return $value;
}
function run_console($command)
{
$path = dirname(__FILE__, 3);
$cmd = "cd '$path' && bash -c 'exec -a ServerCPP $command' 2>&1";
return shell_exec($cmd);
}
?>

486
public/install/index.php Normal file
View file

@ -0,0 +1,486 @@
<?php
include("functions.php");
if (file_exists("../../install.lock")) {
die("The installation has been completed already. Please delete the File 'install.lock' to re-run");
}
?>
<html>
<head>
<title>Controlpanel.gg installer Script</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
body {
background-color: powderblue;
}
.card {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
.ok {
color: green;
}
.ok::before {
content: "✔️";
}
.notok {
color: red;
}
.notok::before {
content: "";
}
</style>
</head>
<body>
<?php
$cardheader = '
<div class="card card-outline-success bg-dark">
<div class="card-header text-center">
<b class="mr-1 text-light">Controlpanel.GG</b>
</div>
<div class="card-body bg-light">';
if (!isset($_GET['step'])) {
if (!file_exists("../../.env")) {
echo run_console('cp .env.example .env');
}
echo $cardheader;
?>
<p class="login-box-msg">This installer will lead you through the most crucial Steps of Controlpanel.gg`s
setup</p>
<p class="<?php print(checkHTTPS() == true ? "ok" : "notok"); ?>">HTTPS is required</p>
<p class="<?php print(checkWriteable() == true ? "ok" : "notok"); ?>">Write-permissions on .env-file</p>
<p class="<?php print(checkPhpVersion() === "OK" ? "ok" : "notok"); ?>"> php
version: <?php echo phpversion(); ?> (required <?php echo $requirements["php"]; ?>)</p>
<p class="<?php print(getMySQLVersion() === "OK" ? "ok" : "notok"); ?>"> mysql
version: <?php echo getMySQLVersion(); ?> (minimum required <?php echo $requirements["mysql"]; ?>)</p>
<p class="<?php print(sizeof(checkExtensions()) == 0 ? "ok" : "notok"); ?>"> Missing
php-extentions: <?php print(sizeof(checkExtensions()) == 0 ? "none" : "");
foreach (checkExtensions() as $ext) {
echo $ext . ", ";
}
print(sizeof(checkExtensions()) == 0 ? "" : "(Proceed anyway)"); ?></p>
<!-- <p class="<?php print(getZipVersion() === "OK" ? "ok" : "notok"); ?>"> Zip
version: <?php echo getZipVersion(); ?> </p> -->
<p class="<?php print(getGitVersion() === "OK" ? "ok" : "notok"); ?>"> Git
version: <?php echo getGitVersion(); ?> </p>
<p class="<?php print(getTarVersion() === "OK" ? "ok" : "notok"); ?>"> Tar
version: <?php echo getTarVersion(); ?> </p>
<a href="?step=2">
<button class="btn btn-primary">Lets go</button>
</a>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 2) {
echo $cardheader;
?>
<p class="login-box-msg">Lets start with your Database</p>
<?php if (isset($_GET['message'])) {
echo "<p class='notok'>" . $_GET['message'] . "</p>";
}
?>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="/install/forms.php" name="checkDB">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="custom-control mb-3">
<label for="database">Database Driver</label>
<input x-model="databasedriver" id="databasedriver" name="databasedriver"
type="text" required
value="mysql" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="databasehost">Database Host</label>
<input x-model="databasehost" id="databasehost" name="databasehost" type="text"
required
value="127.0.0.1" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="databaseport">Database Port</label>
<input x-model="databaseport" id="databaseport" name="databaseport"
type="number" required
value="3306" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="databaseuser">Database User</label>
<input x-model="databaseuser" id="databaseuser" name="databaseuser" type="text"
required
value="dashboarduser" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="databaseuserpass">Database User Password</label>
<input x-model="databaseuserpass" id="databaseuserpass" name="databaseuserpass"
type="text" required
class="form-control ">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="database">Database</label>
<input x-model="database" id="database" name="database" type="text" required
value="dashboard" class="form-control">
</div>
</div>
</div>
<button class="btn btn-primary" name="checkDB">Submit</button>
</div>
</form>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 2.5) {
echo $cardheader;
?>
<p class="login-box-msg">Lets feed your Database and generate some security keys!</p>
<p> This process might take a while. Please do not refresh or close this page!</p>
<?php if (isset($_GET['message'])) {
echo "<p class='notok'>" . $_GET['message'] . "</p>";
}
?>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="/install/forms.php" name="feedDB">
<button class="btn btn-primary" name="feedDB">Submit</button>
</div>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 3) {
echo $cardheader;
?>
<p class="login-box-msg">Tell us something about your Host</p>
<?php if (isset($_GET['message'])) {
echo "<p class='notok'>" . $_GET['message'] . "</p>";
}
?>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="/install/forms.php" name="checkGeneral">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="custom-control mb-3">
<label for="database">Your Dashboard URL</label>
<input id="url" name="url"
type="text" required
value="<?php echo "https://" . $_SERVER['SERVER_NAME']; ?>" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="name">Your Host-Name</label>
<input id="name" name="name" type="text"
required
value="Controlpanel.gg" class="form-control">
</div>
</div>
</div>
<button class="btn btn-primary" name="checkGeneral">Submit</button>
</div>
</form>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 4) {
echo $cardheader;
?>
<p class="login-box-msg">Lets get your E-Mails going! </p>
<p class="login-box-msg">This might take a few seconds when submitted! </p>
<?php if (isset($_GET['message'])) {
echo "<p class='notok'>" . $_GET['message'] . "</p>";
}
?>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="/install/forms.php" name="checkSMTP">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="custom-control mb-3">
<label for="method">Your E-Mail method</label>
<input id="method" name="method"
type="text" required
value="smtp" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="host">Your Mailer-Host</label>
<input id="host" name="host" type="text"
required
value="smtp.google.com" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="port">Your Mail Port</label>
<input id="port" name="port" type="port"
required
value="567" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="user">Your Mail User</label>
<input id="user" name="user" type="text"
required
value="info@mydomain.com" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="pass">Your Mail-User Password</label>
<input id="pass" name="pass" type="password"
required
value="" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="encryption">Your Mail encryption method</label>
<input id="encryption" name="encryption" type="text"
required
value="tls" class="form-control">
</div>
</div>
</div>
<button class="btn btn-primary" name="checkSMTP">Submit</button>
</form>
</div>
<a href="?step=5"><button class="btn btn-warning">Skip this step for now</button></a>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 5) {
echo $cardheader;
?>
<p class="login-box-msg">Almost done! </p>
<p class="login-box-msg">Lets get some info about your Pterodactyl Installation!</p>
<?php if (isset($_GET['message'])) {
echo "<p class='notok'>" . $_GET['message'] . "</p>";
}
?>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="/install/forms.php" name="checkPtero">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="custom-control mb-3">
<label for="url">Pterodactyl URL</label>
<input id="url" name="url"
type="text" required
value="https://ptero.example.com" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="key">Pterodactyl API-Key</label>
<input id="key" name="key" type="text"
required
value="" class="form-control"
placeholder="The Key needs ALL read&write Permissions!">
</div>
</div>
</div>
<button class="btn btn-primary" name="checkPtero">Submit</button>
</div>
</form>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 6) {
echo $cardheader;
?>
<p class="login-box-msg">Lets create yourself!</p>
<p class="login-box-msg">We're making the first Admin user</p>
<?php if (isset($_GET['message'])) {
echo "<p class='notok'>" . $_GET['message'] . "</p>";
}
?>
<form method="POST" enctype="multipart/form-data" class="mb-3"
action="/install/forms.php" name="createUser">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="custom-control mb-3">
<label for="user">Your Username</label>
<input id="user" name="user"
type="text" required
value="" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="email">Your Email Adress (used to Login)</label>
<input id="email" name="email"
type="text" required
value="" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="pass">Password</label>
<input id="pass" name="pass" type="password"
required
value="" minlength="8" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="repass">Retype Password</label>
<input id="repass" name="repass" type="password"
required
value="" minlength="8" class="form-control">
</div>
</div>
<div class="form-group">
<div class="custom-control mb-3">
<label for="pteroID">Your Pterodactyl User-ID</label>
<input id="pteroID" name="pteroID" type="text"
required
value="" class="form-control">
</div>
</div>
</div>
<button class="btn btn-primary" name="createUser">Submit</button>
</div>
</form>
</div>
</div>
<?php
}
if (isset($_GET['step']) && $_GET['step'] == 7) {
$lockfile = fopen("../../install.lock", "w") or die("Unable to open file!");
fwrite($lockfile, "locked");
fclose($lockfile);
echo $cardheader;
?>
<p class="login-box-msg">All done!</p>
<p class="login-box-msg">You may navigate to your Dashboard now and log in!</p>
<a href="<?php echo "https://" . $_SERVER['SERVER_NAME']; ?>">
<button class="btn btn-success">Lets go!</button>
</a>
</div>
</div>
<?php
}
?>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
</body>
</html>

View file

@ -0,0 +1,40 @@
<?php
/**
* PHPMailer Exception class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer exception handler.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/
class Exception extends \Exception
{
/**
* Prettify error message output.
*
* @return string
*/
public function errorMessage()
{
return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n";
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

569
public/js/app.js vendored

File diff suppressed because one or more lines are too long

354
resources/lang/cs.json Normal file
View file

@ -0,0 +1,354 @@
{
"api key created!": "api klíč vygenerován!",
"api key updated!": "api klíč aktualizován!",
"api key has been removed!": "api klíč byl odstraněn!",
"Edit": "Upravit",
"Delete": "Smazat",
"configuration has been updated!": "konfigurace byla aktualizována!",
"Store item has been created!": "Balíček dokoupení kreditů byl vytvořen!",
"Store item has been updated!": "Balíček dokoupení kreditů byl aktualizován!",
"Product has been updated!": "Balíček byl aktualizován!",
"Store item has been removed!": "Balíček dokoupení kreditů byl odstraněn!",
"unknown": "neznámý",
"Pterodactyl synced": "Pterodactyl synchronizován",
"Your credit balance has been increased!": "Kredity byly připsány!",
"Your payment is being processed!": "Vaše platba se nyní zpracovává!",
"Your payment has been canceled!": "Vaše platba byla zrušena!",
"Payment method": "Platební metoda",
"Invoice": "Faktura",
"Product has been created!": "Balíček byl vytvořen!",
"Product has been removed!": "Balíček byl odstraněn!",
"Show": "Zobrazit",
"Clone": "Duplikovat",
"Server removed": "Server byl odstraněn",
"An exception has occurred while trying to remove a resource \"": "Nastala chyba při odstraňování balíčku",
"Server has been updated!": "Server byl aktualizován!",
"Unsuspend": "Zrušit pozastavení",
"Suspend": "Pozastavit",
"Icons updated!": "Ikony byly aktualizovány!",
"link has been created!": "užitečný odkaz byl úspěšně vytvořen!",
"link has been updated!": "užitečný odkaz byl aktualizován!",
"product has been removed!": "balíček byl odstraněn!",
"User does not exists on pterodactyl's panel": "Uživatel neexistuje na pterodactyl panelu",
"user has been removed!": "uživatel byl odstraněn!",
"Notification sent!": "Oznámení odesláno!",
"User has been updated!": "Uživatel byl aktualizován!",
"Login as User": "Přihlásit se jako uživatel",
"voucher has been created!": "poukaz byl vytvořen!",
"voucher has been updated!": "poukaz byl aktualizován!",
"voucher has been removed!": "poukaz byl odstraněn!",
"This voucher has reached the maximum amount of uses": "Tento poukaz dosáhl maximálního počtu použití",
"This voucher has expired": "Tento poukaz už není platný",
"You already redeemed this voucher code": "Tento poukaz už jste využil",
"have been added to your balance!": "bylo připsáno na váš účet!",
"Users": "Uživatelé",
"VALID": "platný",
"days": "dní",
"hours": "hodin",
"You ran out of Credits": "Došly Vám kredity",
"Profile updated": "Profil byl aktualizován",
"Server limit reached!": "Dosažen limit počtu serverů!",
"You are required to verify your email address before you can create a server.": "Pro vytvoření serveru je třeba si ověřit emailovou adresu.",
"You are required to link your discord account before you can create a server.": "Pro vytvoření serveru je třeba ověřit si discord účet.",
"Server created": "Server vytvořen",
"No allocations satisfying the requirements for automatic deployment on this node were found.": "Na vámi vybraném uzlu už nejsou žádné volné porty.",
"You are required to verify your email address before you can purchase credits.": "Pro dobití kreditu je třeba ověřit si emailovou adresu.",
"You are required to link your discord account before you can purchase Credits": "Pro dobití kreditu je třeba ověřit si discord účet",
"EXPIRED": "Po expiraci",
"Payment Confirmation": "Potvrzení Platby",
"Payment Confirmed!": "Platba proběhla v pořádku!",
"Your Payment was successful!": "Vaše platba proběhla úspěšně!",
"Hello": "Dobrý den",
"Your payment was processed successfully!": "Platba byla úspěšně zpracována!",
"Status": "Stav",
"Price": "Cena",
"Type": "Typ",
"Amount": "Množství",
"Balance": "Zůstatek",
"User ID": "ID uživatele",
"Server Creation Error": "Chyba při vytváření serveru",
"Your servers have been suspended!": "Vaše servery byly pozastaveny!",
"To automatically re-enable your server\/s, you need to purchase more credits.": "Pro opětovné spuštění vašich serverů dobijte prosím kredity.",
"Purchase credits": "Zakoupit kredity",
"If you have any questions please let us know.": "Máte-li jakékoli dotazy, dejte nám vědět.",
"Regards": "S pozdravem",
"Getting started!": "Začínáme!",
"Activity Logs": "Historie akcí",
"Dashboard": "Přehled",
"No recent activity from cronjobs": "Žádná nedávná aktivita cronjobů",
"Are cronjobs running?": "Funguje crontab?",
"Check the docs for it here": "Nápovědu naleznete zde",
"Causer": "Průvodce",
"Description": "Popis",
"Created at": "Vytvořeno",
"Application API": "API",
"Create": "Vytvořit",
"Memo": "Název",
"Submit": "Potvrdit",
"Create new": "Vytvořit nový",
"Token": "Token",
"Last used": "Naposledy použito",
"Are you sure you wish to delete?": "Opravdu si přejete odstranit?",
"Edit Configuration": "Upravit konfiguraci",
"Text Field": "Textové pole",
"Cancel": "Zrušit",
"Save": "Uložit",
"Configurations": "Konfigurace",
"Key": "Klíč",
"Value": "Hodnota",
"Nests": "Software\/hra",
"Sync": "Synchronizovat",
"Active": "Aktivní",
"ID": "ID",
"eggs": "distribuce",
"Name": "Název",
"Nodes": "Uzly",
"Location": "Umístění",
"Admin Overview": "Přehled pro správce",
"Support server": "Server podpory",
"Documentation": "Dokumentace",
"Github": "GitHub",
"Support ControlPanel": "Podpořit ControlPanel",
"Servers": "Servery",
"Total": "Celkem",
"Payments": "Platby",
"Pterodactyl": "Pterodactyl",
"Resources": "Prostředky",
"Count": "Počet",
"Locations": "Umístění",
"Eggs": "Distribuce",
"Last updated :date": "Naposledy aktualizováno :datum",
"Product Price": "Cena balíčku",
"Tax Value": "Hodnota daně",
"Tax Percentage": "Procento daně",
"Total Price": "Celková cena",
"Payment ID": "ID Platby",
"Payment Method": "Platební metoda",
"Products": "Balíčky",
"Product Details": "Detaily balíčku",
"Disabled": "Zakázáno",
"Will hide this option from being selected": "Zabrání této možnosti aby nemohla být vybrána",
"Price in": "Cena v",
"Memory": "Paměť RAM",
"Cpu": "CPU",
"Swap": "Swap",
"This is what the users sees": "Toto je náhled, co uvidí zákazník",
"Disk": "Úložiště",
"Minimum": "Minimum",
"Setting to -1 will use the value from configuration.": "Nastavením na -1 použijete hodnotu z konfigurace.",
"IO": "IO",
"Databases": "Databáze",
"Backups": "Zálohy",
"Allocations": "Porty",
"Product Linking": "Propojení balíčku",
"Link your products to nodes and eggs to create dynamic pricing for each option": "Propojte své balíčky s uzly a distribucemi pro vytvoření cen jednotlivých kombinací",
"This product will only be available for these nodes": "Tento balíček bude dostupný pouze pro tyto uzly",
"This product will only be available for these eggs": "Tento balíček bude dostupný pouze pro tyto distribuce",
"Product": "Balíček",
"CPU": "CPU",
"Updated at": "Aktualizováno",
"User": "Uživatel",
"Config": "Konfigurace",
"Suspended at": "Pozastaveno",
"Settings": "Nastavení",
"Dashboard icons": "Ikony hlavního panelu",
"Invoice Settings": "Nastavení fakturace",
"Select panel icon": "Vybrat ikonu panelu",
"Select panel favicon": "Vybrat favikonu panelu",
"Download all Invoices": "Stáhnout všechny faktury",
"Enter your companys name": "Zadejte název vaší společnosti",
"Enter your companys address": "Zadejte adresu vaší společnosti",
"Enter your companys phone number": "Zadejte telefon na vaši společnost",
"Enter your companys VAT id": "Zadejte DIČ vaší společnosti",
"Enter your companys email address": "Zadejte emailovou adresu na vaši společnost",
"Enter your companys website": "Zadejte webovou adresu vaší společnosti",
"Enter your custom invoice prefix": "Zadejte vlastní předčíslí faktury",
"Logo": "Logo",
"Select Invoice Logo": "Zvolte logo na faktuře",
"Store": "Obchod",
"Currency code": "Kód měny",
"Checkout the paypal docs to select the appropriate code": "Nahlédněte do dokumentace PayPalu pro vybrání správného kódu",
"Quantity": "Množství",
"Amount given to the user after purchasing": "Množství kreditů připsaných uživateli po zakoupení",
"Display": "Zobrazení",
"This is what the user sees at store and checkout": "Toto je náhled co uvidí zákazník v obchodu při objednávání",
"Adds 1000 credits to your account": "Připíše 1000 kreditů na váš účet",
"This is what the user sees at checkout": "Toto je náhled co uvidí zákazník při objednávání",
"No payment method is configured.": "Není nastavena žádná platební metoda.",
"To configure the payment methods, head to the .env and add the required options for your prefered payment method.": "Pro nastavení platebních metod běžte prosím do .env souboru a přidejte nutné nastavení požadované platební metody.",
"Useful Links": "Užitečné odkazy",
"Icon class name": "Jméno třídy ikony",
"You can find available free icons": "Dostupné ikony zdarma můžete najít",
"Title": "Nadpis",
"Link": "Odkaz",
"description": "popis",
"Icon": "Ikona",
"Username": "Uživatelské jméno",
"Email": "Email",
"Pterodactyl ID": "ID Pterodactylu",
"This ID refers to the user account created on pterodactyls panel.": "Toto ID koresponduje s účtem vytvořeným na pterodactyl panelu.",
"Only edit this if you know what youre doing :)": "Upravujte pouze v případě, že víte, co děláte :)",
"Server Limit": "Limit počtu serverů",
"Role": "Role",
" Administrator": " Správce",
"Client": "Zákazník",
"Member": "Člen",
"New Password": "Nové heslo",
"Confirm Password": "Potvrdit heslo",
"Notify": "Oznámit",
"Avatar": "Avatar",
"Verified": "Ověřený",
"Last seen": "Naposledy online",
"Notifications": "Oznámení",
"All": "Vše",
"Send via": "Poslat přes",
"Database": "Databáze",
"Content": "Obsah",
"Server limit": "Limit počtu serverů",
"Discord": "Discord",
"Usage": "Využití",
"IP": "IP",
"Vouchers": "Poukazy",
"Voucher details": "Podrobnosti poukazu",
"Summer break voucher": "Poukaz na letní prázdniny",
"Code": "Kód",
"Random": "Random",
"Uses": "Použití",
"A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Poukaz může být použit pouze jednou na uživatele. Počet použití upravuje počet různých uživatelů, kteří můžou poukaz použít.",
"Max": "Maximum",
"Expires at": "Vyprší",
"Used \/ Uses": "Použito",
"Expires": "Vyprší",
"Sign in to start your session": "Pro pokračování se prosím přihlašte",
"Password": "Heslo",
"Remember Me": "Zapamatovat si mě",
"Sign In": "Přihlásit se",
"Forgot Your Password?": "Zapomenuté heslo?",
"Register a new membership": "Zaregistrovat se",
"Please confirm your password before continuing.": "Před pokračováním prosím potvrďte své heslo.",
"You forgot your password? Here you can easily retrieve a new password.": "Zapomenuté heslo? Zde si můžete snadno vytvořit nové.",
"Request new password": "Zažádat o nové heslo",
"Login": "Přihlášení",
"You are only one step a way from your new password, recover your password now.": "Jste poslední krok od nového hesla. Obnovte své heslo teď.",
"Retype password": "Zopakovat heslo",
"Change password": "Změnit heslo",
"Register": "Registrovat",
"I already have a membership": "Už mám účet",
"Verify Your Email Address": "Ověř svou e-mailovou adresu",
"A fresh verification link has been sent to your email address.": "Nový ověřovací email byl odeslán na váš e-mail.",
"Before proceeding, please check your email for a verification link.": "Před pokračováním zkontrolujte vaši emailovou schránku a klikněte na ověřovací link.",
"If you did not receive the email": "Pokud vám nebyl email doručen",
"click here to request another": "klikněte zde pro získání nového",
"per month": "za měsíc",
"Out of Credits in": "Dostatek kreditů na",
"Home": "Domů",
"Languages": "Jazyky",
"See all Notifications": "Zobrazit všechna oznámení",
"Redeem code": "Uplatnit kód",
"Profile": "Profil",
"Log back in": "Přihlásit se zpět",
"Logout": "Odhlásit se",
"Administration": "Správa",
"Overview": "Přehled pro správce",
"Management": "Administrace",
"Other": "Další",
"Logs": "Logy",
"Warning!": "Varování!",
"You have not yet verified your email address": "Ještě nemáte ověřenou emailovou adresu",
"Click here to resend verification email": "Kliknutím zde odešlete nový ověřovací link",
"Please contact support If you didnt receive your verification email.": "Prosím kontaktujte podporu, pokud jste nedostal ověřovací email.",
"Thank you for your purchase!": "Děkujeme za váš nákup!",
"Your payment has been confirmed; Your credit balance has been updated.": "Platbaa byla úspěšná, vaše kredity byly připsány.",
"Thanks": "Děkujeme",
"Redeem voucher code": "Uplatnit kód poukazu",
"Close": "Zavřít",
"Redeem": "Uplatnit",
"All notifications": "Všechna oznámení",
"Required Email verification!": "Je potřeba mít ověřený email!",
"Required Discord verification!": "Je potřeba mít ověřený discord!",
"You have not yet verified your discord account": "Ještě nemáte ověřený discord účet",
"Login with discord": "Přihlásit se s Discordem",
"Please contact support If you face any issues.": "Prosím kontaktujte podporu pokud máte jakýkoliv problém.",
"Due to system settings you are required to verify your discord account!": "Kvůli systémovému nastavení je třeba ověřit si discord účet!",
"It looks like this hasnt been set-up correctly! Please contact support.": "Vypadá to, že je něco špatně nastaveno! Prosím kontaktujte správce.",
"Change Password": "Změnit heslo",
"Current Password": "Aktuální heslo",
"Link your discord account!": "Ověřte váš Discord účet!",
"By verifying your discord account, you receive extra Credits and increased Server amounts": "Ověřením vašeho discord účtu získáte kredity navíc a zvýšený limit počtu serverů",
"Login with Discord": "Přihlašte se s Discordem",
"You are verified!": "Jste ověřený!",
"Re-Sync Discord": "Aktualizovat propojení s discordem",
"Save Changes": "Uložit změny",
"Server configuration": "Konfigurace serveru",
"Error!": "Chyba!",
"Make sure to link your products to nodes and eggs.": "Nezapomeňte propojit své balíčky k uzlům a distribucím.",
"There has to be at least 1 valid product for server creation": "Pro vytvoření serveru musí být nastavena alespoň 1 balíček",
"No products available!": "Žádné dostupné balíčky!",
"No nodes have been linked!": "Nebyly propojeny žádné uzly!",
"No nests available!": "Žádný dostupný software\/hry!",
"No eggs have been linked!": "Nebyly nastaveny žádné distribuce!",
"Software \/ Games": "Software\/hry",
"Please select software ...": "Prosím zvolte software ...",
"---": "---",
"Specification ": "Specifikace ",
"Node": "Uzel",
"Resource Data:": "Data prostředků:",
"vCores": "vlákna",
"MB": "MB",
"MySQL": "MySQL",
"ports": "portů",
"Not enough": "Nedostatek",
"Create server": "Vytvořit server",
"Please select a node ...": "Prosím vyberte uzel ...",
"No nodes found matching current configuration": "Pro zvolenou konfiguraci nebyly nalezeny žádné uzly",
"Please select a resource ...": "Prosím vyberte balíček ...",
"No resources found matching current configuration": "Pro zvolenou konfiguraci nebyly nalezeny žádné balíčky",
"Please select a configuration ...": "Prosím vyberte konfiguraci ...",
"Not enough credits!": "Nedostatek kreditů!",
"Create Server": "Vytvořit server",
"Software": "Software",
"Specification": "Specifikace",
"Resource plan": "Balíček prosředků",
"RAM": "RAM",
"MySQL Databases": "Databáze MySQL",
"per Hour": "za hodinu",
"per Month": "za měsíc",
"Manage": "Spravovat",
"Are you sure?": "Jste si jistý?",
"This is an irreversible action, all files of this server will be removed.": "Tato akce je nevratná. Všechny soubory tohoto serveru budou odstraněny.",
"Yes, delete it!": "Ano, odstranit!",
"No, cancel!": "Ne, zrušit!",
"Canceled ...": "Zrušeno ...",
"Deletion has been canceled.": "Mazání bylo zrušeno.",
"Date": "Datum",
"To": "Komu",
"From": "Od",
"Pending": "Čekající",
"Subtotal": "Mezisoučet",
"Payment Methods": "Platební metody",
"Amount Due": "Platba ke dni",
"Tax": "Poplatek",
"Submit Payment": "Potvrdit platbu",
"Purchase": "Zakoupit",
"There are no store products!": "Nejsou dostupné žádné balíčky pro nákup kreditů!",
"The store is not correctly configured!": "Obchod není správně nastaven!",
"Serial No.": "Sériové číslo",
"Invoice date": "Datum fakturace",
"Seller": "Prodejce",
"Buyer": "Kupující",
"Address": "Adresa",
"VAT Code": "DIČ",
"Phone": "Telefon",
"Units": "Jednotky",
"Discount": "Sleva",
"Total discount": "Celková sleva",
"Taxable amount": "Zpoplatněná částka",
"Tax rate": "Poplatková sazba",
"Total taxes": "Celkem poplatek",
"Shipping": "Dodání",
"Total amount": "Celková částka",
"Notes": "Poznámky",
"Amount in words": "Celkem slovy",
"Please pay until": "Splatné do",
"Account already exists on Pterodactyl. Please contact the Support!": "Účet na Pterodaktylu již existuje. Kontaktujte prosím podporu!"
}

View file

@ -0,0 +1,18 @@
<?php
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
return [
'failed' => 'Tyto přihlašovací údaje neodpovídají žadnému záznamu.',
'password' => 'Zadané heslo je neplatné.',
'throttle' => 'Příliš mnoho pokusů o přihlášení. Zkuste to prosím znovu za :seconds sekund.',
];

View file

@ -0,0 +1,17 @@
<?php
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
return [
'next' => 'další &raquo;',
'previous' => '&laquo; předchozí',
];

View file

@ -0,0 +1,20 @@
<?php
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
return [
'reset' => 'Heslo bylo obnoveno!',
'sent' => 'E-mail s instrukcemi k obnovení hesla byl odeslán!',
'throttled' => 'Počkejte prosím a zkuste to znovu.',
'token' => 'Klíč pro obnovu hesla je nesprávný.',
'user' => 'Nepodařilo se najít uživatele s touto e-mailovou adresou.',
];

View file

@ -0,0 +1,135 @@
<?php
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
return [
'accepted' => ':attribute musí být přijat.',
'accepted_if' => 'The :attribute must be accepted when :other is :value.',
'active_url' => ':attribute není platnou URL adresou.',
'after' => ':attribute musí být datum po :date.',
'after_or_equal' => ':attribute musí být datum :date nebo pozdější.',
'alpha' => ':attribute může obsahovat pouze písmena.',
'alpha_dash' => ':attribute může obsahovat pouze písmena, číslice, pomlčky a podtržítka. České znaky (á, é, í, ó, ú, ů, ž, š, č, ř, ď, ť, ň) nejsou podporovány.',
'alpha_num' => ':attribute může obsahovat pouze písmena a číslice.',
'array' => ':attribute musí být pole.',
'attached' => 'Tento :attribute je již připojen.',
'before' => ':attribute musí být datum před :date.',
'before_or_equal' => 'Datum :attribute musí být před nebo rovno :date.',
'between' => [
'array' => ':attribute musí obsahovat nejméně :min a nesmí obsahovat více než :max prvků.',
'file' => ':attribute musí být větší než :min a menší než :max Kilobytů.',
'numeric' => ':attribute musí být hodnota mezi :min a :max.',
'string' => ':attribute musí být delší než :min a kratší než :max znaků.',
],
'boolean' => ':attribute musí být true nebo false',
'confirmed' => ':attribute nesouhlasí.',
'current_password' => 'Současné heslo není spravné.',
'date' => ':attribute musí být platné datum.',
'date_equals' => ':attribute musí být datum shodné s :date.',
'date_format' => ':attribute není platný formát data podle :format.',
'declined' => 'The :attribute must be declined.',
'declined_if' => 'The :attribute must be declined when :other is :value.',
'different' => ':attribute a :other se musí lišit.',
'digits' => ':attribute musí být :digits pozic dlouhé.',
'digits_between' => ':attribute musí být dlouhé nejméně :min a nejvíce :max pozic.',
'dimensions' => ':attribute má neplatné rozměry.',
'distinct' => ':attribute má duplicitní hodnotu.',
'email' => ':attribute není platný formát.',
'ends_with' => ':attribute musí končit jednou z následujících hodnot: :values',
'exists' => 'Zvolená hodnota pro :attribute není platná.',
'file' => ':attribute musí být soubor.',
'filled' => ':attribute musí být vyplněno.',
'gt' => [
'array' => 'Pole :attribute musí mít více prvků než :value.',
'file' => 'Velikost souboru :attribute musí být větší než :value kB.',
'numeric' => ':attribute musí být větší než :value.',
'string' => 'Počet znaků :attribute musí být větší :value.',
],
'gte' => [
'array' => 'Pole :attribute musí mít :value prvků nebo více.',
'file' => 'Velikost souboru :attribute musí být větší nebo rovno :value kB.',
'numeric' => ':attribute musí být větší nebo rovno :value.',
'string' => 'Počet znaků :attribute musí být větší nebo rovno :value.',
],
'image' => ':attribute musí být obrázek.',
'in' => 'Zvolená hodnota pro :attribute je neplatná.',
'in_array' => ':attribute není obsažen v :other.',
'integer' => ':attribute musí být celé číslo.',
'ip' => ':attribute musí být platnou IP adresou.',
'ipv4' => ':attribute musí být platná IPv4 adresa.',
'ipv6' => ':attribute musí být platná IPv6 adresa.',
'json' => ':attribute musí být platný JSON řetězec.',
'lt' => [
'array' => ':attribute by měl obsahovat méně než :value položek.',
'file' => 'Velikost souboru :attribute musí být menší než :value kB.',
'numeric' => ':attribute musí být menší než :value.',
'string' => ':attribute musí obsahovat méně než :value znaků.',
],
'lte' => [
'array' => ':attribute by měl obsahovat maximálně :value položek.',
'file' => 'Velikost souboru :attribute musí být menší než :value kB.',
'numeric' => ':attribute musí být menší nebo rovno než :value.',
'string' => ':attribute nesmí být delší než :value znaků.',
],
'max' => [
'array' => ':attribute nemůže obsahovat více než :max prvků.',
'file' => 'Velikost souboru :attribute musí být menší než :value kB.',
'numeric' => ':attribute nemůže být větší než :max.',
'string' => ':attribute nemůže být delší než :max znaků.',
],
'mimes' => ':attribute musí být jeden z následujících datových typů :values.',
'mimetypes' => ':attribute musí být jeden z následujících datových typů :values.',
'min' => [
'array' => ':attribute musí obsahovat více než :min prvků.',
'file' => ':attribute musí být větší než :min kB.',
'numeric' => ':attribute musí být větší než :min.',
'string' => ':attribute musí být delší než :min znaků.',
],
'multiple_of' => ':attribute musí být násobkem :value',
'not_in' => 'Zvolená hodnota pro :attribute je neplatná.',
'not_regex' => ':attribute musí být regulární výraz.',
'numeric' => ':attribute musí být číslo.',
'password' => 'Heslo je nesprávné.',
'present' => ':attribute musí být vyplněno.',
'prohibited' => 'Pole :attribute je zakázáno.',
'prohibited_if' => 'Pole :attribute je zakázáno, když je :other :value.',
'prohibited_unless' => 'Pole :attribute je zakázáno, pokud není rok :other v roce :values.',
'prohibits' => 'The :attribute field prohibits :other from being present.',
'regex' => ':attribute nemá správný formát.',
'relatable' => 'Tento :attribute nemusí být spojen s tímto zdrojem.',
'required' => ':attribute musí být vyplněno.',
'required_if' => ':attribute musí být vyplněno pokud :other je :value.',
'required_unless' => ':attribute musí být vyplněno dokud :other je v :values.',
'required_with' => ':attribute musí být vyplněno pokud :values je vyplněno.',
'required_with_all' => ':attribute musí být vyplněno pokud :values je zvoleno.',
'required_without' => ':attribute musí být vyplněno pokud :values není vyplněno.',
'required_without_all' => ':attribute musí být vyplněno pokud není žádné z :values zvoleno.',
'same' => ':attribute a :other se musí shodovat.',
'size' => [
'array' => ':attribute musí obsahovat právě :size prvků.',
'file' => ':attribute musí mít přesně :size Kilobytů.',
'numeric' => ':attribute musí být přesně :size.',
'string' => ':attribute musí být přesně :size znaků dlouhý.',
],
'starts_with' => ':attribute musí začínat jednou z následujících hodnot: :values',
'string' => ':attribute musí být řetězec znaků.',
'timezone' => ':attribute musí být platná časová zóna.',
'unique' => ':attribute musí být unikátní.',
'uploaded' => 'Nahrávání :attribute se nezdařilo.',
'url' => 'Formát :attribute je neplatný.',
'uuid' => ':attribute musí být validní UUID.',
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
];

445
resources/lang/de.json Normal file
View file

@ -0,0 +1,445 @@
{
"Invoice settings updated!": "Rechnungseinstellungen aktualisiert!",
"Language settings have not been updated!": "Spracheinstellungen wurden nicht aktualisiert!",
"Language settings updated!": "Spracheinstellungen wurden aktualisiert!",
"Misc settings have not been updated!": "Allgemeine Einstellungen wurden nicht aktualisiert!",
"Misc settings updated!": "Allgemeine Einstellungen wurden aktualisiert!",
"Payment settings have not been updated!": "Zahlungseinstellungen wurden nicht aktualisiert!",
"Payment settings updated!": "Zahlungseinstellungen wurden aktualisiert!",
"System settings have not been updated!": "Systemeinstellungen wurden nicht aktualisiert!",
"System settings updated!": "Systemeinstellungen wurden aktualisiert!",
"api key created!": "API Key erstellt",
"api key updated!": "API Key updated",
"api key has been removed!": "API Key gelöscht",
"Edit": "Bearbeiten",
"Delete": "Löschen",
"Store item has been created!": "Item wurde erstellt!",
"Store item has been updated!": "Item updated",
"Product has been updated!": "Product updated",
"Store item has been removed!": "Item gelöscht",
"Created at": "Erstellt am",
"Error!": "Fehler!",
"unknown": "unbekannt",
"Pterodactyl synced": "Pterodactyl synced",
"Your credit balance has been increased!": "Dein Kontostand wurde updated",
"Your payment is being processed!": "Deine Bezahlung wurde verarbeitet!",
"Your payment has been canceled!": "Deine Bezahlung wurde abgebrochen!",
"Payment method": "Bezahlmethode",
"Invoice": "Rechnung",
"Download": "Herunterladen",
"Product has been created!": "Produkt erstellt",
"Product has been removed!": "Produkt gelöscht",
"Show": "Zeige",
"Clone": "Klonen",
"Server removed": "Server gelöscht",
"An exception has occurred while trying to remove a resource \"": "Folgender Fehler ist aufgetreten: ",
"Server has been updated!": "Server updated",
"Unsuspend": "Reaktivieren",
"Suspend": "Deaktivieren",
"configuration has been updated!": "Konfig updated",
"link has been created!": "Link erstellt!",
"link has been updated!": "Link updated!",
"product has been removed!": "Das Produkt wurde entfernt!",
"User does not exists on pterodactyl's panel": "User existiert nicht in Pterodactyl",
"user has been removed!": "User gelöscht",
"Notification sent!": "Nachricht gesendet",
"User has been updated!": "User updated!",
"Login as User": "Als User anmelden",
"voucher has been created!": "Gutschein erstellt",
"voucher has been updated!": "Gutschein Updated",
"voucher has been removed!": "Gutschein gelöscht",
"This voucher has reached the maximum amount of uses": "Maximale Anzahl an Einlösungen erreicht",
"This voucher has expired": "Gutschein abgelaufen",
"You already redeemed this voucher code": "Du hast diesen Gutschein bereits eingelöst",
"have been added to your balance!": "wurden deinem Konto hinzugefügt",
"Users": "Benutzer",
"VALID": "GÜLTIG",
"Account already exists on Pterodactyl. Please contact the Support!": "Der Account existiert bereits bei Pterodactyl. Kontaktiere den Support!",
"days": "Tage",
"hours": "Stunden",
"You ran out of Credits": "Keine Credits übrig!",
"Profile updated": "Profile updated",
"Server limit reached!": "Server Limit erreicht!",
"You are required to verify your email address before you can create a server.": "Du musst deine E-Mail verifizieren bevor du einen Server erstellen kannst",
"You are required to link your discord account before you can create a server.": "Du musst dein Discord verifizieren bevor du einen Server erstellen kannst",
"Server created": "Server erstellt!",
"No allocations satisfying the requirements for automatic deployment on this node were found.": "Keine automatischen Portzuweisungen für dieses Node vorhanden",
"You are required to verify your email address before you can purchase credits.": "Vor dem Kauf musst du deine E-Mail verifizieren",
"You are required to link your discord account before you can purchase Credits": "Du musst deinen Discord Account verbinden, bevor du Guthaben kaufen kannst",
"EXPIRED": "ABGELAUFEN",
"Payment Confirmation": "Zahlungsbestätigung",
"Payment Confirmed!": "Zahlung bestätigt!",
"Your Payment was successful!": "Deine Zahlung ist erfolgreich bei uns eingegangen!",
"Hello": "Hallo",
"Your payment was processed successfully!": "Deine Zahlung wurde erfolgreich verarbeitet!",
"Status": "Status",
"Price": "Preis",
"Type": "Typ",
"Amount": "Anzahl",
"Balance": "Stand",
"User ID": "User-ID",
"Server Creation Error": "Fehler beim erstellen des Servers",
"Your servers have been suspended!": "Deine Server wurden pausiert",
"To automatically re-enable your server\/s, you need to purchase more credits.": "Um deine Server zu reaktivieren, musst du mehr Credits kaufen!",
"Purchase credits": "Credits kaufen",
"If you have any questions please let us know.": "Solltest du weiter fragen haben, melde dich gerne beim Support!",
"Regards": "mit freundlichen Grüßen",
"Getting started!": "Den Anfang machen!",
"Activity Logs": "Aktivitäts logs",
"Dashboard": "Dashboard",
"No recent activity from cronjobs": "Keine neuen aktivitäten von Cronjobs",
"Are cronjobs running?": "Sind die Cronjobs gestartet?",
"Check the docs for it here": "Zur Dokumentation",
"Causer": "Verursacher",
"Description": "Beschreibung",
"Application API": "API",
"Create": "Erstellen",
"Memo": "Name",
"Submit": "Abschicken",
"Create new": "Neu erstellen",
"Token": "Token",
"Last used": "Zuletzt benutzt",
"Are you sure you wish to delete?": "Sicher, dass du dies löschen möchtest?",
"Nests": "Nests",
"Sync": "Sync",
"Active": "Aktiv",
"ID": "ID",
"eggs": "eggs",
"Name": "Name",
"Nodes": "Nodes",
"Location": "Standort",
"Admin Overview": "Admin Übersicht",
"Support server": "Discord Server",
"Documentation": "Dokumentation",
"Github": "Github",
"Support ControlPanel": "Unterstütze Controlpanel.gg",
"Servers": "Server",
"Total": "Gesamt",
"Payments": "Zahlungen",
"Pterodactyl": "Pterodactyl",
"Resources": "Ressourcen",
"Count": "Anzahl",
"Locations": "Standorte",
"Eggs": "Eggs",
"Last updated :date": "Zuletzt aktualisiert :date",
"Download all Invoices": "Alle Rechnungen runterladen",
"Product Price": "Produktpreis",
"Tax Value": "Steuern",
"Tax Percentage": "Steuersatz",
"Total Price": "Gesamtpreis",
"Payment ID": "Zahlungs-ID",
"Payment Method": "Bezahlmethode",
"Products": "Produkte",
"Product Details": "Produktdetails",
"Disabled": "Deaktiviert",
"Will hide this option from being selected": "Wird dieses Produkt nicht zum Kauf zur Verfügung stellen",
"Price in": "Preis in ",
"Memory": "Arbeitsspeicher",
"Cpu": "Prozessorleistung",
"Swap": "Swap",
"This is what the users sees": "Das wird der Benutzer sehen",
"Disk": "Festplatte",
"Minimum": "Mindest",
"Setting to -1 will use the value from configuration.": "Benutzt den Standard, wenn der Wert auf -1 gesetzt wird",
"IO": "IO",
"Databases": "Datenbanken",
"Backups": "Backups",
"Allocations": "Port Zuweisungen",
"Product Linking": "Produktbeziehungen",
"Link your products to nodes and eggs to create dynamic pricing for each option": "Verbinde deine Produkte mit Nodes und Eggs um ein dynamisches Preismodell zu erstellen",
"This product will only be available for these nodes": "Dieses Produkt wurd nur für die ausgewählten Nodes verfügbar sein",
"This product will only be available for these eggs": "Dieses Produkt wurd nur für die ausgewählten Eggs verfügbar sein",
"Product": "Produkt",
"CPU": "CPU",
"Updated at": "Aktualisiert",
"User": "Benutzer",
"Config": "Konfiguration",
"Suspended at": "Suspendiert",
"Settings": "Einstellungen",
"The installer is not locked!": "Der Installer ist nicht gesperrt!",
"please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "Bitte erstellen Sie eine Datei mit dem Namen \"install.lock\" in Ihrem Dashboard-Root-Verzeichnis. Sonst werden keine Einstellungen geladen!",
"or click here": "oder klicke hier",
"Company Name": "Firmenname",
"Company Adress": "Firmenadresse",
"Company Phonenumber": "Firmen Telefonnummer",
"VAT ID": "Umsatzsteuer-ID",
"Company E-Mail Adress": "Firmen E-Mail Adresse",
"Company Website": "Firmenwebseite",
"Invoice Prefix": "Rechnungspräfix",
"Enable Invoices": "Rechnungen aktivieren",
"Logo": "Logo",
"Select Invoice Logo": "Firmenlogo auswählen",
"Available languages": "Verfügbare Sprachen",
"Default language": "Standardsprache",
"The fallback Language, if something goes wrong": "Die Rückfall-Sprache, falls etwas schief geht",
"Datable language": "Tabellensprache",
"The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "Der Sprachcode der Tabellensprache. <br><strong>Beispiel:<\/strong> en-gb, fr_fr, de_de<br>Weitere Informationen: ",
"Auto-translate": "Automatisches übersetzen",
"If this is checked, the Dashboard will translate itself to the Clients language, if available": "Wenn dies aktiviert ist, übersetzt sich das Dashboard selbst in die Sprache des Clients, sofern diese verfügbar ist",
"Client Language-Switch": "Nutzer Sprachumschaltung",
"If this is checked, Clients will have the ability to manually change their Dashboard language": "Wenn dies aktiviert ist, haben Nutzer die Möglichkeit, ihre Dashboard-Sprache manuell zu ändern",
"Mail Service": "E-Mail Service",
"The Mailer to send e-mails with": "Der Mailer zum Versenden von E-Mails",
"Mail Host": "E-Mail Hostadresse",
"Mail Port": "E-Mail Port",
"Mail Username": "E-Mail Nutzername",
"Mail Password": "E-Mail Passwort",
"Mail Encryption": "E-Mail Verschlüsselungsart",
"Mail From Adress": "Absender E-Mailadresse",
"Mail From Name": "Absender E-Mailname",
"Discord Client-ID": "Discord Client-ID",
"Discord Client-Secret": "Discord Client-Secret",
"Discord Bot-Token": "Discord Bot-Token",
"Discord Guild-ID": "Discord Guild-ID",
"Discord Invite-URL": "Discord Invite-URL",
"Discord Role-ID": "Discord Rollen-ID",
"Enable ReCaptcha": "Aktiviere ReCaptcha",
"ReCaptcha Site-Key": "ReCaptcha Site-Key",
"ReCaptcha Secret-Key": "ReCaptcha Secret-Key",
"PayPal Client-ID": "PayPal Client-ID",
"PayPal Secret-Key": "PayPal Secret-Key",
"PayPal Sandbox Client-ID": "PayPal Sandbox Client-ID",
"optional": "Optional",
"PayPal Sandbox Secret-Key": "PayPal Sandbox Secret-Key",
"Stripe Secret-Key": "Stripe Secret-Key",
"Stripe Endpoint-Secret-Key": "Stripe Endpoint-Secret-Key",
"Stripe Test Secret-Key": "Stripe Test Secret-Key",
"Stripe Test Endpoint-Secret-Key": "Stripe Test Endpoint-Secret-Key",
"Payment Methods": "Zahlungsmethoden",
"Tax Value in %": "Steuer in %",
"System": "System",
"Register IP Check": "IP-Adressen registrierungs Prüfung",
"Prevent users from making multiple accounts using the same IP address.": "Verhindern Sie, dass Benutzer mehrere Konten mit derselben IP-Adresse erstellen.",
"Charge first hour at creation": "Berechne die erste Stunde bei Erstellung",
"Charges the first hour worth of credits upon creating a server.": "Rechne den ersten stündlichen Anteil direkt bei Erstellung des Servers ab.",
"Credits Display Name": "Credits Anzeigename",
"PHPMyAdmin URL": "PHPMyAdmin URL",
"Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Geben Sie die URL zu Ihrer PHPMyAdmin-Installation ein. <strong>Ohne abschließendendes Slash!<\/strong>",
"Pterodactyl URL": "Pterodactyl URL",
"Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Geben Sie die URL zu Ihrer Pterodactyl-Installation ein. <strong>Ohne abschließendendes Slash!<\/strong>",
"Pterodactyl API Key": "Pterodactyl API Key",
"Enter the API Key to your Pterodactyl installation.": "Geben Sie den API-Schlüssel zu Ihrer Pterodactyl-Installation ein.",
"Force Discord verification": "Discord Verifikation erzwingen",
"Force E-Mail verification": "E-Mail Verifikation erzwingen",
"Initial Credits": "Anfängliche Credits",
"Initial Server Limit": "Anfängliches Serverlimit",
"Credits Reward Amount - Discord": "Credits-Belohnungsbetrag - Discord",
"Credits Reward Amount - E-Mail": "Credits Belohnungsbetrag - E-Mail",
"Server Limit Increase - Discord": "Erhöhung des Serverlimits - Discord",
"Server Limit Increase - E-Mail": "Erhöhung des Serverlimits - E-Mail",
"Server": "Server",
"Server Allocation Limit": "Serverzuweisungslimit",
"The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!": "Die maximale Menge an Zuweisungen, die pro Knoten für die automatische Bereitstellung abgerufen werden können. Wenn mehr Zuweisungen verwendet werden, als dieses Limit festgelegt ist, können keine neuen Server erstellt werden!",
"Select panel icon": "Icon auswählen",
"Select panel favicon": "Favicon auswählen",
"Store": "Laden",
"Currency code": "Währungscode",
"Checkout the paypal docs to select the appropriate code": "Siehe Paypal für die entsprechenden Codes",
"Quantity": "Menge",
"Amount given to the user after purchasing": "Anzahl, die der User nach dem Kauf bekommt",
"Display": "Anzeigename",
"This is what the user sees at store and checkout": "Dies ist die 'Anzahl' welche der User beim Kaufen sieht",
"Adds 1000 credits to your account": "Fügt deinem Account 1000 Credits hinzu",
"This is what the user sees at checkout": "Dies ist die Beschreibung auf der Rechnung und was der Kunde beim kauf sieht",
"No payment method is configured.": "Zurzeit wurde keine Bezahlmethode festgelegt.",
"To configure the payment methods, head to the .env and add the required options for your prefered payment method.": "Öffne die .env Datei und fülle die benötigten Felder aus, um eine Bezahlmethode zu konfigurieren.",
"Useful Links": "Nützliche Links",
"Icon class name": "Icon Klassen-Name",
"You can find available free icons": "Hier gibt es kostenlose Icons",
"Title": "Titel",
"Link": "Link",
"description": "Beschreibung",
"Icon": "Symbol",
"Username": "Username",
"Email": "E-Mail",
"Pterodactyl ID": "Pterodactyl ID",
"This ID refers to the user account created on pterodactyls panel.": "Die ist die Pterodactyl-ID des Users",
"Only edit this if you know what youre doing :)": "Bearbeite dies nur, wenn du weißt, was du tust :)",
"Server Limit": "Serverlimit",
"Role": "Rolle",
" Administrator": " Administrator",
"Client": "Client",
"Member": "Member",
"New Password": "Neues Passwort",
"Confirm Password": "Passwort bestätigen",
"Notify": "Benachrichtigen",
"Avatar": "Avatar",
"Verified": "Verifiziert",
"Last seen": "Zuletzt online",
"Notifications": "Benachrichtigungen",
"All": "Alle",
"Send via": "Senden via",
"Database": "Datenbank",
"Content": "Inhalt",
"Server limit": "Serverlimit",
"Discord": "Discord",
"Usage": "Nutzung",
"IP": "IP",
"Vouchers": "Gutscheine",
"Voucher details": "Gutschein details",
"Summer break voucher": "Summer break Gutschein",
"Code": "Code",
"Random": "Zufällig",
"Uses": "Benutzungen",
"A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "Ein Gutschein kann von einem User nur einmal eingelöst werden. \"Benutzungen\" setzt die Anzahl an Usern die diesen Gutschein einlösen können.",
"Max": "Max",
"Expires at": "Läuft ab am",
"Used \/ Uses": "Benutzungen",
"Expires": "Ablauf",
"Sign in to start your session": "Melde dich an um das Dashboard zu benutzen",
"Password": "Passwort",
"Remember Me": "Login Speichern",
"Sign In": "Anmelden",
"Forgot Your Password?": "Passwort vergessen?",
"Register a new membership": "Neuen Account registrieren",
"Please confirm your password before continuing.": "Bitte bestätige dein Passwort bevor du fortfährst",
"You forgot your password? Here you can easily retrieve a new password.": "Passwort vergessen? Hier kannst du ganz leicht ein neues anfordern",
"Request new password": "Neues Passwort anfordern",
"Login": "Anmelden",
"You are only one step a way from your new password, recover your password now.": "Du bist nurnoch einen Schritt von deinem Passwort entfernt.",
"Retype password": "Passwort bestätigen",
"Change password": "Passwort ändern",
"Register": "Registrieren",
"I already have a membership": "Ich habe bereits einen Account",
"Verify Your Email Address": "Bestätige deine E-Mail Adresse",
"A fresh verification link has been sent to your email address.": "Dir wurde ein neuer Verifizierungslink zugeschickt",
"Before proceeding, please check your email for a verification link.": "Bitte überprüfe dein E-Mail Postfach nach einem Verifizierungslink",
"If you did not receive the email": "Solltest du keine E-Mail erhalten haben",
"click here to request another": "Klicke hier um eine neue zu erhalten",
"per month": "pro Monat",
"Out of Credits in": "Keine :credits mehr in",
"Home": "Startseite",
"Language": "Sprache",
"See all Notifications": "Alle Nachrichten anzeigen",
"Redeem code": "Code einlösen",
"Profile": "Profil",
"Log back in": "Zurück anmelden",
"Logout": "Abmelden",
"Administration": "Administration",
"Overview": "Übersicht",
"Management": "Management",
"Other": "Anderes",
"Logs": "Logs",
"Warning!": "Warnung!",
"You have not yet verified your email address": "Deine E-Mail Adresse ist nicht bestätigt",
"Click here to resend verification email": "Klicke hier, um eine neue Bestätigungsmail zu senden",
"Please contact support If you didnt receive your verification email.": "Wende dich an den Kundensupport wenn du keine E-Mail erhalten hast",
"Thank you for your purchase!": "Vielen Dank für deinen Einkauf!",
"Your payment has been confirmed; Your credit balance has been updated.": "Deine Zahlung wurde bestätigt und deine Credits angepasst",
"Thanks": "Vielen Dank",
"Redeem voucher code": "Gutscheincode einlösen",
"Close": "Schließen",
"Redeem": "Einlösen",
"All notifications": "Alle Nachrichten",
"Required Email verification!": "E-Mail verifizierung nötig!",
"Required Discord verification!": "Discord verifizierung nötig!",
"You have not yet verified your discord account": "Du hast deinen Discord Account noch nicht bestätigt",
"Login with discord": "Mit discord anmelden",
"Please contact support If you face any issues.": "Melde dich beim Support, solltest du Probleme haben",
"Due to system settings you are required to verify your discord account!": "Um das System zu benutzten, musst du deinen Discord Account bestätigen",
"It looks like this hasnt been set-up correctly! Please contact support.": "Es scheint so, als wäre dies nicht richtig Konfiguriert. Bitte melde dich beim Support",
"Change Password": "Passwort ändern",
"Current Password": "Momentanes Passwort",
"Link your discord account!": "Discord Account verbinden!",
"By verifying your discord account, you receive extra Credits and increased Server amounts": "Wenn du deinen Discordaccount verifizierst, bekommst du extra Credits und ein erhöhtes Server Limit",
"Login with Discord": "Mit Discord anmelden",
"You are verified!": "Du bist verifiziert!",
"Re-Sync Discord": "Resync Discord",
"Save Changes": "Änderungen speichern",
"Server configuration": "Server Konfiguration",
"Make sure to link your products to nodes and eggs.": "Stelle sicher, dass deine Produkte mit Nodes und Eggs verknüpft sind",
"There has to be at least 1 valid product for server creation": "Es muss mindestens 1 aktives Produkt erstellt sein, bevor ein Server erstellt wird",
"Sync now": "Jetzt synchronisieren",
"No products available!": "Keine Produkte verfügbar!",
"No nodes have been linked!": "Es wurde keine Nodes verknüpft",
"No nests available!": "Keine Nests verfügbar",
"No eggs have been linked!": "Es wurde keine Eggs verknüpft",
"Software \/ Games": "Software \/ Spiele",
"Please select software ...": "Bitte Software auswählen",
"---": "---",
"Specification ": "Spezifikation",
"Node": "Node",
"Resource Data:": "Ressourcendaten:",
"vCores": "vCores",
"MB": "MB",
"MySQL": "MySQL",
"ports": "Ports",
"Not enough": "Nicht genug",
"Create server": "Server erstellen",
"Please select a node ...": "Bitte Node auswählen",
"No nodes found matching current configuration": "Kein Node passt zur momentanen Konfiguration",
"Please select a resource ...": "Wähle eine Ressource aus...",
"No resources found matching current configuration": "Keine Ressource passt zur momentanen Konfiguration",
"Please select a configuration ...": "Konfiguration Auswählen!",
"Not enough credits!": "Nicht genug Credits!",
"Create Server": "Server erstellen",
"Software": "Software",
"Specification": "Spezifikationen",
"Resource plan": "Ressourcenplan",
"RAM": "RAM",
"MySQL Databases": "MySQL Datenbank",
"per Hour": "pro Stunde",
"per Month": "pro Monat",
"Manage": "Verwalten",
"Are you sure?": "Sind Sie sicher?",
"This is an irreversible action, all files of this server will be removed.": "Dies kann nicht rückgängig gemacht werden. Alle Serverdaten werden gelöscht.",
"Yes, delete it!": "Ja, löschen!",
"No, cancel!": "Abbrechen",
"Canceled ...": "Abgebrochen...",
"Deletion has been canceled.": "Löschen abgebrochen.",
"Date": "Datum",
"Subtotal": "Zwischensumme",
"Amount Due": "Fälliger Betrag",
"Tax": "Steuer",
"Submit Payment": "Zahlung bestätigen",
"Purchase": "Kaufen",
"There are no store products!": "Es gibt keine Produkte",
"The store is not correctly configured!": "Der Laden wurde nicht richtig konfiguriert",
"Serial No.": "Rechnungsnr.",
"Invoice date": "Rechnungsdatum",
"Seller": "Verkäufer",
"Buyer": "Käufer",
"Address": "Adresse",
"VAT Code": "Steuernummer",
"Phone": "Telefon",
"Units": "Einheiten",
"Discount": "Rabatt",
"Total discount": "Gesamtrabatt",
"Taxable amount": "Steuerbetrag",
"Tax rate": "Steuerrate",
"Total taxes": "Steuerngesamt",
"Shipping": "Lieferbedingung",
"Total amount": "Gesamtbetrag",
"Notes": "Notizen",
"Amount in words": "Betrag in Worten",
"Please pay until": "Zahlbar bis",
"Key": "Schlüssel",
"Value": "Wert",
"Edit Configuration": "Konfiguration bearbeiten",
"Text Field": "Textfeld",
"Cancel": "Abbrechen",
"Save": "Speichern",
"Images and Icons may be cached, reload without cache to see your changes appear": "Bilder und Icons können zwischengespeichert werden, laden Sie sie ohne Cache neu, um zu sehen, wie Ihre Änderungen angezeigt werden (STRG + F5)",
"Enter your companys name": "Geben Sie Ihren Firmennamen ein",
"Enter your companys address": "Geben Sie die Adresse Ihrer Firma ein",
"Enter your companys phone number": "Geben Sie die Telefonnummer Ihrer Firma ein",
"Enter your companys VAT id": "Geben Sie die Umsatzsteuer-Identifikationsnummer Ihrer Firma ein",
"Enter your companys email address": "Geben Sie die E-Mail-Adresse Ihrer Firma ein",
"Enter your companys website": "Geben Sie die Website Ihrer Firma ein",
"Enter your custom invoice prefix": "Geben Sie Ihr benutzerdefiniertes Rechnungspräfix ein",
"The Language of the Datatables. Grab the Language-Codes from here": "Die Sprache der Datentabellen. Holen Sie sich die Sprach-codes von hier",
"Let the Client change the Language": "Lassen Sie den Nutzer die Sprache ändern",
"Icons updated!": "Icons aktualisiert!",
"cs": "Tschechisch",
"de": "Deutsch",
"en": "Englisch",
"es": "Spanisch",
"fr": "Französisch",
"hi": "Hindi",
"it": "Italienisch",
"nl": "Niederländisch",
"pl": "Polnisch",
"zh": "Chinesisch",
"tr": "Türkisch",
"ru": "Russisch"
}

View file

@ -0,0 +1,18 @@
<?php
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
return [
'failed' => 'Diese Kombination aus Zugangsdaten wurde nicht in unserer Datenbank gefunden.',
'password' => 'Das eingegebene Passwort ist nicht korrekt.',
'throttle' => 'Zu viele Loginversuche. Versuchen Sie es bitte in :seconds Sekunden nochmal.',
];

View file

@ -0,0 +1,17 @@
<?php
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
return [
'next' => 'Weiter &raquo;',
'previous' => '&laquo; Zurück',
];

View file

@ -0,0 +1,20 @@
<?php
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
return [
'reset' => 'Das Passwort wurde zurückgesetzt!',
'sent' => 'Passworterinnerung wurde gesendet!',
'throttled' => 'Bitte warten Sie, bevor Sie es erneut versuchen.',
'token' => 'Der Passwort-Wiederherstellungs-Schlüssel ist ungültig oder abgelaufen.',
'user' => 'Es konnte leider kein Nutzer mit dieser E-Mail-Adresse gefunden werden.',
];

View file

@ -0,0 +1,135 @@
<?php
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
return [
'accepted' => ':attribute muss akzeptiert werden.',
'accepted_if' => ':attribute muss akzeptiert werden, wenn :other :value ist.',
'active_url' => ':attribute ist keine gültige Internet-Adresse.',
'after' => ':attribute muss ein Datum nach :date sein.',
'after_or_equal' => ':attribute muss ein Datum nach :date oder gleich :date sein.',
'alpha' => ':attribute darf nur aus Buchstaben bestehen.',
'alpha_dash' => ':attribute darf nur aus Buchstaben, Zahlen, Binde- und Unterstrichen bestehen.',
'alpha_num' => ':attribute darf nur aus Buchstaben und Zahlen bestehen.',
'array' => ':attribute muss ein Array sein.',
'attached' => ':attribute ist bereits angehängt.',
'before' => ':attribute muss ein Datum vor :date sein.',
'before_or_equal' => ':attribute muss ein Datum vor :date oder gleich :date sein.',
'between' => [
'array' => ':attribute muss zwischen :min & :max Elemente haben.',
'file' => ':attribute muss zwischen :min & :max Kilobytes groß sein.',
'numeric' => ':attribute muss zwischen :min & :max liegen.',
'string' => ':attribute muss zwischen :min & :max Zeichen lang sein.',
],
'boolean' => ':attribute muss entweder \'true\' oder \'false\' sein.',
'confirmed' => ':attribute stimmt nicht mit der Bestätigung überein.',
'current_password' => 'Das Passwort ist falsch.',
'date' => ':attribute muss ein gültiges Datum sein.',
'date_equals' => ':attribute muss ein Datum gleich :date sein.',
'date_format' => ':attribute entspricht nicht dem gültigen Format für :format.',
'declined' => 'The :attribute must be declined.',
'declined_if' => 'The :attribute must be declined when :other is :value.',
'different' => ':attribute und :other müssen sich unterscheiden.',
'digits' => ':attribute muss :digits Stellen haben.',
'digits_between' => ':attribute muss zwischen :min und :max Stellen haben.',
'dimensions' => ':attribute hat ungültige Bildabmessungen.',
'distinct' => ':attribute beinhaltet einen bereits vorhandenen Wert.',
'email' => ':attribute muss eine gültige E-Mail-Adresse sein.',
'ends_with' => ':attribute muss eine der folgenden Endungen aufweisen: :values',
'exists' => 'Der gewählte Wert für :attribute ist ungültig.',
'file' => ':attribute muss eine Datei sein.',
'filled' => ':attribute muss ausgefüllt sein.',
'gt' => [
'array' => ':attribute muss mehr als :value Elemente haben.',
'file' => ':attribute muss größer als :value Kilobytes sein.',
'numeric' => ':attribute muss größer als :value sein.',
'string' => ':attribute muss länger als :value Zeichen sein.',
],
'gte' => [
'array' => ':attribute muss mindestens :value Elemente haben.',
'file' => ':attribute muss größer oder gleich :value Kilobytes sein.',
'numeric' => ':attribute muss größer oder gleich :value sein.',
'string' => ':attribute muss mindestens :value Zeichen lang sein.',
],
'image' => ':attribute muss ein Bild sein.',
'in' => 'Der gewählte Wert für :attribute ist ungültig.',
'in_array' => 'Der gewählte Wert für :attribute kommt nicht in :other vor.',
'integer' => ':attribute muss eine ganze Zahl sein.',
'ip' => ':attribute muss eine gültige IP-Adresse sein.',
'ipv4' => ':attribute muss eine gültige IPv4-Adresse sein.',
'ipv6' => ':attribute muss eine gültige IPv6-Adresse sein.',
'json' => ':attribute muss ein gültiger JSON-String sein.',
'lt' => [
'array' => ':attribute muss weniger als :value Elemente haben.',
'file' => ':attribute muss kleiner als :value Kilobytes sein.',
'numeric' => ':attribute muss kleiner als :value sein.',
'string' => ':attribute muss kürzer als :value Zeichen sein.',
],
'lte' => [
'array' => ':attribute darf maximal :value Elemente haben.',
'file' => ':attribute muss kleiner oder gleich :value Kilobytes sein.',
'numeric' => ':attribute muss kleiner oder gleich :value sein.',
'string' => ':attribute darf maximal :value Zeichen lang sein.',
],
'max' => [
'array' => ':attribute darf maximal :max Elemente haben.',
'file' => ':attribute darf maximal :max Kilobytes groß sein.',
'numeric' => ':attribute darf maximal :max sein.',
'string' => ':attribute darf maximal :max Zeichen haben.',
],
'mimes' => ':attribute muss den Dateityp :values haben.',
'mimetypes' => ':attribute muss den Dateityp :values haben.',
'min' => [
'array' => ':attribute muss mindestens :min Elemente haben.',
'file' => ':attribute muss mindestens :min Kilobytes groß sein.',
'numeric' => ':attribute muss mindestens :min sein.',
'string' => ':attribute muss mindestens :min Zeichen lang sein.',
],
'multiple_of' => ':attribute muss ein Vielfaches von :value sein.',
'not_in' => 'Der gewählte Wert für :attribute ist ungültig.',
'not_regex' => ':attribute hat ein ungültiges Format.',
'numeric' => ':attribute muss eine Zahl sein.',
'password' => 'Das Passwort ist falsch.',
'present' => ':attribute muss vorhanden sein.',
'prohibited' => ':attribute ist unzulässig.',
'prohibited_if' => ':attribute ist unzulässig, wenn :other :value ist.',
'prohibited_unless' => ':attribute ist unzulässig, wenn :other nicht :values ist.',
'prohibits' => ':attribute verbietet die Angabe von :other.',
'regex' => ':attribute Format ist ungültig.',
'relatable' => ':attribute kann nicht mit dieser Ressource verbunden werden.',
'required' => ':attribute muss ausgefüllt werden.',
'required_if' => ':attribute muss ausgefüllt werden, wenn :other den Wert :value hat.',
'required_unless' => ':attribute muss ausgefüllt werden, wenn :other nicht den Wert :values hat.',
'required_with' => ':attribute muss ausgefüllt werden, wenn :values ausgefüllt wurde.',
'required_with_all' => ':attribute muss ausgefüllt werden, wenn :values ausgefüllt wurde.',
'required_without' => ':attribute muss ausgefüllt werden, wenn :values nicht ausgefüllt wurde.',
'required_without_all' => ':attribute muss ausgefüllt werden, wenn keines der Felder :values ausgefüllt wurde.',
'same' => ':attribute und :other müssen übereinstimmen.',
'size' => [
'array' => ':attribute muss genau :size Elemente haben.',
'file' => ':attribute muss :size Kilobyte groß sein.',
'numeric' => ':attribute muss gleich :size sein.',
'string' => ':attribute muss :size Zeichen lang sein.',
],
'starts_with' => ':attribute muss mit einem der folgenden Anfänge aufweisen: :values',
'string' => ':attribute muss ein String sein.',
'timezone' => ':attribute muss eine gültige Zeitzone sein.',
'unique' => ':attribute ist bereits vergeben.',
'uploaded' => ':attribute konnte nicht hochgeladen werden.',
'url' => ':attribute muss eine URL sein.',
'uuid' => ':attribute muss ein UUID sein.',
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
];

447
resources/lang/en.json Normal file
View file

@ -0,0 +1,447 @@
{
"Invoice settings updated!": "Invoice settings updated!",
"Language settings have not been updated!": "Language settings have not been updated!",
"Language settings updated!": "Language settings updated!",
"Misc settings have not been updated!": "Misc settings have not been updated!",
"Misc settings updated!": "Misc settings updated!",
"Payment settings have not been updated!": "Payment settings have not been updated!",
"Payment settings updated!": "Payment settings updated!",
"System settings have not been updated!": "System settings have not been updated!",
"System settings updated!": "System settings updated!",
"api key created!": "api key created!",
"api key updated!": "api key updated!",
"api key has been removed!": "api key has been removed!",
"Edit": "Edit",
"Delete": "Delete",
"Store item has been created!": "Store item has been created!",
"Store item has been updated!": "Store item has been updated!",
"Product has been updated!": "Product has been updated!",
"Store item has been removed!": "Store item has been removed!",
"Created at": "Created at",
"Error!": "Error!",
"unknown": "unknown",
"Pterodactyl synced": "Pterodactyl synced",
"Your credit balance has been increased!": "Your credit balance has been increased!",
"Your payment is being processed!": "Your payment is being processed!",
"Your payment has been canceled!": "Your payment has been canceled!",
"Payment method": "Payment method",
"Invoice": "Invoice",
"Download": "Download",
"Product has been created!": "Product has been created!",
"Product has been removed!": "Product has been removed!",
"Show": "Show",
"Clone": "Clone",
"Server removed": "Server removed",
"An exception has occurred while trying to remove a resource \"": "An exception has occurred while trying to remove a resource \"",
"Server has been updated!": "Server has been updated!",
"Unsuspend": "Unsuspend",
"Suspend": "Suspend",
"configuration has been updated!": "configuration has been updated!",
"link has been created!": "link has been created!",
"link has been updated!": "link has been updated!",
"product has been removed!": "product has been removed!",
"User does not exists on pterodactyl's panel": "User does not exists on pterodactyl's panel",
"user has been removed!": "user has been removed!",
"Notification sent!": "Notification sent!",
"User has been updated!": "User has been updated!",
"Login as User": "Login as User",
"voucher has been created!": "voucher has been created!",
"voucher has been updated!": "voucher has been updated!",
"voucher has been removed!": "voucher has been removed!",
"This voucher has reached the maximum amount of uses": "This voucher has reached the maximum amount of uses",
"This voucher has expired": "This voucher has expired",
"You already redeemed this voucher code": "You already redeemed this voucher code",
"have been added to your balance!": "have been added to your balance!",
"Users": "Users",
"VALID": "VALID",
"Account already exists on Pterodactyl. Please contact the Support!": "Account already exists on Pterodactyl. Please contact the Support!",
"days": "days",
"hours": "hours",
"You ran out of Credits": "You ran out of Credits",
"Profile updated": "Profile updated",
"Server limit reached!": "Server limit reached!",
"You are required to verify your email address before you can create a server.": "You are required to verify your email address before you can create a server.",
"You are required to link your discord account before you can create a server.": "You are required to link your discord account before you can create a server.",
"Server created": "Server created",
"No allocations satisfying the requirements for automatic deployment on this node were found.": "No allocations satisfying the requirements for automatic deployment on this node were found.",
"You are required to verify your email address before you can purchase credits.": "You are required to verify your email address before you can purchase credits.",
"You are required to link your discord account before you can purchase Credits": "You are required to link your discord account before you can purchase Credits",
"EXPIRED": "EXPIRED",
"Payment Confirmation": "Payment Confirmation",
"Payment Confirmed!": "Payment Confirmed!",
"Your Payment was successful!": "Your Payment was successful!",
"Hello": "Hello",
"Your payment was processed successfully!": "Your payment was processed successfully!",
"Status": "Status",
"Price": "Price",
"Type": "Type",
"Amount": "Amount",
"Balance": "Balance",
"User ID": "User ID",
"Server Creation Error": "Server Creation Error",
"Your servers have been suspended!": "Your servers have been suspended!",
"To automatically re-enable your server\/s, you need to purchase more credits.": "To automatically re-enable your server\/s, you need to purchase more credits.",
"Purchase credits": "Purchase credits",
"If you have any questions please let us know.": "If you have any questions please let us know.",
"Regards": "Regards",
"Getting started!": "Getting started!",
"Activity Logs": "Activity Logs",
"Dashboard": "Dashboard",
"No recent activity from cronjobs": "No recent activity from cronjobs",
"Are cronjobs running?": "Are cronjobs running?",
"Check the docs for it here": "Check the docs for it here",
"Causer": "Causer",
"Description": "Description",
"Application API": "Application API",
"Create": "Create",
"Memo": "Memo",
"Submit": "Submit",
"Create new": "Create new",
"Token": "Token",
"Last used": "Last used",
"Are you sure you wish to delete?": "Are you sure you wish to delete?",
"Nests": "Nests",
"Sync": "Sync",
"Active": "Active",
"ID": "ID",
"eggs": "eggs",
"Name": "Name",
"Nodes": "Nodes",
"Location": "Location",
"Admin Overview": "Admin Overview",
"Support server": "Support server",
"Documentation": "Documentation",
"Github": "Github",
"Support ControlPanel": "Support ControlPanel",
"Servers": "Servers",
"Total": "Total",
"Payments": "Payments",
"Pterodactyl": "Pterodactyl",
"Resources": "Resources",
"Count": "Count",
"Locations": "Locations",
"Eggs": "Eggs",
"Last updated :date": "Last updated :date",
"Download all Invoices": "Download all Invoices",
"Product Price": "Product Price",
"Tax Value": "Tax Value",
"Tax Percentage": "Tax Percentage",
"Total Price": "Total Price",
"Payment ID": "Payment ID",
"Payment Method": "Payment Method",
"Products": "Products",
"Product Details": "Product Details",
"Disabled": "Disabled",
"Will hide this option from being selected": "Will hide this option from being selected",
"Price in": "Price in",
"Memory": "Memory",
"Cpu": "Cpu",
"Swap": "Swap",
"This is what the users sees": "This is what the users sees",
"Disk": "Disk",
"Minimum": "Minimum",
"Setting to -1 will use the value from configuration.": "Setting to -1 will use the value from configuration.",
"IO": "IO",
"Databases": "Databases",
"Backups": "Backups",
"Allocations": "Allocations",
"Product Linking": "Product Linking",
"Link your products to nodes and eggs to create dynamic pricing for each option": "Link your products to nodes and eggs to create dynamic pricing for each option",
"This product will only be available for these nodes": "This product will only be available for these nodes",
"This product will only be available for these eggs": "This product will only be available for these eggs",
"Product": "Product",
"CPU": "CPU",
"Updated at": "Updated at",
"User": "User",
"Config": "Config",
"Suspended at": "Suspended at",
"Settings": "Settings",
"The installer is not locked!": "The installer is not locked!",
"please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!",
"or click here": "or click here",
"Company Name": "Company Name",
"Company Adress": "Company Adress",
"Company Phonenumber": "Company Phonenumber",
"VAT ID": "VAT ID",
"Company E-Mail Adress": "Company E-Mail Adress",
"Company Website": "Company Website",
"Invoice Prefix": "Invoice Prefix",
"Enable Invoices": "Enable Invoices",
"Logo": "Logo",
"Select Invoice Logo": "Select Invoice Logo",
"Available languages": "Available languages",
"Default language": "Default language",
"The fallback Language, if something goes wrong": "The fallback Language, if something goes wrong",
"Datable language": "Datable language",
"The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ",
"Auto-translate": "Auto-translate",
"If this is checked, the Dashboard will translate itself to the Clients language, if available": "If this is checked, the Dashboard will translate itself to the Clients language, if available",
"Client Language-Switch": "Client Language-Switch",
"If this is checked, Clients will have the ability to manually change their Dashboard language": "If this is checked, Clients will have the ability to manually change their Dashboard language",
"Mail Service": "Mail Service",
"The Mailer to send e-mails with": "The Mailer to send e-mails with",
"Mail Host": "Mail Host",
"Mail Port": "Mail Port",
"Mail Username": "Mail Username",
"Mail Password": "Mail Password",
"Mail Encryption": "Mail Encryption",
"Mail From Adress": "Mail From Adress",
"Mail From Name": "Mail From Name",
"Discord Client-ID": "Discord Client-ID",
"Discord Client-Secret": "Discord Client-Secret",
"Discord Bot-Token": "Discord Bot-Token",
"Discord Guild-ID": "Discord Guild-ID",
"Discord Invite-URL": "Discord Invite-URL",
"Discord Role-ID": "Discord Role-ID",
"Enable ReCaptcha": "Enable ReCaptcha",
"ReCaptcha Site-Key": "ReCaptcha Site-Key",
"ReCaptcha Secret-Key": "ReCaptcha Secret-Key",
"PayPal Client-ID": "PayPal Client-ID",
"PayPal Secret-Key": "PayPal Secret-Key",
"PayPal Sandbox Client-ID": "PayPal Sandbox Client-ID",
"optional": "optional",
"PayPal Sandbox Secret-Key": "PayPal Sandbox Secret-Key",
"Stripe Secret-Key": "Stripe Secret-Key",
"Stripe Endpoint-Secret-Key": "Stripe Endpoint-Secret-Key",
"Stripe Test Secret-Key": "Stripe Test Secret-Key",
"Stripe Test Endpoint-Secret-Key": "Stripe Test Endpoint-Secret-Key",
"Payment Methods": "Payment Methods",
"Tax Value in %": "Tax Value in %",
"System": "System",
"Register IP Check": "Register IP Check",
"Prevent users from making multiple accounts using the same IP address.": "Prevent users from making multiple accounts using the same IP address.",
"Charge first hour at creation": "Charge first hour at creation",
"Charges the first hour worth of credits upon creating a server.": "Charges the first hour worth of credits upon creating a server.",
"Credits Display Name": "Credits Display Name",
"PHPMyAdmin URL": "PHPMyAdmin URL",
"Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>",
"Pterodactyl URL": "Pterodactyl URL",
"Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>",
"Pterodactyl API Key": "Pterodactyl API Key",
"Enter the API Key to your Pterodactyl installation.": "Enter the API Key to your Pterodactyl installation.",
"Force Discord verification": "Force Discord verification",
"Force E-Mail verification": "Force E-Mail verification",
"Initial Credits": "Initial Credits",
"Initial Server Limit": "Initial Server Limit",
"Credits Reward Amount - Discord": "Credits Reward Amount - Discord",
"Credits Reward Amount - E-Mail": "Credits Reward Amount - E-Mail",
"Server Limit Increase - Discord": "Server Limit Increase - Discord",
"Server Limit Increase - E-Mail": "Server Limit Increase - E-Mail",
"Server": "Server",
"Server Allocation Limit": "Server Allocation Limit",
"The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!": "The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!",
"Select panel icon": "Select panel icon",
"Select panel favicon": "Select panel favicon",
"Store": "Store",
"Currency code": "Currency code",
"Checkout the paypal docs to select the appropriate code": "Checkout the paypal docs to select the appropriate code",
"Quantity": "Quantity",
"Amount given to the user after purchasing": "Amount given to the user after purchasing",
"Display": "Display",
"This is what the user sees at store and checkout": "This is what the user sees at store and checkout",
"Adds 1000 credits to your account": "Adds 1000 credits to your account",
"This is what the user sees at checkout": "This is what the user sees at checkout",
"No payment method is configured.": "No payment method is configured.",
"To configure the payment methods, head to the settings-page and add the required options for your prefered payment method.": "To configure the payment methods, head to the settings-page and add the required options for your prefered payment method.",
"Useful Links": "Useful Links",
"Icon class name": "Icon class name",
"You can find available free icons": "You can find available free icons",
"Title": "Title",
"Link": "Link",
"description": "description",
"Icon": "Icon",
"Username": "Username",
"Email": "Email",
"Pterodactyl ID": "Pterodactyl ID",
"This ID refers to the user account created on pterodactyls panel.": "This ID refers to the user account created on pterodactyls panel.",
"Only edit this if you know what youre doing :)": "Only edit this if you know what youre doing :)",
"Server Limit": "Server Limit",
"Role": "Role",
" Administrator": " Administrator",
"Client": "Client",
"Member": "Member",
"New Password": "New Password",
"Confirm Password": "Confirm Password",
"Notify": "Notify",
"Avatar": "Avatar",
"Verified": "Verified",
"Last seen": "Last seen",
"Notifications": "Notifications",
"All": "All",
"Send via": "Send via",
"Database": "Database",
"Content": "Content",
"Server limit": "Server limit",
"Discord": "Discord",
"Usage": "Usage",
"IP": "IP",
"Vouchers": "Vouchers",
"Voucher details": "Voucher details",
"Summer break voucher": "Summer break voucher",
"Code": "Code",
"Random": "Random",
"Uses": "Uses",
"A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.",
"Max": "Max",
"Expires at": "Expires at",
"Used \/ Uses": "Used \/ Uses",
"Expires": "Expires",
"Sign in to start your session": "Sign in to start your session",
"Password": "Password",
"Remember Me": "Remember Me",
"Sign In": "Sign In",
"Forgot Your Password?": "Forgot Your Password?",
"Register a new membership": "Register a new membership",
"Please confirm your password before continuing.": "Please confirm your password before continuing.",
"You forgot your password? Here you can easily retrieve a new password.": "You forgot your password? Here you can easily retrieve a new password.",
"Request new password": "Request new password",
"Login": "Login",
"You are only one step a way from your new password, recover your password now.": "You are only one step a way from your new password, recover your password now.",
"Retype password": "Retype password",
"Change password": "Change password",
"Register": "Register",
"I already have a membership": "I already have a membership",
"Verify Your Email Address": "Verify Your Email Address",
"A fresh verification link has been sent to your email address.": "A fresh verification link has been sent to your email address.",
"Before proceeding, please check your email for a verification link.": "Before proceeding, please check your email for a verification link.",
"If you did not receive the email": "If you did not receive the email",
"click here to request another": "click here to request another",
"per month": "per month",
"Out of Credits in": "Out of Credits in",
"Home": "Home",
"Language": "Language",
"See all Notifications": "See all Notifications",
"Redeem code": "Redeem code",
"Profile": "Profile",
"Log back in": "Log back in",
"Logout": "Logout",
"Administration": "Administration",
"Overview": "Overview",
"Management": "Management",
"Other": "Other",
"Logs": "Logs",
"Warning!": "Warning!",
"You have not yet verified your email address": "You have not yet verified your email address",
"Click here to resend verification email": "Click here to resend verification email",
"Please contact support If you didnt receive your verification email.": "Please contact support If you didnt receive your verification email.",
"Thank you for your purchase!": "Thank you for your purchase!",
"Your payment has been confirmed; Your credit balance has been updated.": "Your payment has been confirmed; Your credit balance has been updated.",
"Thanks": "Thanks",
"Redeem voucher code": "Redeem voucher code",
"Close": "Close",
"Redeem": "Redeem",
"All notifications": "All notifications",
"Required Email verification!": "Required Email verification!",
"Required Discord verification!": "Required Discord verification!",
"You have not yet verified your discord account": "You have not yet verified your discord account",
"Login with discord": "Login with discord",
"Please contact support If you face any issues.": "Please contact support If you face any issues.",
"Due to system settings you are required to verify your discord account!": "Due to system settings you are required to verify your discord account!",
"It looks like this hasnt been set-up correctly! Please contact support.": "It looks like this hasnt been set-up correctly! Please contact support.",
"Change Password": "Change Password",
"Current Password": "Current Password",
"Link your discord account!": "Link your discord account!",
"By verifying your discord account, you receive extra Credits and increased Server amounts": "By verifying your discord account, you receive extra Credits and increased Server amounts",
"Login with Discord": "Login with Discord",
"You are verified!": "You are verified!",
"Re-Sync Discord": "Re-Sync Discord",
"Save Changes": "Save Changes",
"Server configuration": "Server configuration",
"Make sure to link your products to nodes and eggs.": "Make sure to link your products to nodes and eggs.",
"There has to be at least 1 valid product for server creation": "There has to be at least 1 valid product for server creation",
"Sync now": "Sync now",
"No products available!": "No products available!",
"No nodes have been linked!": "No nodes have been linked!",
"No nests available!": "No nests available!",
"No eggs have been linked!": "No eggs have been linked!",
"Software \/ Games": "Software \/ Games",
"Please select software ...": "Please select software ...",
"---": "---",
"Specification ": "Specification ",
"Node": "Node",
"Resource Data:": "Resource Data:",
"vCores": "vCores",
"MB": "MB",
"MySQL": "MySQL",
"ports": "ports",
"Not enough": "Not enough",
"Create server": "Create server",
"Please select a node ...": "Please select a node ...",
"No nodes found matching current configuration": "No nodes found matching current configuration",
"Please select a resource ...": "Please select a resource ...",
"No resources found matching current configuration": "No resources found matching current configuration",
"Please select a configuration ...": "Please select a configuration ...",
"Not enough credits!": "Not enough credits!",
"Create Server": "Create Server",
"Software": "Software",
"Specification": "Specification",
"Resource plan": "Resource plan",
"RAM": "RAM",
"MySQL Databases": "MySQL Databases",
"per Hour": "per Hour",
"per Month": "per Month",
"Manage": "Manage",
"Are you sure?": "Are you sure?",
"This is an irreversible action, all files of this server will be removed.": "This is an irreversible action, all files of this server will be removed.",
"Yes, delete it!": "Yes, delete it!",
"No, cancel!": "No, cancel!",
"Canceled ...": "Canceled ...",
"Deletion has been canceled.": "Deletion has been canceled.",
"Date": "Date",
"Subtotal": "Subtotal",
"Amount Due": "Amount Due",
"Tax": "Tax",
"Submit Payment": "Submit Payment",
"Purchase": "Purchase",
"There are no store products!": "There are no store products!",
"The store is not correctly configured!": "The store is not correctly configured!",
"Serial No.": "Serial No.",
"Invoice date": "Invoice date",
"Seller": "Seller",
"Buyer": "Buyer",
"Address": "Address",
"VAT Code": "VAT Code",
"Phone": "Phone",
"Units": "Units",
"Discount": "Discount",
"Total discount": "Total discount",
"Taxable amount": "Taxable amount",
"Tax rate": "Tax rate",
"Total taxes": "Total taxes",
"Shipping": "Shipping",
"Total amount": "Total amount",
"Notes": "Notes",
"Amount in words": "Amount in words",
"Please pay until": "Please pay until",
"Key": "Key",
"Value": "Value",
"Edit Configuration": "Edit Configuration",
"Text Field": "Text Field",
"Cancel": "Cancel",
"Save": "Save",
"Select panel icon": "Select panel icon",
"Select panel favicon": "Select panel favicon",
"Images and Icons may be cached, reload without cache to see your changes appear": "Images and Icons may be cached, reload without cache to see your changes appear",
"Enter your companys name": "Enter your companys name",
"Enter your companys address": "Enter your companys address",
"Enter your companys phone number": "Enter your companys phone number",
"Enter your companys VAT id": "Enter your companys VAT id",
"Enter your companys email address": "Enter your companys email address",
"Enter your companys website": "Enter your companys website",
"Enter your custom invoice prefix": "Enter your custom invoice prefix",
"The Language of the Datatables. Grab the Language-Codes from here": "The Language of the Datatables. Grab the Language-Codes from here",
"Let the Client change the Language": "Let the Client change the Language",
"Icons updated!": "Icons updated!",
"cs": "Czech",
"de": "German",
"en": "English",
"es": "Spanish",
"fr": "French",
"hi": "Hindi",
"it": "Italian",
"nl": "Dutch",
"pl": "Polish",
"zh": "Chinese",
"tr": "Turkish",
"ru": "Russian"
}

445
resources/lang/es.json Normal file
View file

@ -0,0 +1,445 @@
{
"Invoice settings updated!": "¡Configuración de factura actualizada!",
"Language settings have not been updated!": "¡La configuración de idioma no se ha actualizado!",
"Language settings updated!": "¡Configuración de idioma actualizada!",
"Misc settings have not been updated!": "¡La configuración miscelánea no se ha actualizado!",
"Misc settings updated!": "¡Configuraciones misceláneas actualizadas!",
"Payment settings have not been updated!": "¡La configuración de pago no se ha actualizado!",
"Payment settings updated!": "¡Configuración de pago actualizada!",
"System settings have not been updated!": "¡La configuración del sistema no se ha actualizado!",
"System settings updated!": "¡Configuración del sistema actualizada!",
"api key created!": "¡API Key creada!",
"api key updated!": "¡API Key actualizada!",
"api key has been removed!": "¡La API Key a sido eliminada!",
"Edit": "Editar",
"Delete": "Eliminar",
"Store item has been created!": "¡Se ha creado el artículo en la tienda!",
"Store item has been updated!": "¡El artículo de la tienda ha sido actualizado!",
"Product has been updated!": "¡El producto ha sido actualizado!",
"Store item has been removed!": "¡El artículo de la tienda ha sido eliminado!",
"Created at": "Creado a",
"Error!": "Error!",
"unknown": "desconocido",
"Pterodactyl synced": "Pterodactyl sincronizado",
"Your credit balance has been increased!": "¡Su saldo de crédito ha aumentado!",
"Your payment is being processed!": "¡Tu pago está siendo procesado!",
"Your payment has been canceled!": "¡Tu pago ha sido cancelado!",
"Payment method": "Método de pago",
"Invoice": "Factura",
"Download": "Descargar",
"Product has been created!": "¡El producto ha sido creado!",
"Product has been removed!": "¡El producto ha sido eliminado!",
"Show": "Mostrar",
"Clone": "Clonar",
"Server removed": "Servidor eliminado",
"An exception has occurred while trying to remove a resource \"": "Se produjo una excepción al intentar eliminar un recurso \"",
"Server has been updated!": "¡El servidor ha sido actualizado!",
"Unsuspend": "Quitar suspensión",
"Suspend": "Suspender",
"configuration has been updated!": "¡La configuración ha sido actualizada!",
"link has been created!": "¡Se ha creado el enlace!",
"link has been updated!": "¡El enlace ha sido actualizado!",
"product has been removed!": "¡El producto ha sido eliminado!",
"User does not exists on pterodactyl's panel": "El usuario no existe en el panel pterodactyl",
"user has been removed!": "¡El usuario ha sido eliminado!",
"Notification sent!": "¡Notificación enviada!",
"User has been updated!": "¡El usuario ha sido actualizado!",
"Login as User": "Iniciar sesión como usuario",
"voucher has been created!": "¡Se a creado un cupón!",
"voucher has been updated!": "¡El cupón ha sido actualizado!",
"voucher has been removed!": "¡El cupón a sido eliminado!",
"This voucher has reached the maximum amount of uses": "Este cupón ha alcanzado la cantidad máxima de usos",
"This voucher has expired": "Este cupón a expirado",
"You already redeemed this voucher code": "Ya has usado este cupón",
"have been added to your balance!": "se han añadido a tu saldo!",
"Users": "Usuarios",
"VALID": "VÁLIDO",
"Account already exists on Pterodactyl. Please contact the Support!": "La cuenta ya existe en Pterodactyl. ¡Póngase en contacto con el soporte!",
"days": "días",
"hours": "horas",
"You ran out of Credits": "Te has quedado sin créditos",
"Profile updated": "Perfil actualizado",
"Server limit reached!": "¡Se alcanzó el límite de servidores!",
"You are required to verify your email address before you can create a server.": "Debe verificar su dirección de correo electrónico antes de poder crear un servidor.",
"You are required to link your discord account before you can create a server.": "Debe vincular su cuenta de discord antes de poder crear un servidor.",
"Server created": "Servidor creado",
"No allocations satisfying the requirements for automatic deployment on this node were found.": "No se encontraron asignaciones que satisfagan los requisitos para la implementación automática en este nodo.",
"You are required to verify your email address before you can purchase credits.": "Debes de verificar tu dirección de correo electrónico antes de poder comprar créditos.",
"You are required to link your discord account before you can purchase Credits": "Debe vincular su cuenta de discord antes de poder comprar Créditos",
"EXPIRED": "CADUCADO",
"Payment Confirmation": "Confirmación de Pago",
"Payment Confirmed!": "¡Pago Confirmado!",
"Your Payment was successful!": "¡El pago se ha realizado correctamente!",
"Hello": "Hola",
"Your payment was processed successfully!": "¡Su pago se procesó correctamente!",
"Status": "Estado",
"Price": "Precio",
"Type": "Tipo",
"Amount": "Cantidad",
"Balance": "Saldo",
"User ID": "ID Usuario",
"Server Creation Error": "Error de creación del servidor",
"Your servers have been suspended!": "¡Sus servidores han sido suspendidos!",
"To automatically re-enable your server\/s, you need to purchase more credits.": "Para volver a habilitar automáticamente sus servidores, debe comprar más créditos.",
"Purchase credits": "Comprar Créditos",
"If you have any questions please let us know.": "Si tienes más preguntas, por favor háznoslas saber.",
"Regards": "Atentamente",
"Getting started!": "¡Empezando!",
"Activity Logs": "Registros de Actividad",
"Dashboard": "Panel de control",
"No recent activity from cronjobs": "No hay actividad reciente de cronjobs",
"Are cronjobs running?": "¿Se están ejecutando los cronjobs?",
"Check the docs for it here": "Consulte la documentación aquí",
"Causer": "Causantes",
"Description": "Descripción",
"Application API": "Aplicación API",
"Create": "Crear",
"Memo": "Memo",
"Submit": "Enviar",
"Create new": "Crear nuevo",
"Token": "Token",
"Last used": "Último Uso",
"Are you sure you wish to delete?": "¿Está seguro que desea borrarlo?",
"Nests": "Nidos",
"Sync": "Sincronizar Ahora",
"Active": "Activo",
"ID": "ID",
"eggs": "huevos",
"Name": "Nombre",
"Nodes": "Nodos",
"Location": "Ubicación",
"Admin Overview": "Vista de Administrador",
"Support server": "Servidor de Ayuda",
"Documentation": "Documentación",
"Github": "Github",
"Support ControlPanel": "Apoya ControlPanel",
"Servers": "Servidores",
"Total": "Total",
"Payments": "Pagos",
"Pterodactyl": "Pterodactyl",
"Resources": "Recursos",
"Count": "Contador",
"Locations": "Localizaciones",
"Eggs": "Huevos",
"Last updated :date": "Ultima actualización :date",
"Download all Invoices": "Descargar todas las facturas",
"Product Price": "Precio del producto",
"Tax Value": "Valor Impuestos",
"Tax Percentage": "Porcentaje Impuestos",
"Total Price": "Precio Total",
"Payment ID": "ID del pago",
"Payment Method": "Método de Pago",
"Products": "Productos",
"Product Details": "Detalles del Producto",
"Disabled": "Deshabilitado",
"Will hide this option from being selected": "Ocultará esta opción para que no se seleccione",
"Price in": "Precio en",
"Memory": "Ram",
"Cpu": "Cpu",
"Swap": "Swap",
"This is what the users sees": "Esto es lo que ven los usuarios",
"Disk": "Disco",
"Minimum": "Mínimo",
"Setting to -1 will use the value from configuration.": "Si se establece en -1, se utilizará el valor de la configuración.",
"IO": "IO",
"Databases": "Bases de Datos",
"Backups": "Copias de Seguridad",
"Allocations": "Asignaciones",
"Product Linking": "Vinculación de Productos",
"Link your products to nodes and eggs to create dynamic pricing for each option": "Vincula tus productos a nodos y huevos para crear precios dinámicos para cada opción",
"This product will only be available for these nodes": "Este producto solo está disponible para estos nodos",
"This product will only be available for these eggs": "Este producto solo esta disponible para estos huevos",
"Product": "Producto",
"CPU": "CPU",
"Updated at": "Última Actualización",
"User": "Usuario",
"Config": "Configuración",
"Suspended at": "Suspendido en",
"Settings": "Configuraciones",
"The installer is not locked!": "¡El instalador no está bloqueado!",
"please create a file called \"install.lock\" in your dashboard Root directory. Otherwise no settings will be loaded!": "cree un archivo llamado \"install.lock\" en el directorio Raíz de su tablero. ¡De lo contrario, no se cargará ninguna configuración!",
"or click here": "o haga clic aquí",
"Company Name": "Nombre Empresa",
"Company Adress": "Dirección de la Empresa",
"Company Phonenumber": "Número de teléfono de la empresa",
"VAT ID": "ID de IVA",
"Company E-Mail Adress": "Dirección de correo electrónico de la empresa",
"Company Website": "Página Web de la empresa",
"Invoice Prefix": "Prefijo de factura",
"Enable Invoices": "Habilitar facturas",
"Logo": "Logo",
"Select Invoice Logo": "Seleccione el logotipo de la factura",
"Available languages": "Idiomas disponibles",
"Default language": "Idioma predeterminado",
"The fallback Language, if something goes wrong": "El lenguaje alternativo, si algo sale mal",
"Datable language": "Lenguaje de tabla de datos",
"The datatables lang-code. <br><strong>Example:<\/strong> en-gb, fr_fr, de_de<br>More Information: ": "El código de idioma de las tablas de datos. <br><strong>Ejemplo:<\/strong> en-gb, fr_fr, de_de<br>Más información: ",
"Auto-translate": "Traducir automáticamente",
"If this is checked, the Dashboard will translate itself to the Clients language, if available": "Si está marcado, el Tablero se traducirá solo al idioma del Cliente, si está disponible",
"Client Language-Switch": "Cambio de idioma del cliente",
"If this is checked, Clients will have the ability to manually change their Dashboard language": "Si esto está marcado, los Clientes tendrán la capacidad de cambiar manualmente el idioma de su Panel de Control",
"Mail Service": "Servicio de correo",
"The Mailer to send e-mails with": "El Mailer para enviar correos electrónicos con",
"Mail Host": "Host del correo",
"Mail Port": "Puerto del correo",
"Mail Username": "Nombre de usuario del correo",
"Mail Password": "Contraseña de correo",
"Mail Encryption": "Cifrado de correo",
"Mail From Adress": "Dirección del correo",
"Mail From Name": "Nombre del correo",
"Discord Client-ID": "Discord ID-Cliente",
"Discord Client-Secret": "Discord Secreto-Cliente",
"Discord Bot-Token": "Discord Bot-Token",
"Discord Guild-ID": "Identificación de Guild de Discord",
"Discord Invite-URL": "URL de invitación del servidor de Discord",
"Discord Role-ID": "ID del Rol de Discord",
"Enable ReCaptcha": "Habilitar ReCaptcha",
"ReCaptcha Site-Key": "Clave del sitio de ReCaptcha",
"ReCaptcha Secret-Key": "Clave secreta de ReCaptcha",
"PayPal Client-ID": "PayPal Cliente-ID",
"PayPal Secret-Key": "PayPal Clave-Secreta",
"PayPal Sandbox Client-ID": "PayPal Sandbox Cliente-ID",
"optional": "opcional",
"PayPal Sandbox Secret-Key": "PayPal Sandbox Clave-Secreta",
"Stripe Secret-Key": "Stripe Clave-Secreta",
"Stripe Endpoint-Secret-Key": "Stripe Extremo-Clave-Secreta",
"Stripe Test Secret-Key": "Stripe Test Clave-Secreta",
"Stripe Test Endpoint-Secret-Key": "Stripe Test Extremo-Clave-Secreta",
"Payment Methods": "Métodos de Pago",
"Tax Value in %": "Valor Impuestos en %",
"System": "Sistema",
"Register IP Check": "Registrar comprobación de IP",
"Prevent users from making multiple accounts using the same IP address.": "Evite que los usuarios creen varias cuentas con la misma dirección IP.",
"Charge first hour at creation": "Carga la primera hora en la creación",
"Charges the first hour worth of credits upon creating a server.": "Carga la primera hora de créditos al crear un servidor.",
"Credits Display Name": "Nombre de los Créditos para mostrar",
"PHPMyAdmin URL": "PHPMyAdmin URL",
"Enter the URL to your PHPMyAdmin installation. <strong>Without a trailing slash!<\/strong>": "Ingrese la URL de su instalación de PHPMyAdmin. <strong>¡Sin una barra diagonal final!<\/strong>",
"Pterodactyl URL": "Pterodactyl URL",
"Enter the URL to your Pterodactyl installation. <strong>Without a trailing slash!<\/strong>": "Introduzca la URL de su instalación de Pterodactyl. <strong>¡Sin una barra diagonal final!<\/strong>",
"Pterodactyl API Key": "Pterodactyl API Key",
"Enter the API Key to your Pterodactyl installation.": "Ingrese la API Key para su instalación de Pterodactyl.",
"Force Discord verification": "Forzar verificación de Discord",
"Force E-Mail verification": "Forzar verificación de E-Mail",
"Initial Credits": "Créditos Iniciales",
"Initial Server Limit": "Límite inicial de servidor",
"Credits Reward Amount - Discord": "Cantidad de recompensa de créditos - Discord",
"Credits Reward Amount - E-Mail": "Cantidad de recompensa de créditos: E-Mail",
"Server Limit Increase - Discord": "Aumento del límite de servidor - Discord",
"Server Limit Increase - E-Mail": "Aumento del límite de servidor: E-Mail",
"Server": "Servidor",
"Server Allocation Limit": "Límite de asignación del servidor",
"The maximum amount of allocations to pull per node for automatic deployment, if more allocations are being used than this limit is set to, no new servers can be created!": "La cantidad máxima de asignaciones para extraer por nodo para la implementación automática, si se utilizan más asignaciones que las establecidas en este límite, ¡no se pueden crear nuevos servidores!",
"Select panel icon": "Seleccionar icono de panel",
"Select panel favicon": "Seleccionar favicon del panel",
"Store": "Tienda",
"Currency code": "Código de divisa\/moneda",
"Checkout the paypal docs to select the appropriate code": "Consulte los documentos de PayPal para seleccionar el código apropiado",
"Quantity": "Cantidad",
"Amount given to the user after purchasing": "Importe dado al usuario después de la compra",
"Display": "Mostrar",
"This is what the user sees at store and checkout": "Esto es lo que ve el usuario en la tienda y al finalizar la compra",
"Adds 1000 credits to your account": "Agrega 1000 créditos a su cuenta",
"This is what the user sees at checkout": "Esto es lo que ve el usuario al finalizar la compra",
"No payment method is configured.": "No hay ningún método de pago configurado.",
"To configure the payment methods, head to the settings-page and add the required options for your prefered payment method.": "To configure the payment methods, head to the settings-page and add the required options for your prefered payment method.",
"Useful Links": "Enlaces útiles",
"Icon class name": "Nombre de la clase de icono",
"You can find available free icons": "Puedes encontrar iconos gratuitos disponibles",
"Title": "Titulo",
"Link": "Enlace",
"description": "descripción",
"Icon": "Icono",
"Username": "Nombre de usuario",
"Email": "Email",
"Pterodactyl ID": "Pterodactyl ID",
"This ID refers to the user account created on pterodactyls panel.": "Esta ID se refiere a la cuenta de usuario creada en el panel de pterodactyl.",
"Only edit this if you know what youre doing :)": "Edite esto solo si sabe lo que está haciendo :)",
"Server Limit": "Limite Servidor",
"Role": "Rol",
" Administrator": " Administrador",
"Client": "Cliente",
"Member": "Miembro",
"New Password": "Nueva Contraseña",
"Confirm Password": "Confirmar Contraseña",
"Notify": "Notificar",
"Avatar": "Avatar",
"Verified": "Verificado",
"Last seen": "Visto por ùltima vez",
"Notifications": "Notificaciones",
"All": "Todos",
"Send via": "Enviar vía",
"Database": "Base de Datos",
"Content": "Contenido",
"Server limit": "Limite Servidores",
"Discord": "Discord",
"Usage": "Uso",
"IP": "IP",
"Vouchers": "Descuentos",
"Voucher details": "Detalles del vale",
"Summer break voucher": "Descuento de vacaciones de verano",
"Code": "Código",
"Random": "Aleatorio",
"Uses": "Usos",
"A voucher can only be used one time per user. Uses specifies the number of different users that can use this voucher.": "El descuento solo se puede utilizar una vez por usuario. Los usos especifica el número de usuarios diferentes que pueden utilizar este cupón.",
"Max": "Máx",
"Expires at": "Expira el",
"Used \/ Uses": "Uso \/ Usos",
"Expires": "Expira",
"Sign in to start your session": "Iniciar sesión para comenzar",
"Password": "Contraseña",
"Remember Me": "Recuérdame",
"Sign In": "Iniciar sesión",
"Forgot Your Password?": "¿Olvidó su contraseña?",
"Register a new membership": "Registrar un nuevo miembro",
"Please confirm your password before continuing.": "Por favor confirme su contraseña antes de continuar.",
"You forgot your password? Here you can easily retrieve a new password.": "¿Olvidaste tu contraseña? Aquí puede recuperar fácilmente una nueva contraseña.",
"Request new password": "Solicitar nueva contraseña",
"Login": "Iniciar sesión",
"You are only one step a way from your new password, recover your password now.": "Está a solo un paso de su nueva contraseña, recupere su contraseña ahora.",
"Retype password": "Vuelva a escribir la contraseña",
"Change password": "Cambiar contraseña",
"Register": "Registrar",
"I already have a membership": "Ya soy miembro",
"Verify Your Email Address": "Verifica Tu Email",
"A fresh verification link has been sent to your email address.": "Se ha enviado un nuevo enlace de verificación a su correo electrónico.",
"Before proceeding, please check your email for a verification link.": "Antes de continuar, por favor, confirme su correo electrónico con el enlace de verificación que le fue enviado.",
"If you did not receive the email": "Si no ha recibido el correo electrónico",
"click here to request another": "haga clic aquí para solicitar otro",
"per month": "al mes",
"Out of Credits in": "Sin créditos en",
"Home": "Inicio",
"Language": "Idioma",
"See all Notifications": "Ver todas las notificaciones",
"Redeem code": "Canjear código",
"Profile": "Perfil",
"Log back in": "Volver a iniciar sesión",
"Logout": "Cerrar sesión",
"Administration": "Administración",
"Overview": "Resumen",
"Management": "Gestión",
"Other": "Otro",
"Logs": "Logs",
"Warning!": "¡Advertencia!",
"You have not yet verified your email address": "No has verificado tu correo electrónico",
"Click here to resend verification email": "Haz click aquí para reenviar tu correo electrónico de activación",
"Please contact support If you didnt receive your verification email.": "Contacte con el soporte si no recibió su correo electrónico de verificación.",
"Thank you for your purchase!": "¡Gracias por su compra!",
"Your payment has been confirmed; Your credit balance has been updated.": "Su pago ha sido confirmado; Se actualizó su saldo de crédito.",
"Thanks": "Gracias",
"Redeem voucher code": "Canjear código de descuento",
"Close": "Cerrar",
"Redeem": "Canjear",
"All notifications": "Todas las notificaciones",
"Required Email verification!": "¡Se requiere verificación de correo electrónico!",
"Required Discord verification!": "¡Se requiere verificación de Discord!",
"You have not yet verified your discord account": "Aún no has verificado tu cuenta de discord",
"Login with discord": "Acceder con Discord",
"Please contact support If you face any issues.": "Póngase en contacto con soporte si tiene algún problema.",
"Due to system settings you are required to verify your discord account!": "¡Debido a la configuración del sistema, debe verificar su cuenta de discord!",
"It looks like this hasnt been set-up correctly! Please contact support.": "¡Parece que esto no se ha configurado correctamente! Comuníquese con el soporte.",
"Change Password": "Cambiar Contraseña",
"Current Password": "Contraseña Actual",
"Link your discord account!": "¡Vincular tu cuenta de Discord!",
"By verifying your discord account, you receive extra Credits and increased Server amounts": "Al verificar su cuenta de discord, recibe créditos adicionales y aumenta su limite de cantidad de servidores",
"Login with Discord": "Iniciar sesión con Discord",
"You are verified!": "¡Estás verificado!",
"Re-Sync Discord": "Re-Sincronizar Discord",
"Save Changes": "Guardar Cambios",
"Server configuration": "Configuración del servidor",
"Make sure to link your products to nodes and eggs.": "Asegúrese de vincular sus productos a nodos y huevos.",
"There has to be at least 1 valid product for server creation": "Tiene que haber al menos 1 producto válido para la creación del servidor",
"Sync now": "Sincronizar ahora",
"No products available!": "¡No hay productos disponibles!",
"No nodes have been linked!": "¡No se han vinculado nodos!",
"No nests available!": "¡No hay nidos disponibles!",
"No eggs have been linked!": "¡No se han vinculado huevos!",
"Software \/ Games": "Software \/ Juegos",
"Please select software ...": "Seleccione el software...",
"---": "---",
"Specification ": "Especificación ",
"Node": "Nodo",
"Resource Data:": "Datos de recursos:",
"vCores": "vCores",
"MB": "MB",
"MySQL": "MySQL",
"ports": "puertos",
"Not enough": "No es suficiente",
"Create server": "Crear Servidor",
"Please select a node ...": "Por favor, seleccione un nodo...",
"No nodes found matching current configuration": "No se encontraron nodos que coincidan con la configuración actual",
"Please select a resource ...": "Por favor, seleccione un recurso ...",
"No resources found matching current configuration": "No se encontraron recursos que coincidan con la configuración actual",
"Please select a configuration ...": "Por favor elija su configuración...",
"Not enough credits!": "¡No tiene suficientes créditos!",
"Create Server": "Crear Servidor",
"Software": "Software",
"Specification": "Especificaciones",
"Resource plan": "Plan de recursos",
"RAM": "RAM",
"MySQL Databases": "Bases de datos MySQL",
"per Hour": "por Hora",
"per Month": "por Mes",
"Manage": "Gestionar",
"Are you sure?": "¿Estas seguro?",
"This is an irreversible action, all files of this server will be removed.": "Esta es una acción irreversible, se eliminarán todos los archivos de este servidor.",
"Yes, delete it!": "Si, borralo",
"No, cancel!": "No, cancelar",
"Canceled ...": "Cancelado ...",
"Deletion has been canceled.": "Se canceló la eliminación.",
"Date": "Fecha",
"Subtotal": "Subtotal",
"Amount Due": "Cantidad Adeudada",
"Tax": "Impuesto",
"Submit Payment": "Proceder al Pago",
"Purchase": "Comprar",
"There are no store products!": "¡No hay productos de la tienda!",
"The store is not correctly configured!": "¡La tienda no está configurada correctamente!",
"Serial No.": "Nº Serie.",
"Invoice date": "Fecha de Factura",
"Seller": "Vendedor",
"Buyer": "Comprador",
"Address": "Dirección",
"VAT Code": "Código de IVA",
"Phone": "Teléfono",
"Units": "Unidades",
"Discount": "Descuento",
"Total discount": "Descuento total",
"Taxable amount": "Base imponible",
"Tax rate": "Tasa de impuestos",
"Total taxes": "Total de impuestos",
"Shipping": "Envío",
"Total amount": "Cantidad total",
"Notes": "Notas",
"Amount in words": "Cantidad en palabras",
"Please pay until": "Por favor pague hasta",
"Key": "Clave",
"Value": "Valor",
"Edit Configuration": "Editar Configuración",
"Text Field": "Campo de texto",
"Cancel": "Cancelar",
"Save": "Guardar",
"Images and Icons may be cached, reload without cache to see your changes appear": "Las imágenes y los íconos pueden almacenarse en caché, vuelva a cargar sin caché para ver sus cambios",
"Enter your companys name": "Introduce el nombre de tu empresa",
"Enter your companys address": "Ingrese la dirección de su empresa",
"Enter your companys phone number": "Ingrese el número de teléfono de su empresa",
"Enter your companys VAT id": "Ingrese el ID de IVA de su empresa",
"Enter your companys email address": "Ingrese la dirección de correo electrónico de su empresa",
"Enter your companys website": "Ingresa la web de tu empresa",
"Enter your custom invoice prefix": "Ingrese su prefijo de factura personalizado",
"The Language of the Datatables. Grab the Language-Codes from here": "El lenguaje de las tablas de datos. Coge los códigos de idioma de aquí",
"Let the Client change the Language": "Dejar que el cliente cambie el idioma",
"Icons updated!": "¡Iconos actualizados!",
"cs": "Checo",
"de": "Alemán",
"en": "Inglés",
"es": "Español",
"fr": "Francés",
"hi": "Hindi",
"it": "Italiano",
"nl": "Holandés",
"pl": "Polaco",
"zh": "Chino",
"tr": "Turco",
"ru": "Ruso"
}

View file

@ -0,0 +1,18 @@
<?php
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
return [
'failed' => 'Estas credenciales no coinciden con nuestros registros.',
'password' => 'La contraseña ingresada no es correcta.',
'throttle' => 'Demasiados intentos de acceso. Por favor intente nuevamente en :seconds segundos.',
];

View file

@ -0,0 +1,17 @@
<?php
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
return [
'next' => 'Siguiente &raquo;',
'previous' => '&laquo; Anterior',
];

View file

@ -0,0 +1,20 @@
<?php
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
return [
'reset' => '¡Su contraseña ha sido restablecida!',
'sent' => '¡Le hemos enviado por correo electrónico el enlace para restablecer su contraseña!',
'throttled' => 'Por favor espere antes de intentar de nuevo.',
'token' => 'El token de restablecimiento de contraseña es inválido.',
'user' => 'No encontramos ningún usuario con ese correo electrónico.',
];

View file

@ -0,0 +1,138 @@
<?php
/*
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
return [
'accepted' => ':attribute debe ser aceptado.',
'accepted_if' => ':attribute debe ser aceptado cuando :other sea :value.',
'active_url' => ':attribute no es una URL válida.',
'after' => ':attribute debe ser una fecha posterior a :date.',
'after_or_equal' => ':attribute debe ser una fecha posterior o igual a :date.',
'alpha' => ':attribute sólo debe contener letras.',
'alpha_dash' => ':attribute sólo debe contener letras, números, guiones y guiones bajos.',
'alpha_num' => ':attribute sólo debe contener letras y números.',
'array' => ':attribute debe ser un conjunto.',
'attached' => 'Este :attribute ya se adjuntó.',
'before' => ':attribute debe ser una fecha anterior a :date.',
'before_or_equal' => ':attribute debe ser una fecha anterior o igual a :date.',
'between' => [
'array' => ':attribute tiene que tener entre :min - :max elementos.',
'file' => ':attribute debe pesar entre :min - :max kilobytes.',
'numeric' => ':attribute tiene que estar entre :min - :max.',
'string' => ':attribute tiene que tener entre :min - :max caracteres.',
],
'boolean' => 'El campo :attribute debe tener un valor verdadero o falso.',
'confirmed' => 'La confirmación de :attribute no coincide.',
'current_password' => 'La contraseña es incorrecta.',
'date' => ':attribute no es una fecha válida.',
'date_equals' => ':attribute debe ser una fecha igual a :date.',
'date_format' => ':attribute no corresponde al formato :format.',
'declined' => ':attribute debe ser rechazado.',
'declined_if' => ':attribute debe ser rechazado cuando :other sea :value.',
'different' => ':attribute y :other deben ser diferentes.',
'digits' => ':attribute debe tener :digits dígitos.',
'digits_between' => ':attribute debe tener entre :min y :max dígitos.',
'dimensions' => 'Las dimensiones de la imagen :attribute no son válidas.',
'distinct' => 'El campo :attribute contiene un valor duplicado.',
'email' => ':attribute no es un correo válido.',
'ends_with' => 'El campo :attribute debe finalizar con uno de los siguientes valores: :values',
'exists' => ':attribute es inválido.',
'file' => 'El campo :attribute debe ser un archivo.',
'filled' => 'El campo :attribute es obligatorio.',
'gt' => [
'array' => 'El campo :attribute debe tener más de :value elementos.',
'file' => 'El campo :attribute debe tener más de :value kilobytes.',
'numeric' => 'El campo :attribute debe ser mayor que :value.',
'string' => 'El campo :attribute debe tener más de :value caracteres.',
],
'gte' => [
'array' => 'El campo :attribute debe tener como mínimo :value elementos.',
'file' => 'El campo :attribute debe tener como mínimo :value kilobytes.',
'numeric' => 'El campo :attribute debe ser como mínimo :value.',
'string' => 'El campo :attribute debe tener como mínimo :value caracteres.',
],
'image' => ':attribute debe ser una imagen.',
'in' => ':attribute es inválido.',
'in_array' => 'El campo :attribute no existe en :other.',
'integer' => ':attribute debe ser un número entero.',
'ip' => ':attribute debe ser una dirección IP válida.',
'ipv4' => ':attribute debe ser una dirección IPv4 válida.',
'ipv6' => ':attribute debe ser una dirección IPv6 válida.',
'json' => 'El campo :attribute debe ser una cadena JSON válida.',
'lt' => [
'array' => 'El campo :attribute debe tener menos de :value elementos.',
'file' => 'El campo :attribute debe tener menos de :value kilobytes.',
'numeric' => 'El campo :attribute debe ser menor que :value.',
'string' => 'El campo :attribute debe tener menos de :value caracteres.',
],
'lte' => [
'array' => 'El campo :attribute debe tener como máximo :value elementos.',
'file' => 'El campo :attribute debe tener como máximo :value kilobytes.',
'numeric' => 'El campo :attribute debe ser como máximo :value.',
'string' => 'El campo :attribute debe tener como máximo :value caracteres.',
],
'max' => [
'array' => ':attribute no debe tener más de :max elementos.',
'file' => ':attribute no debe ser mayor que :max kilobytes.',
'numeric' => ':attribute no debe ser mayor que :max.',
'string' => ':attribute no debe ser mayor que :max caracteres.',
],
'mimes' => ':attribute debe ser un archivo con formato: :values.',
'mimetypes' => ':attribute debe ser un archivo con formato: :values.',
'min' => [
'array' => ':attribute debe tener al menos :min elementos.',
'file' => 'El tamaño de :attribute debe ser de al menos :min kilobytes.',
'numeric' => 'El tamaño de :attribute debe ser de al menos :min.',
'string' => ':attribute debe contener al menos :min caracteres.',
],
'multiple_of' => 'El campo :attribute debe ser múltiplo de :value',
'not_in' => ':attribute es inválido.',
'not_regex' => 'El formato del campo :attribute no es válido.',
'numeric' => ':attribute debe ser numérico.',
'password' => 'La contraseña es incorrecta.',
'present' => 'El campo :attribute debe estar presente.',
'prohibited' => 'El campo :attribute está prohibido.',
'prohibited_if' => 'El campo :attribute está prohibido cuando :other es :value.',
'prohibited_unless' => 'El campo :attribute está prohibido a menos que :other sea :values.',
'prohibits' => 'El campo :attribute prohibe que :other esté presente.',
'regex' => 'El formato de :attribute es inválido.',
'relatable' => 'Este :attribute no se puede asociar con este recurso',
'required' => 'El campo :attribute es obligatorio.',
'required_if' => 'El campo :attribute es obligatorio cuando :other es :value.',
'required_unless' => 'El campo :attribute es obligatorio a menos que :other esté en :values.',
'required_with' => 'El campo :attribute es obligatorio cuando :values está presente.',
'required_with_all' => 'El campo :attribute es obligatorio cuando :values están presentes.',
'required_without' => 'El campo :attribute es obligatorio cuando :values no está presente.',
'required_without_all' => 'El campo :attribute es obligatorio cuando ninguno de :values está presente.',
'same' => ':attribute y :other deben coincidir.',
'size' => [
'array' => ':attribute debe contener :size elementos.',
'file' => 'El tamaño de :attribute debe ser :size kilobytes.',
'numeric' => 'El tamaño de :attribute debe ser :size.',
'string' => ':attribute debe contener :size caracteres.',
],
'starts_with' => 'El campo :attribute debe comenzar con uno de los siguientes valores: :values',
'string' => 'El campo :attribute debe ser una cadena de caracteres.',
'timezone' => ':Attribute debe ser una zona horaria válida.',
'unique' => 'El campo :attribute ya ha sido registrado.',
'uploaded' => 'Subir :attribute ha fallado.',
'url' => ':Attribute debe ser una URL válida.',
'uuid' => 'El campo :attribute debe ser un UUID válido.',
'custom' => [
'email' => [
'unique' => 'El :attribute ya ha sido registrado.',
],
'password' => [
'min' => 'La :attribute debe contener más de :min caracteres',
],
],
];

328
resources/lang/fr.json Normal file
View file

@ -0,0 +1,328 @@
{
"Activity Logs": "Journal des activités",
"No recent activity from cronjobs": "Aucune activité récente de cronjobs",
"Check the docs for it here": "Consultez la documentation ici",
"Are cronjobs running?": "Les tâches cron sont-elles en cours d'exécution ?",
"Causer": "Cause",
"Description": "Description",
"Created at": "Créé à",
"Edit Configuration": "Modifier la configuration",
"Text Field": "Champ de texte",
"Cancel": "Annuler",
"Close": "Fermer",
"Save": "Sauvegarder",
"true": "vrai",
"false": "faux",
"Configurations": "Configuration",
"Dashboard": "Tableau de bord",
"Key": "Clé",
"Value": "Valeur",
"Type": "Type",
"Admin Overview": "Vue administrateur",
"Support server": "Serveur de support",
"Documentation": "Documentation",
"Github": "Github",
"Support ControlPanel": "ControlPanel Support",
"Servers": "Serveurs",
"Users": "Utilisateurs",
"Total": "Total",
"Payments": "Paiments",
"Pterodactyl": "Pterodactyl",
"Sync": "Synchroniser",
"Resources": "Ressources",
"Count": "Nombre",
"Locations": "Emplacements",
"Node": "Node",
"Nodes": "Nœuds",
"Nests": "Nids",
"Eggs": "Œufs",
"Last updated :date": "Dernière mise à jour",
"Purchase": "Acheter",
"ID": "IDENTIFIANT",
"User": "Utilisateur",
"Amount": "Montant ",
"Product Price": "Prix du produit",
"Tax": "Tva & autres taxes",
"Total Price": "Prix total",
"Payment_ID": "ID_PAIEMENT",
"Payer_ID": "Payer_ID",
"Product": "Article",
"Products": "Produits",
"Create": "Créer",
"Product Details": "Détails du produit",
"Server Details": "Détails du serveur",
"Product Linking": "Lien du produit",
"Name": "Nom",
"Price in": "Prix en",
"Memory": "Mémoire",
"Cpu": "Cpu",
"Swap": "Swap",
"Disk": "Disque",
"Minimum": "Minimum",
"IO": "IO",
"Databases": "Bases de données",
"Database": "Base de donnée",
"Backups": "Sauvegardes",
"Allocations": "Allocations",
"Disabled": "Désactivé",
"Submit": "Valider",
"This product will only be available for these nodes": "Ce produit est uniquement disponible pour cette node",
"This product will only be available for these eggs": "Ce produit n'est pas disponible pour cet eggs",
"Will hide this option from being selected": "Cachera cette option",
"Link your products to nodes and eggs to create dynamic pricing for each option": "Liez vos produits à des nodes et des eggs pour créer une tarification dynamique pour chaque option",
"Setting to -1 will use the value from configuration.": "Le réglage à -1 utilisera la valeur de la configuration.",
"This is what the users sees": "C'est ce que voient les utilisateurs",
"Edit": "Modifier",
"Price": "Prix",
"Are you sure you wish to delete?": "Êtes-vous sûr de vouloir supprimer ?",
"Create new": "Créer nouveau",
"Show": "Voir",
"Updated at": "Mis à jour le",
"Suspended at": "Suspendus le",
"Settings": "Paramètres",
"Dashboard icons": "Icônes du tableau de bord",
"Select panel icon": "Sélectionner l'icône du panel",
"Select panel favicon": "Sélectionner le favicon du panel",
"Token": "Token",
"Last used": "Dernière utilisation",
"Store": "Boutique",
"Currency code": "Code de devise",
"Checkout the paypal docs to select the appropriate code": "Vérifiez la doc de paypal pour sélectionner le code approprié",
"Quantity": "Quantité",
"Amount given to the user after purchasing": "Montant donné à l'utilisateur après l'achat",
"Display": "Affichage",
"This is what the user sees at store and checkout": "C'est ce que l'utilisateur voit dans la boutique et au moment de payé",
"This is what the user sees at checkout": "C'est ce que l'utilisateur voit dans au moment de payé",
"Adds 1000 credits to your account": "Ajoute 1000 crédits à votre compte",
"Active": "Actif",
"Paypal is not configured.": "Paypal n'est pas configuré.",
"To configure PayPal, head to the .env and add your PayPals client id and secret.": "Pour configurer PayPal, rendez-vous sur le fichier .env et ajoutez votre identifiant \"client id\" PayPal et votre \"client id secret\".",
"Useful Links": "Liens Utiles",
"Icon class name": "Nom de la classe de l'icône",
"You can find available free icons": "Vous pouvez trouver des icônes gratuites",
"Title": "Titre",
"Link": "Lien",
"Username": "Nom d'utilisateur",
"Email": "Adresse email",
"Pterodactly ID": "ID Pterodactyl",
"Server Limit": "Limite Serveur",
"Role": "Rôle",
"Administrator": "Administrateur",
"Client": "Client",
"Member": "Membre",
"New Password": "Nouveau mot de passe",
"Confirm Password": "Confirmez le mot de passe",
"This ID refers to the user account created on pterodactyls panel.": "Cet identifiant fait référence au compte utilisateur créé sur le panel Pterodactyl.",
"Only edit this if you know what youre doing :)": "Ne l'activez que si vous savez ce que vous faites.",
"Verified": "Verifié",
"Last seen": "Etait ici",
"Notify": "Notifier",
"All": "Tout",
"Send via": "Envoyer via",
"Content": "Contenu",
"Notifications": "Notifications",
"Usage": "Utilisation",
"Config": "Configuration",
"Vouchers": "Coupons",
"Voucher details": "Détails du bon de réduction",
"Memo": "Mémo",
"Code": "Code",
"Uses": "Utilisations",
"Expires at": "Expire à",
"Max": "Max",
"Random": "Aléatoire",
"Status": "Statut",
"Used / Uses": "Utilisé / Utilisations",
"Expires": "Expire",
"Please confirm your password before continuing.": "Veuillez confirmer votre mot de passe avant de continuer.",
"Password": "Mot de passe",
"Forgot Your Password?": "Mot de passe oublié ?",
"Sign in to start your session": "Identifiez-vous pour commencer votre session",
"Remember Me": "Se souvenir de moi",
"Sign In": "S'enregistrer",
"Register a new membership": "Enregistrer un nouveau membre",
"You forgot your password? Here you can easily retrieve a new password.": "Tu as oublie ton mot de passe ? Ici tu peux facilement le changé.",
"Request new password": "Changer son mot de passe",
"Login": "Connexion",
"You are only one step a way from your new password, recover your password now.": "Vous n'êtes qu'à une étape de votre nouveau mot de passe, récupérez votre mot de passe maintenant.",
"Retype password": "Retapez le mot de passe",
"Change password": "Changer le mot de passe",
"I already have a membership": "Je possède déjà un compte",
"Register": "Inscription",
"Verify Your Email Address": "Vérifiez votre adresse email",
"A fresh verification link has been sent to your email address.": "Un nouveau lien de vérification a été envoyé à votre adresse email.",
"Before proceeding, please check your email for a verification link.": "Avant de continuer, veuillez vérifier vos emails, vous devriez avoir reçu un lien de vérification.",
"If you did not receive the email": "Si vous ne recevez pas l'e-mail",
"click here to request another": "cliquez ici pour faire une nouvelle demande",
"Home": "Accueil",
"Languages": "Langues",
"See all Notifications": "Voir toutes les notifications",
"Profile": "Profil",
"Log back in": "Reconnectez-vous",
"Logout": "Déconnexion",
"Administration": "Administration",
"Overview": "Récapitulatif",
"Application API": "Application API",
"Management": "Gestion",
"Other": "Autre",
"Logs": "Logs",
"Redeem code": "Utiliser un code",
"You have not yet verified your email address": "Vous n'avez pas vérifiez votre adresse mail",
"Click here to resend verification email": "Cliquez ici pour renvoyer un mail de confirmation",
"Please contact support If you didnt receive your verification email.": "Veuillez contacter le support si vous n'avez pas reçu votre e-mail de vérification.",
"Thank you for your purchase!": "Merci pour votre achat !",
"Your payment has been confirmed; Your credit balance has been updated.": "Votre paiement à été accepter, Vos crédits son maintenant disponible sur votre compte.",
"Payment ID": "ID du paiement",
"Balance": "Solde",
"User ID": "ID d'utilisateur",
"Thanks": "Merci",
"Redeem voucher code": "Utiliser le code",
"Redeem": "Appliquer",
"All notifications": "Toutes les notifications",
"Required Email verification!": "La vérification du mail est requise !",
"Required Discord verification!": "Vérification de votre discord est requise !",
"You have not yet verified your discord account": "Vous n'avez pas vérifiez votre compte discord",
"Login with discord": "Se connecter avec Discord",
"Please contact support If you face any issues.": "Veuillez contacter le support si vous rencontrez des problèmes.",
"Due to system settings you are required to verify your discord account!": "En raison des paramètres système, vous devez vérifier votre compte Discord !",
"It looks like this hasnt been set-up correctly! Please contact support.": "Il semble que cela n'a pas été configuré correctement ! Veuillez contacter le support.",
"Change Password": "Modifier le mot de passe",
"Current Password": "Mot de passe actuel",
"Save Changes": "Sauvegarder les modifications",
"Re-Sync Discord": "Resynchroniser Discord",
"You are verified!": "Vous êtes vérifié !",
"By verifying your discord account, you receive extra Credits and increased Server amounts": "En vérifiant votre compte discord, vous recevez des crédits supplémentaires et la possibilité d'avoir plus de serveur",
"Server configuration": "Configuration du serveur",
"Error!": "Erreur !",
"Make sure to link your products to nodes and eggs.": "Assurez-vous de lier vos produits aux nodes aux eggs.",
"There has to be at least 1 valid product for server creation": "Il doit y avoir au moins 1 produit valide pour la création de serveur",
"No products available!": "Aucun produit disponible !",
"No nodes have been linked!": "Aucune node n'a été lié !",
"No nests available!": "Aucun nests disponible !",
"No eggs have been linked!": "Aucun eggs n'a été lié !",
"Software / Games": "Logiciels / Jeux",
"Please select software ...": "Veuillez sélectionner...",
"Specification": "Spécification",
"No selection": "Pas de sélection",
"per month": "par mois",
"Not enough credits!": "Pas assez de crédits !",
"Please select a configuration ...": "Veuillez sélectionner une configuration...",
"No resources found matching current configuration": "Aucune ressources trouvée pour la configuration actuelle",
"No nodes found matching current configuration": "Aucune node trouvée pour la configuration actuelle",
"Please select a node ...": "Veuillez sélectionner une node...",
"Create server": "Créer le serveur",
"Use your servers on our": "Utilisez vos serveurs sur notre",
"pterodactyl panel": "panel pterodactyl",
"Server limit reached!": "Limite de serveurs atteinte !",
"Create Server": "Créer le serveur",
"Manage": "Gérer",
"Delete server": "Supprimer le serveur",
"Price per Hour": "Prix par heure",
"Price per Month": "Prix par Mois",
"Date": "Date",
"To": "À",
"From": "De",
"Pending": "En attente",
"Subtotal": "Sous-total",
"Submit Payment": "Soumettre le Paiement",
"Payment Methods": "Moyens de paiement",
"By purchasing this product you agree and accept our terms of service": "En achetant ce produit, vous acceptez et acceptez nos conditions d'utilisation",
"There are no store products!": "Il n'y a plus de produits dans la boutique !",
"The store is not correctly configured!": "La boutique n'est pas configurée correctement !",
"Out of Credits in": "Hors crédits dans",
"days": "jours",
"hours": "heures",
"You ran out of Credits": "Vous navez plus de crédits",
"Profile updated": "Profil mis à jour",
"You are required to verify your email address before you can create a server.": "Vous devez vérifier votre email avant de pouvoir créer un serveur.",
"You are required to link your discord account before you can create a server.": "Vous devez vérifier votre discord avant de pouvoir créer un serveur.",
"No allocations satisfying the requirements for automatic deployment on this node were found.": "Aucune allocation répondant aux exigences de déploiement automatique sur cette node n'a été trouvée.",
"Server removed": "Serveur supprimé",
"Server created": "Serveur créé",
"An exception has occurred while trying to remove a resource \"": "Une erreur s'est produite en essayant de supprimer la ressource",
"You are required to verify your email address before you can purchase credits.": "Vous devez vérifier votre email avant de pouvoir acheter des crédits.",
"You are required to link your discord account before you can purchase ": "Vous devez vérifier votre compte discord avant de pouvoir acheter des crédits ",
"Warning!": "Attention !",
"api key created!": "La clé Api a été créée !",
"api key updated!": "La clé Api a été modifiée !",
"api key has been removed!": "La clé Api a été supprimée !",
"configuration has been updated!": "la configuration a été mise à jour!",
"Pterodactyl synced": "Synchroniser Pterodactyl",
"Your credit balance has been increased!": "Votre solde a été augmenté !",
"Payment was Canceled": "Le paiement a été annulé",
"Store item has been created!": "L'article de la boutique a été créé !",
"Store item has been updated!": "L'article de la boutique a été mis à jour !",
"Product has been updated!": "Produit mis à jour !",
"Store item has been removed!": "L'article de la boutique a été supprimé !",
"Product has been created!": "Produit a été créé !",
"Product has been removed!": "Produit a été supprimé !",
"Server has been updated!": "Le serveur à été mis à jour !",
"Icons updated!": "Icône mise à jour !",
"link has been created!": "Le lien à été créé !",
"link has been updated!": "Le lien à été mis à jour !",
"user has been removed!": "L'utilisateur a été supprimé !",
"Notification sent!": "Notification envoyée !",
"User has been updated!": "L'utilisateur a été mis à jour !",
"User does not exists on pterodactyl's panel": "L'utilisateur n'existe pas sur le panel pterodactyl",
"voucher has been created!": "Le code à été créé !",
"voucher has been updated!": "Le code à été mis à jour !",
"voucher has been removed!": "Le code à été supprimé !",
"This voucher has reached the maximum amount of uses": "Ce code a atteint le nombre maximum d'utilisations",
"This voucher has expired": "Ce code de réduction a expiré",
"You already redeemed this voucher code": "Vous avez déjà utilisé ce code promotionnel",
"You can't redeem this voucher because you would exceed the limit of ": "Vous ne pouvez pas utiliser ce bon car vous dépasseriez la limite de ",
"have been added to your balance!": "ont été ajoutés à votre solde !",
"Invoice": "Facture",
"Serial No.": "N° de série",
"Invoice date": "Date de la facture",
"Seller": "Vendeur",
"Buyer": "Acheteur",
"Address": "Adresse",
"VAT code": "Taux TVA",
"Phone": "Téléphone",
"Units": "Unités",
"Qty": "Qté",
"Discount": "Remise",
"Sub total": "Sous-total",
"Total discount": "Total des réductions",
"Taxable amount": "Montant taxable",
"Total taxes": "Total des taxes",
"Tax rate": "Taux de taxes",
"Total amount": "Montant total",
"Please pay until": "Veuillez payer avant",
"Amount in words": "Montant en toutes lettres",
"Notes": "Notes",
"Shipping": "Expédition",
"Paid": "Payé",
"Due:": "Du:",
"Invoice Settings": "Paramètres de facturation",
"Download all Invoices": "Télécharger toutes les factures",
"Enter your companys name": "Entrez le nom de votre entreprise",
"Enter your companys address": "Entrez l'adresse de votre entreprise",
"Enter your companys phone number": "Entrez le numéro de téléphone de votre entreprise",
"Enter your companys VAT id": "Entrez le site internet de votre entreprise",
"Enter your companys email address": "Entrez l'adresse mail de votre entreprise",
"Enter your companys website": "Entrez le site internet de votre entreprise",
"Enter your custom invoice prefix": "Entrez votre préfixe de facture personnalisé",
"Select Invoice Logo": "Sélectionnez le logo des factures",
"Payment Confirmation": "Confirmation de paiement",
"Payment Confirmed!": "Paiement confirmé !",
"Server Creation Error": "Erreur lors de la création de votre serveur",
"Your servers have been suspended!": "Votre serveur à été suspendu !",
"To automatically re-enable your server/s, you need to purchase more credits.": "Pour réactiver automatiquement votre ou vos serveurs, vous devez racheter des crédits.",
"Purchase credits": "Acheter des crédits",
"If you have any questions please let us know.": "N'hésitez pas à nous contacter si vous avez des questions.",
"Regards": "Cordialement",
"Getting started!": "Commencer !",
"EXPIRED": "EXPIRÉ",
"VALID": "VALIDE",
"Unsuspend": "Annuler la suspension",
"Suspend": "Suspendre",
"Delete": "Supprimer",
"Login as User": "Connectez-vous en tant qu'utilisateur",
"Clone": "Dupliquer",
"Amount due": "Montant à payer",
"Your Payment was successful!": "Votre paiement a été reçu avec succès !",
"Hello": "Bonjour",
"Your payment was processed successfully!": "Votre requête a été traitée avec succès."
}

View file

@ -0,0 +1,18 @@
<?php
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
return [
'failed' => 'Ces identifiants ne correspondent pas à nos enregistrements.',
'password' => 'Le mot de passe fourni est incorrect.',
'throttle' => 'Tentatives de connexion trop nombreuses. Veuillez essayer de nouveau dans :seconds secondes.',
];

View file

@ -0,0 +1,17 @@
<?php
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
return [
'next' => 'Suivant &raquo;',
'previous' => '&laquo; Précédent',
];

View file

@ -0,0 +1,20 @@
<?php
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
return [
'reset' => 'Votre mot de passe a été réinitialisé !',
'sent' => 'Nous vous avons envoyé par email le lien de réinitialisation du mot de passe !',
'throttled' => 'Veuillez patienter avant de réessayer.',
'token' => 'Ce jeton de réinitialisation du mot de passe n\'est pas valide.',
'user' => 'Aucun utilisateur n\'a été trouvé avec cette adresse email.',
];

Some files were not shown because too many files have changed in this diff Show more