| |
| <aside class="w-64 bg-code-surface border-r border-code-border h-[calc(100vh-4rem)] sticky top-16 flex-shrink-0 flex flex-col"> |
| <nav class="p-4 space-y-2 flex-1 overflow-y-auto scrollbar-thin"> |
| |
| <a href="{% url 'cpanel:dashboard' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if request.resolver_match.url_name == 'dashboard' %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/> |
| </svg> |
| <span>Dashboard</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:script_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'script' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/> |
| </svg> |
| <span>Scripts</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:run_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'run' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/> |
| </svg> |
| <span>Runs</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:tasks' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'task' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/> |
| </svg> |
| <span>Tasks</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:environment_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'environment' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/> |
| </svg> |
| <span>Environments</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:secret_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'secret' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/> |
| </svg> |
| <span>Secrets</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:tag_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'tag' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"/> |
| </svg> |
| <span>Tags</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:datastore_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'datastore' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/> |
| </svg> |
| <span>Data Stores</span> |
| </a> |
|
|
| |
| <div class="my-4 border-t border-code-border"></div> |
|
|
| |
| <a href="{% url 'cpanel:settings' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'settings' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/> |
| </svg> |
| <span>Settings</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:services' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'service' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"/> |
| </svg> |
| <span>Services</span> |
| </a> |
|
|
| |
| <a href="{% url 'cpanel:logs' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'logs' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> |
| </svg> |
| <span>Logs</span> |
| </a> |
|
|
| {% if request.user.is_superuser %} |
| |
| <a href="{% url 'cpanel:user_list' %}" |
| class="flex items-center space-x-3 px-4 py-3 rounded-lg transition-colors {% if 'user' in request.resolver_match.url_name %}bg-code-accent/20 text-code-accent{% else %}text-code-muted hover:text-code-text hover:bg-code-bg{% endif %}"> |
| <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/> |
| </svg> |
| <span>Users</span> |
| </a> |
| {% endif %} |
| </nav> |
|
|
| |
| <div class="flex-shrink-0 border-t border-code-border p-3 space-y-2"> |
| |
| <div class="flex items-center gap-2 text-xs"> |
| <span class="text-code-muted">Developer:</span> |
| <a href="https://x.com/hasan_ab_hasan" target="_blank" class="text-code-accent hover:text-white transition">X</a> |
| <span class="text-code-border">|</span> |
| <a href="https://www.youtube.com/@hasanaboulhasan" target="_blank" class="text-code-accent hover:text-white transition">YouTube</a> |
| <span class="text-code-border">|</span> |
| <a href="https://learnwithhasan.com" target="_blank" class="text-code-accent hover:text-white transition">Website</a> |
| </div> |
| |
| <div class="flex items-center justify-between"> |
| <a href="https://learnwithhasan.com/courses/solo-builder-10/" target="_blank" |
| class="inline-flex items-center gap-1 px-2 py-0.5 bg-code-bg border border-code-border rounded-full text-xs text-code-muted hover:text-white hover:border-code-accent transition"> |
| <span>Built With:</span> |
| <span class="text-code-purple font-medium">Solo Builder</span> |
| </a> |
| <a href="https://pyrunner.dev" target="_blank" class="text-xs text-code-muted hover:text-code-accent transition"> |
| v1.8.2 |
| </a> |
| </div> |
| </div> |
| </aside> |
|
|