Initial Ladill Hosting app with Gitea deploy pipeline.
Deploy Ladill Hosting / deploy (push) Failing after 17s

Shared web hosting extracted from the platform monolith, with CI deploy
to /var/www/ladill-hosting matching Bird/Domains/Email.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-06-06 16:24:20 +00:00
co-authored by Cursor
commit e251a4cf60
367 changed files with 66268 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class PromoBanner extends Model
{
use HasFactory;
public const TYPE_DOMAINS = 'domains';
public const TYPE_HOSTING = 'hosting';
public const TYPE_VPS = 'vps';
public const TYPE_DEDICATED = 'dedicated';
public const TYPE_EMAIL = 'email';
public const TYPE_GENERAL = 'general';
protected $fillable = [
'name',
'product_type',
'title',
'description',
'featured_image',
'badge_text',
'desktop_text',
'mobile_text',
'cta_text',
'cta_url',
'background_color',
'text_color',
'cta_background_color',
'cta_text_color',
'discount_percent',
'package_ids',
'starts_at',
'ends_at',
'is_active',
'show_topbar',
'show_on_homepage',
'sort_order',
];
protected $casts = [
'package_ids' => 'array',
'starts_at' => 'datetime',
'ends_at' => 'datetime',
'is_active' => 'boolean',
'show_topbar' => 'boolean',
'show_on_homepage' => 'boolean',
'discount_percent' => 'integer',
'sort_order' => 'integer',
];
public function scopeActive(Builder $query): Builder
{
return $query->where('is_active', true)
->where(function ($q) {
$q->whereNull('starts_at')
->orWhere('starts_at', '<=', now());
})
->where(function ($q) {
$q->whereNull('ends_at')
->orWhere('ends_at', '>=', now());
});
}
public function scopeForTopbar(Builder $query): Builder
{
return $query->active()->where('show_topbar', true);
}
public static function getActiveTopbar(): ?self
{
return static::forTopbar()->latest()->first();
}
public function scopeForHomepage(Builder $query): Builder
{
return $query->active()->where('show_on_homepage', true)->orderBy('sort_order');
}
public static function getHomepagePromos()
{
return static::forHomepage()->get();
}
public static function getProductTypes(): array
{
return [
self::TYPE_DOMAINS => 'Domains',
self::TYPE_HOSTING => 'Hosting',
self::TYPE_VPS => 'VPS',
self::TYPE_DEDICATED => 'Dedicated Servers',
self::TYPE_EMAIL => 'Email',
self::TYPE_GENERAL => 'General',
];
}
public function getFeaturedImageUrlAttribute(): ?string
{
if (!$this->featured_image) {
return null;
}
if (str_starts_with($this->featured_image, 'http')) {
return $this->featured_image;
}
return asset('storage/' . $this->featured_image);
}
}