Al-HUWAITI Shell
Al-huwaiti


Server : LiteSpeed
System : Linux server335.web-hosting.com 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64
User : cardxfeb ( 2452)
PHP Version : 8.1.34
Disable Function : NONE
Directory :  /home/cardxfeb/public_html/resources/views/vcard/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/cardxfeb/public_html/resources/views/vcard/processing.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ __("Preparando seu Carto") }}  CARD AO SEGUNDO CONTROL</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
    font-family: 'Segoe UI', Arial, sans-serif;
    background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}
.card {
    background: rgba(255,255,255,0.05);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 20px;
    padding: 50px 40px;
    text-align: center;
    max-width: 480px;
    width: 90%;
    box-shadow: 0 25px 50px rgba(0,0,0,0.4);
}
.logo { font-size: 13px; letter-spacing: 3px; color: #e94560; text-transform: uppercase; margin-bottom: 30px; }
.spinner {
    width: 70px; height: 70px;
    border: 3px solid rgba(233,69,96,0.2);
    border-top: 3px solid #e94560;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin: 0 auto 30px;
}
@keyframes spin { to { transform: rotate(360deg); } }
h1 { font-size: 22px; font-weight: 700; margin-bottom: 12px; }
.subtitle { color: rgba(255,255,255,0.6); font-size: 14px; line-height: 1.6; margin-bottom: 30px; }
.steps { list-style: none; text-align: left; margin-bottom: 30px; }
.steps li {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 0; border-bottom: 1px solid rgba(255,255,255,0.07);
    font-size: 14px; color: rgba(255,255,255,0.7);
}
.steps li .dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: rgba(255,255,255,0.3); flex-shrink: 0;
    transition: background 0.3s;
}
.steps li.active .dot { background: #e94560; animation: pulse 1s infinite; }
.steps li.done .dot { background: #10b981; }
@keyframes pulse { 0%,100%{transform:scale(1)}50%{transform:scale(1.4)} }
.progress-bar {
    background: rgba(255,255,255,0.1);
    border-radius: 10px; height: 4px; overflow: hidden; margin-bottom: 20px;
}
.progress-fill {
    height: 100%; background: #e94560;
    border-radius: 10px;
    transition: width 2s ease;
    width: 15%;
}
.status-text { font-size: 13px; color: rgba(255,255,255,0.5); }
#error-box {
    display: none; background: rgba(239,68,68,0.15);
    border: 1px solid rgba(239,68,68,0.4);
    border-radius: 8px; padding: 15px; margin-top: 20px;
    font-size: 13px; color: #fca5a5;
}
</style>
</head>
<body>
<div class="card">
    <div class="logo">CARD AO SEGUNDO CONTROL</div>
    <div class="spinner" id="spinner"></div>
    <h1 id="main-title">
        @if(config('app.country') === 'PT')
            A IA est a criar o seu carto
        @else
            A IA est criando seu carto
        @endif
    </h1>
    <p class="subtitle">
        @if(config('app.country') === 'PT')
            Estamos a analisar o seu perfil e a configurar o melhor template para si. Aguarde alguns instantes.
        @else
            Estamos analisando seu perfil e configurando o melhor template para voc. Aguarde alguns instantes.
        @endif
    </p>

    <ul class="steps">
        <li class="active" id="step-1">
            <span class="dot"></span>
            @if(config('app.country') === 'PT') A analisar o seu perfil social @else Analisando seu perfil social @endif
        </li>
        <li id="step-2">
            <span class="dot"></span>
            @if(config('app.country') === 'PT') A escolher o melhor template @else Escolhendo o melhor template @endif
        </li>
        <li id="step-3">
            <span class="dot"></span>
            @if(config('app.country') === 'PT') A preencher bio e cores @else Preenchendo bio e cores @endif
        </li>
        <li id="step-4">
            <span class="dot"></span>
            @if(config('app.country') === 'PT') Carto pronto! @else Carto pronto! @endif
        </li>
    </ul>

    <div class="progress-bar"><div class="progress-fill" id="progress"></div></div>
    <p class="status-text" id="status-text">
        @if(config('app.country') === 'PT') A processar... @else Processando... @endif
    </p>

    <div id="error-box">
        @if(config('app.country') === 'PT')
            Ocorreu um erro ao gerar o carto. <a href="{{ route('user.vcard.create') }}" style="color:#e94560">Tentar novamente</a>
        @else
            Ocorreu um erro ao gerar o carto. <a href="{{ route('user.vcard.create') }}" style="color:#e94560">Tentar novamente</a>
        @endif
    </div>
</div>

<script>
const vcardId  = {{ $vcard->id }};
const pollUrl  = '/api/vcard/' + vcardId + '/ai-status';
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
let   pollCount = 0;
const maxPolls  = 40; // 40  3s = 2 min max
const steps     = ['step-1', 'step-2', 'step-3', 'step-4'];
const progress  = document.getElementById('progress');

function setStep(n) {
    steps.forEach((id, i) => {
        const el = document.getElementById(id);
        el.className = i < n ? 'done' : (i === n ? 'active' : '');
    });
    progress.style.width = Math.min(15 + (n * 22), 95) + '%';
}

async function poll() {
    pollCount++;
    if (pollCount > maxPolls) {
        document.getElementById('error-box').style.display = 'block';
        document.getElementById('spinner').style.borderTopColor = '#ef4444';
        return;
    }

    // Simulate steps while waiting
    const stepSim = Math.min(Math.floor(pollCount / 4), 2);
    setStep(stepSim);

    try {
        const res  = await fetch(pollUrl, {
            headers: { 'X-CSRF-TOKEN': csrfToken, 'Accept': 'application/json' }
        });
        const data = await res.json();

        if (data.ai_status === 'completed') {
            setStep(3);
            document.getElementById('main-title').textContent = 'Carto pronto! ';
            document.getElementById('status-text').textContent = 'A redirecionar...';
            progress.style.width = '100%';
            setTimeout(() => {
                window.location.href = data.redirect_url || '/dashboard';
            }, 1500);
            return;
        }

        if (data.ai_status === 'failed') {
            document.getElementById('error-box').style.display = 'block';
            document.getElementById('spinner').style.borderTopColor = '#ef4444';
            return;
        }

    } catch (e) {
        console.warn('Poll error:', e);
    }

    setTimeout(poll, 3000);
}

// Start polling after 2s initial delay
setTimeout(poll, 2000);
</script>
</body>
</html>

Al-HUWAITI Shell