fix: remove lemon + paddle things

This commit is contained in:
Andras Bacsai 2024-06-25 13:54:58 +02:00
parent f557cd0933
commit 3ebb35a5cd
12 changed files with 21 additions and 480 deletions

View File

@ -3,7 +3,6 @@
namespace App\Livewire\Subscription;
use App\Models\Team;
use Illuminate\Support\Facades\Http;
use Livewire\Component;
class Actions extends Component
@ -15,70 +14,6 @@ public function mount()
$this->server_limits = Team::serverLimit();
}
public function cancel()
{
try {
$subscription_id = currentTeam()->subscription->lemon_subscription_id;
if (! $subscription_id) {
throw new \Exception('No subscription found');
}
$response = Http::withHeaders([
'Accept' => 'application/vnd.api+json',
'Content-Type' => 'application/vnd.api+json',
'Authorization' => 'Bearer '.config('subscription.lemon_squeezy_api_key'),
])->delete('https://api.lemonsqueezy.com/v1/subscriptions/'.$subscription_id);
$json = $response->json();
if ($response->failed()) {
$error = data_get($json, 'errors.0.status');
if ($error === '404') {
throw new \Exception('Subscription not found.');
}
throw new \Exception(data_get($json, 'errors.0.title', 'Something went wrong. Please try again later.'));
} else {
$this->dispatch('success', 'Subscription cancelled successfully. Reloading in 5s.');
$this->dispatch('reloadWindow', 5000);
}
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function resume()
{
try {
$subscription_id = currentTeam()->subscription->lemon_subscription_id;
if (! $subscription_id) {
throw new \Exception('No subscription found');
}
$response = Http::withHeaders([
'Accept' => 'application/vnd.api+json',
'Content-Type' => 'application/vnd.api+json',
'Authorization' => 'Bearer '.config('subscription.lemon_squeezy_api_key'),
])->patch('https://api.lemonsqueezy.com/v1/subscriptions/'.$subscription_id, [
'data' => [
'type' => 'subscriptions',
'id' => $subscription_id,
'attributes' => [
'cancelled' => false,
],
],
]);
$json = $response->json();
if ($response->failed()) {
$error = data_get($json, 'errors.0.status');
if ($error === '404') {
throw new \Exception('Subscription not found.');
}
throw new \Exception(data_get($json, 'errors.0.title', 'Something went wrong. Please try again later.'));
} else {
$this->dispatch('success', 'Subscription resumed successfully. Reloading in 5s.');
$this->dispatch('reloadWindow', 5000);
}
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function stripeCustomerPortal()
{
$session = getStripeCustomerPortalSession(currentTeam());

View File

@ -15,22 +15,7 @@ public function team()
public function type()
{
if (isLemon()) {
$basic = explode(',', config('subscription.lemon_squeezy_basic_plan_ids'));
$pro = explode(',', config('subscription.lemon_squeezy_pro_plan_ids'));
$ultimate = explode(',', config('subscription.lemon_squeezy_ultimate_plan_ids'));
$subscription = $this->lemon_variant_id;
if (in_array($subscription, $basic)) {
return 'basic';
}
if (in_array($subscription, $pro)) {
return 'pro';
}
if (in_array($subscription, $ultimate)) {
return 'ultimate';
}
} elseif (isStripe()) {
if (isStripe()) {
if (! $this->stripe_plan_id) {
return 'zero';
}

View File

@ -1,51 +1,8 @@
<?php
use App\Models\Team;
use Illuminate\Support\Carbon;
use Stripe\Stripe;
function getSubscriptionLink($type)
{
$checkout_id = config("subscription.lemon_squeezy_checkout_id_$type");
if (! $checkout_id) {
return null;
}
$user_id = auth()->user()->id;
$team_id = currentTeam()->id ?? null;
$email = auth()->user()->email ?? null;
$name = auth()->user()->name ?? null;
$url = "https://store.coollabs.io/checkout/buy/$checkout_id?";
if ($user_id) {
$url .= "&checkout[custom][user_id]={$user_id}";
}
if (isset($team_id)) {
$url .= "&checkout[custom][team_id]={$team_id}";
}
if ($email) {
$url .= "&checkout[email]={$email}";
}
if ($name) {
$url .= "&checkout[name]={$name}";
}
return $url;
}
function getPaymentLink()
{
return currentTeam()->subscription->lemon_update_payment_menthod_url;
}
function getRenewDate()
{
return Carbon::parse(currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s');
}
function getEndDate()
{
return Carbon::parse(currentTeam()->subscription->lemon_renews_at)->format('Y-M-d H:i:s');
}
function isSubscriptionActive()
{
if (! isCloud()) {
@ -60,12 +17,6 @@ function isSubscriptionActive()
if (is_null($subscription)) {
return false;
}
if (isLemon()) {
return $subscription->lemon_status === 'active';
}
// if (isPaddle()) {
// return $subscription->paddle_status === 'active';
// }
if (isStripe()) {
return $subscription->stripe_invoice_paid === true;
}
@ -82,12 +33,6 @@ function isSubscriptionOnGracePeriod()
if (! $subscription) {
return false;
}
if (isLemon()) {
$is_still_grace_period = $subscription->lemon_ends_at &&
Carbon::parse($subscription->lemon_ends_at) > Carbon::now();
return $is_still_grace_period;
}
if (isStripe()) {
return $subscription->stripe_cancel_at_period_end;
}
@ -98,18 +43,10 @@ function subscriptionProvider()
{
return config('subscription.provider');
}
function isLemon()
{
return config('subscription.provider') === 'lemon';
}
function isStripe()
{
return config('subscription.provider') === 'stripe';
}
function isPaddle()
{
return config('subscription.provider') === 'paddle';
}
function getStripeCustomerPortalSession(Team $team)
{
Stripe::setApiKey(config('subscription.stripe_api_key'));

View File

@ -1,7 +1,8 @@
<?php
return [
'provider' => env('SUBSCRIPTION_PROVIDER', null), // stripe, paddle, lemon
'provider' => env('SUBSCRIPTION_PROVIDER', null), // stripe
// Stripe
'stripe_api_key' => env('STRIPE_API_KEY', null),
'stripe_webhook_secret' => env('STRIPE_WEBHOOK_SECRET', null),
@ -22,29 +23,4 @@
'stripe_price_id_dynamic_monthly' => env('STRIPE_PRICE_ID_DYNAMIC_MONTHLY', null),
'stripe_price_id_dynamic_yearly' => env('STRIPE_PRICE_ID_DYNAMIC_YEARLY', null),
// Paddle
'paddle_vendor_id' => env('PADDLE_VENDOR_ID', null),
'paddle_vendor_auth_code' => env('PADDLE_VENDOR_AUTH_CODE', null),
'paddle_webhook_secret' => env('PADDLE_WEBHOOK_SECRET', null),
'paddle_public_key' => env('PADDLE_PUBLIC_KEY', null),
'paddle_price_id_basic_monthly' => env('PADDLE_PRICE_ID_BASIC_MONTHLY', null),
'paddle_price_id_basic_yearly' => env('PADDLE_PRICE_ID_BASIC_YEARLY', null),
'paddle_price_id_pro_monthly' => env('PADDLE_PRICE_ID_PRO_MONTHLY', null),
'paddle_price_id_pro_yearly' => env('PADDLE_PRICE_ID_PRO_YEARLY', null),
'paddle_price_id_ultimate_monthly' => env('PADDLE_PRICE_ID_ULTIMATE_MONTHLY', null),
'paddle_price_id_ultimate_yearly' => env('PADDLE_PRICE_ID_ULTIMATE_YEARLY', null),
// Lemon
'lemon_squeezy_api_key' => env('LEMON_SQUEEZY_API_KEY', null),
'lemon_squeezy_webhook_secret' => env('LEMON_SQUEEZY_WEBHOOK_SECRET', null),
'lemon_squeezy_checkout_id_basic_monthly' => env('LEMON_SQUEEZY_CHECKOUT_ID_BASIC_MONTHLY', null),
'lemon_squeezy_checkout_id_basic_yearly' => env('LEMON_SQUEEZY_CHECKOUT_ID_BASIC_YEARLY', null),
'lemon_squeezy_checkout_id_pro_monthly' => env('LEMON_SQUEEZY_CHECKOUT_ID_PRO_MONTHLY', null),
'lemon_squeezy_checkout_id_pro_yearly' => env('LEMON_SQUEEZY_CHECKOUT_ID_PRO_YEARLY', null),
'lemon_squeezy_checkout_id_ultimate_monthly' => env('LEMON_SQUEEZY_CHECKOUT_ID_ULTIMATE_MONTHLY', null),
'lemon_squeezy_checkout_id_ultimate_yearly' => env('LEMON_SQUEEZY_CHECKOUT_ID_ULTIMATE_YEARLY', null),
'lemon_squeezy_basic_plan_ids' => env('LEMON_SQUEEZY_BASIC_PLAN_IDS', ''),
'lemon_squeezy_pro_plan_ids' => env('LEMON_SQUEEZY_PRO_PLAN_IDS', ''),
'lemon_squeezy_ultimate_plan_ids' => env('LEMON_SQUEEZY_ULTIMATE_PLAN_IDS', ''),
];

View File

@ -69,27 +69,6 @@ services:
- STRIPE_PRICE_ID_ULTIMATE_MONTHLY_OLD
- STRIPE_PRICE_ID_ULTIMATE_YEARLY_OLD
- STRIPE_EXCLUDED_PLANS
- PADDLE_VENDOR_ID
- PADDLE_WEBHOOK_SECRET
- PADDLE_VENDOR_AUTH_CODE
- PADDLE_PUBLIC_KEY
- PADDLE_PRICE_ID_BASIC_MONTHLY
- PADDLE_PRICE_ID_BASIC_YEARLY
- PADDLE_PRICE_ID_PRO_MONTHLY
- PADDLE_PRICE_ID_PRO_YEARLY
- PADDLE_PRICE_ID_ULTIMATE_MONTHLY
- PADDLE_PRICE_ID_ULTIMATE_YEARLY
- LEMON_SQUEEZY_API_KEY
- LEMON_SQUEEZY_WEBHOOK_SECRET
- LEMON_SQUEEZY_CHECKOUT_ID_BASIC_MONTHLY
- LEMON_SQUEEZY_CHECKOUT_ID_BASIC_YEARLY
- LEMON_SQUEEZY_CHECKOUT_ID_PRO_MONTHLY
- LEMON_SQUEEZY_CHECKOUT_ID_PRO_YEARLY
- LEMON_SQUEEZY_CHECKOUT_ID_ULTIMATE_MONTHLY
- LEMON_SQUEEZY_CHECKOUT_ID_ULTIMATE_YEARLY
- LEMON_SQUEEZY_BASIC_PLAN_IDS
- LEMON_SQUEEZY_PRO_PLAN_IDS
- LEMON_SQUEEZY_ULTIMATE_PLAN_IDS
ports:
- "${APP_PORT:-8000}:80"
expose:

View File

@ -1,80 +0,0 @@
<x-slot:basic>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-basic" class="w-full h-10 buyme"
x-on:click="subscribe('basic-monthly')"> Subscribe
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-basic" class="w-full h-10 buyme"
x-on:click="subscribe('basic-yearly')"> Subscribe
</x-forms.button>
</x-slot:basic>
<x-slot:pro>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-pro" class="w-full h-10 buyme"
x-on:click="subscribe('pro-monthly')"> Subscribe
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-pro" class="w-full h-10 buyme"
x-on:click="subscribe('pro-yearly')"> Subscribe
</x-forms.button>
</x-slot:pro>
<x-slot:ultimate>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-ultimate" class="w-full h-10 buyme"
x-on:click="subscribe('ultimate-monthly')"> Subscribe
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-ultimate" class="w-full h-10 buyme"
x-on:click="subscribe('ultimate-yearly')"> Subscribe
</x-forms.button>
</x-slot:ultimate>
<x-slot:other>
<script src="https://cdn.paddle.com/paddle/v2/paddle.js"></script>
<script type="text/javascript">
Paddle.Environment.set("{{ isDev() ? 'sandbox' : 'production' }}");
Paddle.Setup({
seller: {{ config('subscription.paddle_vendor_id') }},
checkout: {
settings: {
displayMode: "overlay",
theme: "light",
}
}
});
function subscribe(type) {
let priceId = null
switch (type) {
case 'basic-monthly':
priceId = "{{ config('subscription.paddle_price_id_basic_monthly') }}"
break;
case 'basic-yearly':
priceId = "{{ config('subscription.paddle_price_id_basic_yearly') }}"
break;
case 'pro-monthly':
priceId = "{{ config('subscription.paddle_price_id_pro_monthly') }}"
break;
case 'pro-yearly':
priceId = "{{ config('subscription.paddle_price_id_pro_yearly') }}"
break;
case 'ultimate-monthly':
priceId = "{{ config('subscription.paddle_price_id_ultimate_monthly') }}"
break;
case 'ultimate-yearly':
priceId = "{{ config('subscription.paddle_price_id_ultimate_yearly') }}"
break;
default:
break;
}
Paddle.Checkout.open({
customer: {
email: '{{ auth()->user()->email }}',
},
customData: {
"team_id": "{{ currentTeam()->id }}",
},
items: [{
priceId,
quantity: 1
}],
});
}
</script>
</x-slot:other>

View File

@ -34,15 +34,16 @@ class="font-bold dark:text-warning">{{ config('constants.limits.trial_period') }
<div>
</div>
</div>
{{-- <div class="p-4 rounded bg-coolgray-400">
<div class="p-4 rounded bg-coolgray-400">
<h2 id="tier-hobby" class="flex items-start gap-4 text-4xl font-bold tracking-tight">Unlimited Trial
<x-forms.button><a class="font-bold dark:text-white hover:no-underline"
href="https://github.com/coollabsio/coolify">Get Started</a></x-forms.button>
</h2>
<p class="mt-4 text-sm leading-6">Start self-hosting <span class="dark:text-warning">without limits</span> with
<p class="mt-4 text-sm leading-6">Start self-hosting <span class="dark:text-warning">without limits</span>
with
our
OSS version. Same features as the paid version, but you have to manage by yourself.</p>
</div> --}}
</div>
<div class="flow-root mt-12">
<div class="pb-10 text-xl text-center">For the detailed list of features, please visit our landing page: <a
@ -78,8 +79,8 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-neutral-200 dark:divide-
</p>
<ul role="list" class="space-y-3 text-sm leading-6 ">
<li class="flex">
<svg class="flex-none w-5 h-6 mr-3 dark:text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<svg class="flex-none w-5 h-6 mr-3 dark:text-warning" viewBox="0 0 20 20"
fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.775 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
@ -141,13 +142,14 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-neutral-200 dark:divide-
{{ $pro }}
@endisset
@endif
<p class="h-20 mt-10 text-sm leading-6 dark:text-white">Expand your business or set up your own hosting
<p class="h-20 mt-10 text-sm leading-6 dark:text-white">Expand your business or set up your own
hosting
environment.
</p>
<ul role="list" class="mt-6 space-y-3 text-sm leading-6 ">
<li class="flex ">
<svg class="flex-none w-5 h-6 mr-3 dark:text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<svg class="flex-none w-5 h-6 mr-3 dark:text-warning" viewBox="0 0 20 20"
fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />
@ -188,7 +190,7 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-neutral-200 dark:divide-
</div>
<div class="pt-16 lg:px-8 lg:pt-0 xl:px-12">
<h3 id="tier-ultimate" class="text-base font-semibold leading-7 dark:text-white">Ultimate</h3>
<p class="flex items-baseline mt-6 gap-x-1">
<p class="flex items-baseline mt-6 gap-x-1">
<span x-show="selected === 'monthly'" x-cloak>
<span class="text-4xl font-bold tracking-tight dark:text-white">Custom</span>
{{-- <span class="text-sm font-semibold leading-6 ">pay-as-you-go</span> --}}
@ -198,7 +200,7 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-neutral-200 dark:divide-
{{-- <span class="text-sm font-semibold leading-6 ">/month + VAT</span> --}}
</span>
</p>
<span x-show="selected === 'monthly'" x-cloak>
<span x-show="selected === 'monthly'" x-cloak>
<span>pay-as-you-go</span>
</span>
<span x-show="selected === 'yearly'" x-cloak>
@ -213,8 +215,8 @@ class="grid max-w-sm grid-cols-1 -mt-16 divide-y divide-neutral-200 dark:divide-
single location.</p>
<ul role="list" class="mt-6 space-y-3 text-sm leading-6 ">
<li class="flex ">
<svg class="flex-none w-5 h-6 mr-3 dark:text-warning" viewBox="0 0 20 20" fill="currentColor"
aria-hidden="true">
<svg class="flex-none w-5 h-6 mr-3 dark:text-warning" viewBox="0 0 20 20"
fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
clip-rule="evenodd" />

View File

@ -2,12 +2,11 @@
@if (subscriptionProvider() === 'stripe')
<div class="pt-4">
<h2>Your current plan</h2>
<div class="pb-4">Tier: <strong
class="dark:text-warning">
<div class="pb-4">Tier: <strong class="dark:text-warning">
@if (data_get(currentTeam(), 'subscription')->type() == 'dynamic')
Pay-as-you-go
Pay-as-you-go
@else
{{ data_get(currentTeam(), 'subscription')->type() }}
{{ data_get(currentTeam(), 'subscription')->type() }}
@endif
</strong></div>
@ -50,35 +49,4 @@ class="dark:text-warning">
target="_blank">contact us.</a>
</div>
@endif
{{-- @if (subscriptionProvider() === 'lemon')
<div>Status: {{ currentTeam()->subscription->lemon_status }}</div>
<div>Type: {{ currentTeam()->subscription->lemon_variant_name }}</div>
@if (currentTeam()->subscription->lemon_status === 'cancelled')
<div class="pb-4">Subscriptions ends at: {{ getRenewDate() }}</div>
<div class="py-4">If you would like to change the subscription to a lower/higher plan, <a
class="underline dark:text-white" href="{{ config('coolify.contact') }}" target="_blank">please
contact
us.</a></div>
@else
<div class="pb-4">Renews at: {{ getRenewDate() }}</div>
@endif
<div class="flex flex-col gap-2">
<div class="flex gap-2">
@if (currentTeam()->subscription->lemon_status === 'cancelled')
<x-forms.button class="bg-coollabs-gradient" wire:click='resume'>Resume Subscription
</x-forms.button>
@else
<x-forms.button wire:click='cancel'>Cancel Subscription</x-forms.button>
@endif
</div>
<div>
<x-forms.button><a class="dark:text-white hover:no-underline" href="{{ getPaymentLink() }}">Update Payment
Details</a>
</x-forms.button>
<a class="dark:text-white hover:no-underline"
href="https://app.lemonsqueezy.com/my-orders"><x-forms.button>Manage My
Subscription</x-forms.button></a>
</div>
</div>
@endif --}}
</div>

View File

@ -1,67 +0,0 @@
<x-pricing-plans>
@if (config('subscription.provider') === 'stripe')
<x-slot:basic>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-basic" class="w-full h-10 buyme"
wire:click="subscribeStripe('basic-monthly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-basic" class="w-full h-10 buyme"
wire:click="subscribeStripe('basic-yearly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
</x-slot:basic>
<x-slot:pro>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-pro" class="w-full h-10 buyme"
wire:click="subscribeStripe('pro-monthly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-pro" class="w-full h-10 buyme"
wire:click="subscribeStripe('pro-yearly')"> {{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
</x-slot:pro>
<x-slot:ultimate>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-ultimate" class="w-full h-10 buyme"
wire:click="subscribeStripe('ultimate-monthly')">
{{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-ultimate" class="w-full h-10 buyme"
wire:click="subscribeStripe('ultimate-yearly')"> {{ $isTrial ? 'Start Trial' : 'Subscribe' }}
</x-forms.button>
</x-slot:ultimate>
@endif
@if (config('subscription.provider') === 'paddle')
<x-paddle />
@endif
@if (config('subscription.provider') === 'lemon')
<x-slot:basic>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-basic"
class="w-full h-10 buyme" wire:click="getSubscriptionLink('basic-monthly')"> Subscribe
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-basic"
class="w-full h-10 buyme" wire:click="getSubscriptionLink('basic-yearly')"> Subscribe
</x-forms.button>
</x-slot:basic>
<x-slot:pro>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-pro"
class="w-full h-10 buyme" wire:click="getSubscriptionLink('pro-monthly')"> Subscribe
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-pro" class="w-full h-10 buyme"
wire:click="getSubscriptionLink('pro-yearly')"> Subscribe
</x-forms.button>
</x-slot:pro>
<x-slot:ultimate>
<x-forms.button x-show="selected === 'monthly'" x-cloak aria-describedby="tier-ultimate"
class="w-full h-10 buyme" wire:click="getSubscriptionLink('ultimate-monthly')"> Subscribe
</x-forms.button>
<x-forms.button x-show="selected === 'yearly'" x-cloak aria-describedby="tier-ultimate"
class="w-full h-10 buyme" wire:click="getSubscriptionLink('ultimate-yearly')"> Subscribe
</x-forms.button>
</x-slot:ultimate>
@endif
</x-pricing-plans>

View File

@ -25,7 +25,7 @@
<div>This is the default team. You can't delete it.</div>
@elseif(auth()->user()->teams()->get()->count() === 1 || auth()->user()->currentTeam()->personal_team)
<div>You can't delete your last / personal team.</div>
@elseif(currentTeam()->subscription && currentTeam()->subscription?->lemon_status !== 'cancelled')
@elseif(currentTeam()->subscription)
<div>Please cancel your subscription <a class="underline dark:text-white"
href="{{ route('subscription.show') }}">here</a> before delete this team.</div>
@else

View File

@ -1,62 +0,0 @@
<?php
use App\Actions\CoolifyTask\RunRemoteProcess;
use App\Actions\CoolifyTask\TidyOutput;
use App\Models\Server;
use App\Models\User;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
uses(DatabaseMigrations::class);
beforeEach(function () {
$this->seed(DatabaseSeeder::class);
});
it('starts a docker container correctly', function () {
test()->actingAs(User::factory([
'uuid' => Str::uuid(),
'email' => Str::uuid() . '@example.com',
])->create());
$coolifyNamePrefix = 'coolify_test_';
$format = '{"ID":"{{ .ID }}", "Image": "{{ .Image }}", "Names":"{{ .Names }}"}';
$areThereCoolifyTestContainers = "docker ps --filter=\"name={$coolifyNamePrefix}*\" --format '{$format}' ";
// Generate a known name
$containerName = 'coolify_test_' . now()->format('Ymd_his');
$host = Server::where('name', 'testing-local-docker-container')->first();
remote_process([
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq) > /dev/null 2>&1"
], $host);
// Assert there's no containers start with coolify_test_*
$activity = remote_process([$areThereCoolifyTestContainers], $host);
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
$containers = format_docker_command_output_to_json($tidyOutput);
expect($containers)->toBeEmpty();
// start a container nginx -d --name = $containerName
$activity = remote_process(["docker run -d --rm --name {$containerName} nginx"], $host);
expect($activity->getExtraProperty('exitCode'))->toBe(0);
// docker ps name = $container
$activity = remote_process([$areThereCoolifyTestContainers], $host);
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
$containers = format_docker_command_output_to_json($tidyOutput);
expect($containers->where('Names', $containerName)->count())->toBe(1);
// Stop testing containers
$activity = remote_process([
"docker ps --filter='name={$coolifyNamePrefix}*' -aq && " .
"docker rm -f $(docker ps --filter='name={$coolifyNamePrefix}*' -aq)"
], $host);
expect($activity->getExtraProperty('exitCode'))->toBe(0);
});

View File

@ -1,32 +0,0 @@
<?php
use App\Actions\CoolifyTask\RunRemoteProcess;
use App\Models\Server;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
uses(DatabaseMigrations::class);
beforeEach(function () {
$this->seed(DatabaseSeeder::class);
});
it('outputs correctly', function () {
$host = Server::where('name', 'testing-local-docker-container')->first();
$activity = remote_process([
'pwd',
'x=1; while [ $x -le 3 ]; do sleep 0.1 && echo "Welcome $x times" $(( x++ )); done',
], $host);
$tidyOutput = RunRemoteProcess::decodeOutput($activity);
expect($tidyOutput)
->toContain('Welcome 1 times')
->toContain('Welcome 3 times')
->not()->toBeJson();
});