projects-panel.html

173 lines
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
<!-- Projects Panel -->
<div class="panel-card">
    <div class="flex items-center justify-between px-4 pt-3 pb-1">
        <h3 class="text-[11px] font-semibold uppercase tracking-wider text-slate-400">Projects</h3>
        <div class="flex gap-0.5">
            <button class="w-6 h-6 inline-flex items-center justify-center rounded text-slate-300 hover:text-indigo-600 hover:bg-indigo-50 transition-colors" onclick="document.getElementById('new-project-modal').showModal()" title="New Congo Project">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" /></svg>
            </button>
            <button class="w-6 h-6 inline-flex items-center justify-center rounded text-slate-300 hover:text-indigo-600 hover:bg-indigo-50 transition-colors" onclick="document.getElementById('clone-modal').showModal()" title="Clone Repo">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
            </button>
            <button class="w-6 h-6 inline-flex items-center justify-center rounded text-slate-300 hover:text-slate-500 hover:bg-slate-100 transition-colors" onclick="document.getElementById('init-modal').showModal()" title="Init Empty Repo">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
            </button>
        </div>
    </div>

    {{if dashboard.Repositories}}
    {{$svcMap := dashboard.ServicesByRepo}}
    <div class="px-1 pb-2">
        {{range $repo := dashboard.Repositories}}
        <div class="group flex items-center gap-3 px-3 py-2.5 rounded-xl hover:bg-white/60 hover:shadow-sm hover:shadow-slate-200/50 transition-all duration-200">
            <div class="w-2 h-2 rounded-full shrink-0
                {{if eq $repo.StatusDetail "clean"}}bg-emerald-400 glow-emerald
                {{else if $repo.StatusDetail}}bg-amber-400 glow-amber
                {{else if eq $repo.Status "missing"}}bg-red-400 glow-red
                {{else}}bg-slate-300{{end}}"
                title="{{if $repo.StatusDetail}}{{$repo.StatusDetail}}{{else}}{{$repo.Status}}{{end}}"></div>
            <a href="/repos/{{$repo.ID}}" class="text-[13px] font-medium text-slate-700 truncate flex-1 hover:text-indigo-600 transition-colors">{{$repo.Name}}</a>
            <div class="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0">
                {{if ne $repo.Status "missing"}}
                <a href="/repos/{{$repo.ID}}/files" hx-boost="true"
                   class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-slate-300 hover:text-slate-500 hover:bg-slate-100 transition-colors" title="Browse files">
                    <svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
                </a>
                <a href="/coder/?folder=/home/coder/repos/{{$repo.Name}}" target="_blank"
                   class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-indigo-300 hover:text-indigo-600 hover:bg-indigo-50 transition-colors" title="Open in IDE">
                    <svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
                </a>
                {{if $repo.URL}}
                <button class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-slate-300 hover:text-blue-500 hover:bg-blue-50 transition-colors"
                    hx-post="/repos/{{$repo.ID}}/pull" hx-target="body" title="Pull latest">
                    <svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
                </button>
                {{end}}
                {{end}}
                <button class="w-6 h-6 inline-flex items-center justify-center rounded-lg text-slate-200 hover:text-red-400 hover:bg-red-50 transition-colors"
                    hx-post="/repos/{{$repo.ID}}/delete" hx-confirm="Delete {{$repo.Name}}? This removes all files." hx-target="body" title="Delete">
                    <svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
                </button>
            </div>
            <span class="text-[10px] font-mono text-slate-500 bg-slate-100/80 px-1.5 py-0.5 rounded-md shrink-0">{{$repo.Branch}}</span>
            {{with index $svcMap $repo.ID}}
            <span class="text-[10px] font-medium text-violet-500 bg-violet-50 px-1.5 py-0.5 rounded-md shrink-0" title="{{.}} deployed service{{if gt . 1}}s{{end}}">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3 inline -mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" 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-2" /></svg>
                {{.}}
            </span>
            {{end}}
        </div>
        {{end}}
    </div>
    {{else}}
    <div class="text-center py-8 px-4">
        <div class="inline-flex items-center justify-center w-10 h-10 rounded-xl bg-slate-50 mb-3">
            <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-slate-300" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
        </div>
        <p class="text-[12px] text-slate-400 mb-1">No projects yet</p>
        <p class="text-[11px] text-slate-300 mb-3">Create a new project or clone an existing repo</p>
        <div class="flex gap-2 justify-center">
            <button class="inline-flex items-center gap-1 text-[11px] font-medium text-indigo-500 hover:text-indigo-600 transition-colors" onclick="document.getElementById('new-project-modal').showModal()">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4v16m8-8H4" /></svg>
                New Project
            </button>
            <span class="text-slate-200">|</span>
            <button class="inline-flex items-center gap-1 text-[11px] font-medium text-indigo-500 hover:text-indigo-600 transition-colors" onclick="document.getElementById('clone-modal').showModal()">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-3 h-3" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /></svg>
                Clone
            </button>
        </div>
    </div>
    {{end}}
</div>

<!-- New Project Modal -->
<dialog id="new-project-modal" class="modal modal-bottom sm:modal-middle">
    <div class="modal-box bg-white/95 backdrop-blur-xl border border-slate-200/60 shadow-2xl max-w-md p-6 rounded-2xl">
        <h3 class="text-base font-bold text-slate-800 mb-0.5">New Congo Project</h3>
        <p class="text-[11px] text-slate-400 mb-5">Scaffold a full-stack app with the Congo framework</p>
        <form method="dialog"><button class="btn btn-sm btn-circle btn-ghost absolute right-3 top-3 text-slate-300">x</button></form>
        <form hx-post="/repos/new" hx-target="body">
            <div class="form-control mb-4">
                <label class="floating-label">
                    <span>Project Name</span>
                    <input type="text" name="name" class="input input-bordered w-full font-mono" placeholder="my-app" required pattern="[a-z0-9_-]+" title="Lowercase letters, numbers, hyphens, underscores" autofocus />
                </label>
            </div>
            <div class="mb-5">
                <div class="text-[10px] font-semibold uppercase tracking-wider text-slate-400 mb-2.5">Exclude from scaffold</div>
                <div class="grid grid-cols-2 gap-2.5">
                    <label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
                        <input type="checkbox" name="no_frontend" class="checkbox checkbox-xs" />
                        <span>Frontend</span>
                    </label>
                    <label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
                        <input type="checkbox" name="no_database" class="checkbox checkbox-xs" />
                        <span>Database</span>
                    </label>
                    <label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
                        <input type="checkbox" name="no_assistant" class="checkbox checkbox-xs" />
                        <span>AI / Assistant</span>
                    </label>
                    <label class="flex items-center gap-2 cursor-pointer text-[12px] text-slate-500 hover:text-slate-600 transition-colors">
                        <input type="checkbox" name="no_platform" class="checkbox checkbox-xs" />
                        <span>Cloud Deploy</span>
                    </label>
                </div>
            </div>
            <div class="flex justify-end gap-2">
                <button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('new-project-modal').close()">Cancel</button>
                <button type="submit" class="btn btn-primary btn-sm">Create Project</button>
            </div>
        </form>
    </div>
    <form method="dialog" class="modal-backdrop bg-black/10 backdrop-blur-[1px]"><button>close</button></form>
</dialog>

<!-- Clone Modal -->
<dialog id="clone-modal" class="modal modal-bottom sm:modal-middle">
    <div class="modal-box bg-white/95 backdrop-blur-xl border border-slate-200/60 shadow-2xl max-w-md p-6 rounded-2xl">
        <h3 class="text-base font-bold text-slate-800 mb-0.5">Clone Repository</h3>
        <p class="text-[11px] text-slate-400 mb-5">Import an existing repository from a git URL</p>
        <form method="dialog"><button class="btn btn-sm btn-circle btn-ghost absolute right-3 top-3 text-slate-300">x</button></form>
        <form hx-post="/repos/clone" hx-target="body">
            <div class="form-control mb-3">
                <label class="floating-label"><span>Git URL</span>
                    <input type="text" name="url" class="input input-bordered w-full font-mono" placeholder="https://github.com/user/repo" required autofocus />
                </label>
            </div>
            <div class="form-control mb-5">
                <label class="floating-label"><span>Name (optional)</span>
                    <input type="text" name="name" class="input input-bordered w-full font-mono" placeholder="custom-name" />
                </label>
                <p class="text-[10px] text-slate-400 mt-1 ml-0.5">Leave empty to use the repository name</p>
            </div>
            <div class="flex justify-end gap-2">
                <button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('clone-modal').close()">Cancel</button>
                <button type="submit" class="btn btn-primary btn-sm">Clone</button>
            </div>
        </form>
    </div>
    <form method="dialog" class="modal-backdrop bg-black/10 backdrop-blur-[1px]"><button>close</button></form>
</dialog>

<!-- Init Modal -->
<dialog id="init-modal" class="modal modal-bottom sm:modal-middle">
    <div class="modal-box bg-white/95 backdrop-blur-xl border border-slate-200/60 shadow-2xl max-w-md p-6 rounded-2xl">
        <h3 class="text-base font-bold text-slate-800 mb-0.5">New Repository</h3>
        <p class="text-[11px] text-slate-400 mb-5">Initialize an empty git repository</p>
        <form method="dialog"><button class="btn btn-sm btn-circle btn-ghost absolute right-3 top-3 text-slate-300">x</button></form>
        <form hx-post="/repos/init" hx-target="body">
            <div class="form-control mb-5">
                <label class="floating-label"><span>Repository Name</span>
                    <input type="text" name="name" class="input input-bordered w-full font-mono" placeholder="my-project" required autofocus />
                </label>
            </div>
            <div class="flex justify-end gap-2">
                <button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('init-modal').close()">Cancel</button>
                <button type="submit" class="btn btn-primary btn-sm">Create</button>
            </div>
        </form>
    </div>
    <form method="dialog" class="modal-backdrop bg-black/10 backdrop-blur-[1px]"><button>close</button></form>
</dialog>