main
erb 219 lines 12.3 KB
Raw
1 <% content_for :title, @repository.full_name %>
2 <%= render "shared/repository_social", repository: @repository %>
3 <% content_for :structured_data, repository_structured_data(@repository) %>
4 <% card = @card || @repository.model_card %>
5
6 <div data-controller="tabs" data-tabs-active-value="<%= params[:tab] || 'card' %>">
7
8 <%# ── Model header band ── %>
9 <div class="border-b border-surface-600 bg-surface-800">
10 <div class="max-w-6xl mx-auto px-4 sm:px-6 pt-6 pb-0">
11
12 <div class="flex items-start justify-between gap-4 mb-4">
13 <div class="min-w-0">
14 <div class="flex items-center gap-2 text-sm flex-wrap">
15 <%# cube / weights glyph %>
16 <svg class="w-5 h-5 text-brand-500 shrink-0" viewBox="0 0 24 24" fill="none"
17 stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
18 <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/>
19 <path d="m3.27 6.96 8.73 5.05 8.73-5.05M12 22.08V12"/>
20 </svg>
21 <%= link_to "@#{@owner.username}", user_profile_path(@owner.username),
22 class: "text-brand-500 hover:underline font-medium" %>
23 <span class="text-gray-500">/</span>
24 <%= link_to @repository.name, repository_path(@owner.username, @repository.name),
25 class: "text-gray-100 hover:underline font-semibold text-base" %>
26 <% if @repository.is_private %>
27 <span class="badge-gray ml-1">Private</span>
28 <% end %>
29 </div>
30
31 <% if @repository.description.present? %>
32 <p class="text-sm text-gray-400 mt-2 max-w-2xl"><%= @repository.description %></p>
33 <% end %>
34
35 <%# ── Metadata pills ── %>
36 <div class="flex items-center gap-2 flex-wrap mt-3 text-xs">
37 <% if (label = pipeline_label(card.pipeline_tag)) %>
38 <%= link_to label, models_path(pipeline_tag: card.pipeline_tag),
39 class: "badge-blue hover:bg-brand-500/20" %>
40 <% end %>
41 <% if card.library_name.present? %>
42 <%= link_to models_path(library: card.library_name),
43 class: "badge-gray hover:bg-surface-500 flex items-center gap-1" do %>
44 <svg class="w-3 h-3" viewBox="0 0 16 16" fill="currentColor"><path d="M3 2.75A.75.75 0 0 1 3.75 2h8.5a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-8.5a.75.75 0 0 1-.75-.75Zm1.5.75v9h7v-9Z"/></svg>
45 <%= card.library_name %>
46 <% end %>
47 <% end %>
48 <% if card.license.present? %>
49 <span class="badge-gray">License: <%= card.license %></span>
50 <% end %>
51 <% card.tags.first(6).each do |tag| %>
52 <span class="badge-gray text-gray-400"><%= tag %></span>
53 <% end %>
54 </div>
55 </div>
56
57 <%# ── Like / download stats ── %>
58 <div class="flex items-center gap-2 shrink-0">
59 <%= button_to repository_star_path(@owner.username, @repository.name),
60 method: :post,
61 class: "btn-secondary text-xs py-1.5 px-3 #{'text-amber-300 border-amber-500/40' if @repository.starred_by?(current_user)}" do %>
62 <svg class="w-3.5 h-3.5" viewBox="0 0 16 16"
63 fill="<%= @repository.starred_by?(current_user) ? 'currentColor' : 'none' %>"
64 stroke="currentColor" stroke-width="1.5">
65 <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"/>
66 </svg>
67 <span>Like</span>
68 <span class="badge-gray ml-0.5"><%= number_with_delimiter(@repository.stars_count) %></span>
69 <% end %>
70 </div>
71 </div>
72
73 <%# ── Tabs ── %>
74 <div class="flex items-center gap-0 -mb-px">
75 <button data-tabs-target="tab" data-tabs-key="card" data-action="click->tabs#switch"
76 class="tab-item active flex items-center gap-1.5">
77 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor">
78 <path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Z"/>
79 </svg>
80 Model card
81 </button>
82 <button data-tabs-target="tab" data-tabs-key="files" data-action="click->tabs#switch"
83 class="tab-item flex items-center gap-1.5">
84 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor">
85 <path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Z"/>
86 </svg>
87 Files and versions
88 <% if @files&.any? %><span class="badge-gray text-xs"><%= @files.size %></span><% end %>
89 </button>
90 </div>
91 </div>
92 </div>
93
94 <%# ── Body ── %>
95 <div class="max-w-6xl mx-auto px-4 sm:px-6 py-6">
96
97 <% if @empty %>
98 <div class="card p-8 text-center max-w-2xl mx-auto">
99 <h2 class="text-lg font-semibold text-gray-100 mb-2">This model has no files yet</h2>
100 <p class="text-sm text-gray-400 mb-6">Push your model card and weights to get started.</p>
101 <div class="code-container text-left p-4 max-w-lg mx-auto text-xs font-mono space-y-0.5">
102 <p class="text-gray-500 mb-1"># Push weights with Git LFS</p>
103 <p class="text-gray-300">git clone git@sigitsi.com:<%= @owner.username %>/<%= @repository.name %></p>
104 <p class="text-gray-300">cd <%= @repository.name %></p>
105 <p class="text-gray-300">git lfs install &amp;&amp; git lfs track "*.safetensors" "*.gguf"</p>
106 <p class="text-gray-300">git add . &amp;&amp; git commit -m "Add weights"</p>
107 <p class="text-gray-300">git push origin <%= @repository.default_branch %></p>
108 </div>
109 </div>
110 <% else %>
111 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
112
113 <%# ── Main column ── %>
114 <div class="lg:col-span-2 min-w-0">
115 <%# Model card panel %>
116 <div data-tabs-target="panel" data-tabs-key="card">
117 <% if @card_html.present? %>
118 <div class="card">
119 <div class="px-6 py-6 prose-readme"><%= @card_html %></div>
120 </div>
121 <% else %>
122 <div class="card px-6 py-12 text-center text-sm text-gray-500">
123 No model card yet. Add a <code>README.md</code> to describe this model.
124 </div>
125 <% end %>
126 </div>
127
128 <%# Files and versions panel %>
129 <div data-tabs-target="panel" data-tabs-key="files" class="hidden">
130 <div class="card rounded-b-none border-b-0 px-4 py-2.5 flex items-center justify-between gap-4 bg-surface-600">
131 <span class="text-xs text-gray-400 flex items-center gap-2">
132 <span class="btn-secondary py-1 px-2.5 text-xs font-mono cursor-default"><%= @branch %></span>
133 <%= pluralize(@files.size, "file") %>
134 </span>
135 <span class="text-xs text-gray-500">
136 Total: <span class="text-gray-300"><%= number_to_human_size(@total_size) %></span>
137 </span>
138 </div>
139 <div class="card rounded-t-none">
140 <% @files.each do |entry| %>
141 <div class="file-row">
142 <% if entry[:type] == "tree" %>
143 <svg class="w-4 h-4 text-brand-400 shrink-0" viewBox="0 0 16 16" fill="currentColor">
144 <path d="M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1Z"/>
145 </svg>
146 <%= link_to entry[:name],
147 repository_tree_path(@owner.username, @repository.name, @branch, entry[:path]),
148 class: "text-brand-500 hover:underline font-medium flex-1" %>
149 <% else %>
150 <svg class="w-4 h-4 text-gray-500 shrink-0" viewBox="0 0 16 16" fill="currentColor">
151 <path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V6h-2.75A1.75 1.75 0 0 1 9 4.25V1.5Z"/>
152 </svg>
153 <%= link_to entry[:name],
154 repository_blob_path(@owner.username, @repository.name, @branch, entry[:path]),
155 class: "text-gray-200 hover:text-brand-500 hover:underline flex-1 truncate" %>
156 <div class="flex items-center gap-2 shrink-0">
157 <% if (fmt = weight_format(entry[:name])) %>
158 <span class="badge-blue text-[10px]"><%= fmt %></span>
159 <% end %>
160 <% if entry[:lfs] %>
161 <span class="badge-gray text-[10px] text-gray-400" title="Stored with Git LFS">LFS</span>
162 <% end %>
163 <% if entry[:size] %>
164 <span class="text-xs text-gray-500 font-mono w-20 text-right"><%= number_to_human_size(entry[:size]) %></span>
165 <% end %>
166 <%= link_to repository_blob_raw_path(@owner.username, @repository.name, @branch, entry[:path]),
167 class: "text-gray-500 hover:text-brand-500", title: "Download" do %>
168 <svg class="w-4 h-4" viewBox="0 0 16 16" fill="currentColor"><path d="M7.47 10.78a.75.75 0 0 0 1.06 0l3.75-3.75a.75.75 0 0 0-1.06-1.06L8.75 8.44V1.75a.75.75 0 0 0-1.5 0v6.69L4.78 5.97a.75.75 0 0 0-1.06 1.06ZM3.75 13a.75.75 0 0 0 0 1.5h8.5a.75.75 0 0 0 0-1.5Z"/></svg>
169 <% end %>
170 </div>
171 <% end %>
172 </div>
173 <% end %>
174 </div>
175 </div>
176 </div>
177
178 <%# ── Sidebar ── %>
179 <aside class="lg:col-span-1 space-y-4">
180 <%= render "repositories/model_use", repository: @repository, owner: @owner, card: card %>
181
182 <div class="card p-4 space-y-3 text-sm">
183 <h3 class="text-xs uppercase tracking-wider text-gray-500 font-semibold">Model details</h3>
184 <% if card.base_model.present? %>
185 <div class="flex items-center justify-between gap-2">
186 <span class="text-gray-500">Base model</span>
187 <span class="text-gray-300 truncate font-mono text-xs"><%= card.base_model %></span>
188 </div>
189 <% end %>
190 <% if card.library_name.present? %>
191 <div class="flex items-center justify-between"><span class="text-gray-500">Library</span><span class="text-gray-300"><%= card.library_name %></span></div>
192 <% end %>
193 <% if card.license.present? %>
194 <div class="flex items-center justify-between"><span class="text-gray-500">License</span><span class="text-gray-300"><%= card.license %></span></div>
195 <% end %>
196 <% if card.language.any? %>
197 <div class="flex items-center justify-between"><span class="text-gray-500">Languages</span><span class="text-gray-300"><%= card.language.first(4).join(", ") %></span></div>
198 <% end %>
199 <div class="flex items-center justify-between"><span class="text-gray-500">Downloads</span><span class="text-gray-300"><%= number_with_delimiter(@repository.downloads_count) %></span></div>
200 <div class="flex items-center justify-between"><span class="text-gray-500">Likes</span><span class="text-gray-300"><%= number_with_delimiter(@repository.stars_count) %></span></div>
201 <div class="flex items-center justify-between"><span class="text-gray-500">Updated</span><span class="text-gray-300"><%= time_ago_in_words(@repository.updated_at) %> ago</span></div>
202 </div>
203
204 <% if card.tags.any? %>
205 <div class="card p-4">
206 <h3 class="text-xs uppercase tracking-wider text-gray-500 font-semibold mb-3">Tags</h3>
207 <div class="flex flex-wrap gap-1.5">
208 <% card.tags.each do |tag| %>
209 <span class="badge-gray text-[11px] text-gray-400"><%= tag %></span>
210 <% end %>
211 </div>
212 </div>
213 <% end %>
214 </aside>
215
216 </div>
217 <% end %>
218 </div>
219 </div>