Add author auth, forking, tags, and stats tracking
Introduce token-based author authentication (register/verify API), skill forking with EditGate protection, tag metadata on skills, and download/push stats. Enhanced push scripts with token auth and per-skill filtering. Updated UI with stats, tags, and author info on skill cards.
This commit is contained in:
1
dist/client/_astro/DeleteButton.CHpgpUL1.js
vendored
Normal file
1
dist/client/_astro/DeleteButton.CHpgpUL1.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/client/_astro/DeleteButton.CyEek_0f.js
vendored
1
dist/client/_astro/DeleteButton.CyEek_0f.js
vendored
@@ -1 +0,0 @@
|
||||
import{_ as i}from"./_plugin-vue_export-helper.DlAUqK2U.js";import{c as d,a as l,b as c,t as u,e as m,f as p,o as f}from"./runtime-core.esm-bundler.D9KZBfyO.js";const _=m({__name:"DeleteButton",props:{slug:{}},setup(n,{expose:t}){t();const o=n,e=p(!1);async function a(){if(confirm(`Delete "${o.slug}"? This cannot be undone.`)){e.value=!0;try{const s=await fetch(`/api/skills/${o.slug}`,{method:"DELETE"});if(!s.ok&&s.status!==204)throw new Error("Failed to delete");window.location.href="/"}catch{alert("Failed to delete skill."),e.value=!1}}}const r={props:o,deleting:e,handleDelete:a};return Object.defineProperty(r,"__isScriptSetup",{enumerable:!1,value:!0}),r}}),b=["disabled"];function g(n,t,o,e,a,r){return f(),d("button",{onClick:e.handleDelete,disabled:e.deleting,class:"inline-flex items-center gap-1.5 rounded-lg border border-red-500/20 bg-red-500/5 px-3.5 py-2 text-sm font-medium text-red-400 hover:bg-red-500/10 hover:border-red-500/30 disabled:opacity-50 active:scale-[0.97] transition-all"},[t[0]||(t[0]=l("svg",{class:"h-3.5 w-3.5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[l("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"})],-1)),c(" "+u(e.deleting?"Deleting...":"Delete"),1)],8,b)}const v=i(_,[["render",g]]);export{v as default};
|
||||
1
dist/client/_astro/EditGate.mFTQzSOo.js
vendored
Normal file
1
dist/client/_astro/EditGate.mFTQzSOo.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{c as d,a as o,d as u,l as b,g as p,t as f,w as C,v as _,b as m,T as S,F as T,h as E,i,m as M,o as c}from"./runtime-dom.esm-bundler.A7MyAQcw.js";import{_ as V}from"./_plugin-vue_export-helper.DlAUqK2U.js";const B=E({__name:"EditGate",props:{slug:{},authorEmail:{},authorName:{},authorHasToken:{type:Boolean}},setup(h,{expose:e}){e();const r=h,t=i(!1),s=i(""),a=i(""),n=i(!1),v=i();async function x(){if(!r.authorEmail||!r.authorHasToken){window.location.href=`/${r.slug}/edit`;return}const l=localStorage.getItem("skillshere-token")||"";if(l)try{if((await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:r.authorEmail,token:l})})).ok){localStorage.setItem("skillshere-token",l),window.location.href=`/${r.slug}/edit`;return}}catch{}t.value=!0,a.value="",s.value="",M(()=>v.value?.focus())}async function g(){n.value=!0,a.value="";try{const l=await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:r.authorEmail,token:s.value})});if(!l.ok){const y=await l.json();a.value=y.error||"Invalid token";return}localStorage.setItem("skillshere-token",s.value),window.location.href=`/${r.slug}/edit`}catch{a.value="Could not verify token"}finally{n.value=!1}}function w(){t.value=!1,window.location.href=`/new?from=${encodeURIComponent(r.slug)}`}const k={props:r,showModal:t,token:s,error:a,verifying:n,tokenInput:v,handleClick:x,verify:g,forkSkill:w};return Object.defineProperty(k,"__isScriptSetup",{enumerable:!1,value:!0}),k}}),I={class:"w-full max-w-md rounded-2xl border border-white/[0.08] bg-[var(--color-surface-200)] p-6 shadow-2xl"},N={class:"text-sm text-gray-500 mb-4"},j={class:"text-gray-300"},O={key:0,class:"mt-2 text-sm text-red-400"},A={class:"mt-4 flex items-center gap-3"},H=["disabled"],P={key:0,class:"h-4 w-4 animate-spin",fill:"none",viewBox:"0 0 24 24"};function F(h,e,r,t,s,a){return c(),d(T,null,[o("button",{onClick:t.handleClick,class:"inline-flex items-center gap-1.5 rounded-lg border border-white/[0.08] bg-surface-200 px-3.5 py-2 text-sm font-medium text-gray-300 hover:border-white/[0.15] hover:text-white transition-all"},[...e[3]||(e[3]=[o("svg",{class:"h-3.5 w-3.5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[o("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"})],-1),u(" Edit ",-1)])]),(c(),b(S,{to:"body"},[t.showModal?(c(),d("div",{key:0,class:"fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm",onClick:e[2]||(e[2]=p(n=>t.showModal=!1,["self"]))},[o("div",I,[e[7]||(e[7]=o("h3",{class:"text-lg font-semibold text-white mb-1"},"Author Verification",-1)),o("p",N,[e[4]||(e[4]=u(" This skill is owned by ",-1)),o("strong",j,f(r.authorName||r.authorEmail),1),e[5]||(e[5]=u(". Enter your token to edit. ",-1))]),o("form",{onSubmit:p(t.verify,["prevent"])},[C(o("input",{ref:"tokenInput","onUpdate:modelValue":e[0]||(e[0]=n=>t.token=n),type:"password",placeholder:"Paste your author token...",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] px-4 py-2.5 text-sm text-white placeholder-gray-600 font-mono focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[_,t.token]]),t.error?(c(),d("p",O,f(t.error),1)):m("",!0),o("div",A,[o("button",{type:"submit",disabled:t.verifying||!t.token,class:"inline-flex items-center gap-2 rounded-xl bg-[var(--color-accent-500)] px-5 py-2 text-sm font-semibold text-white shadow-lg shadow-[var(--color-accent-500)]/20 hover:bg-[var(--color-accent-600)] disabled:opacity-50 active:scale-[0.97] transition-all"},[t.verifying?(c(),d("svg",P,[...e[6]||(e[6]=[o("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),o("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"},null,-1)])])):m("",!0),u(" "+f(t.verifying?"Verifying...":"Continue to Edit"),1)],8,H),o("button",{type:"button",onClick:t.forkSkill,class:"text-sm text-[var(--color-accent-400)] hover:text-[var(--color-accent-300)] transition-colors"}," Fork instead "),o("button",{type:"button",onClick:e[1]||(e[1]=n=>t.showModal=!1),class:"ml-auto text-sm text-gray-600 hover:text-gray-300 transition-colors"}," Cancel ")])],32)])])):m("",!0)]))],64)}const D=V(B,[["render",F]]);export{D as default};
|
||||
65
dist/client/_astro/SkillEditor.CYIrd0Il.js
vendored
65
dist/client/_astro/SkillEditor.CYIrd0Il.js
vendored
File diff suppressed because one or more lines are too long
66
dist/client/_astro/SkillEditor.DYeR1V3X.js
vendored
Normal file
66
dist/client/_astro/SkillEditor.DYeR1V3X.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/client/_astro/SkillSearch.A7FO5axR.js
vendored
Normal file
1
dist/client/_astro/SkillSearch.A7FO5axR.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/client/_astro/SkillSearch.DXmAyDfU.js
vendored
1
dist/client/_astro/SkillSearch.DXmAyDfU.js
vendored
@@ -1 +0,0 @@
|
||||
import{v as m}from"./runtime-dom.esm-bundler.ALO2-icn.js";import{_ as f}from"./_plugin-vue_export-helper.DlAUqK2U.js";import{c as _,a as r,w as h,e as v,g as x,f as y,o as w}from"./runtime-core.esm-bundler.D9KZBfyO.js";const k=v({__name:"SkillSearch",setup(c,{expose:e}){e();const n=y("");x(n,a=>{const o=a.toLowerCase().trim();document.querySelectorAll("[data-skill]").forEach(s=>{const i=s.dataset.name||"",d=s.dataset.description||"",u=s.dataset.tools||"",p=!o||i.includes(o)||d.includes(o)||u.includes(o);s.style.display=p?"":"none"})});const t={query:n};return Object.defineProperty(t,"__isScriptSetup",{enumerable:!1,value:!0}),t}}),b={class:"mb-6 max-w-md"},S={class:"relative"};function g(c,e,n,t,a,o){return w(),_("div",b,[r("div",S,[e[1]||(e[1]=r("svg",{class:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-600",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor","stroke-width":"2"},[r("path",{"stroke-linecap":"round","stroke-linejoin":"round",d:"m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"})],-1)),h(r("input",{"onUpdate:modelValue":e[0]||(e[0]=l=>t.query=l),type:"text",placeholder:"Search skills...",class:"w-full rounded-xl border border-white/[0.06] bg-[var(--color-surface-100)] pl-10 pr-4 py-2.5 text-sm text-white placeholder-gray-600 focus:border-[var(--color-accent-500)]/50 focus:outline-none focus:ring-1 focus:ring-[var(--color-accent-500)]/20 transition-all"},null,512),[[m,t.query]])])])}const j=f(k,[["render",g]]);export{j as default};
|
||||
1
dist/client/_astro/_slug_.CExMWyw3.css
vendored
1
dist/client/_astro/_slug_.CExMWyw3.css
vendored
File diff suppressed because one or more lines are too long
1
dist/client/_astro/_slug_.DRpcPMTm.css
vendored
Normal file
1
dist/client/_astro/_slug_.DRpcPMTm.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/client/_astro/client.BOmCbIK_.js
vendored
1
dist/client/_astro/client.BOmCbIK_.js
vendored
@@ -1 +0,0 @@
|
||||
import{c as m,d as y}from"./runtime-dom.esm-bundler.ALO2-icn.js";import{e as v,i as r,S}from"./runtime-core.esm-bundler.D9KZBfyO.js";const g=()=>{},A=v({props:{value:String,name:String,hydrate:{type:Boolean,default:!0}},setup({name:t,value:e,hydrate:a}){if(!e)return()=>null;let c=a?"astro-slot":"astro-static-slot";return()=>r(c,{name:t,innerHTML:e})}});var h=A;let p=new WeakMap;var M=t=>async(e,a,c,{client:l})=>{if(!t.hasAttribute("ssr"))return;const f=e.name?`${e.name} Host`:void 0,i={};for(const[n,o]of Object.entries(c))i[n]=()=>r(h,{value:o,name:n==="default"?void 0:n});const u=l!=="only",d=u?m:y;let s=p.get(t);if(s)s.props=a,s.slots=i,s.component.$forceUpdate();else{s={props:a,slots:i};const n=d({name:f,render(){let o=r(e,s.props,s.slots);return s.component=this,b(e.setup)&&(o=r(S,null,o)),o}});n.config.idPrefix=t.getAttribute("prefix")??void 0,await g(),n.mount(t,u),p.set(t,s),t.addEventListener("astro:unmount",()=>n.unmount(),{once:!0})}};function b(t){const e=t?.constructor;return e&&e.name==="AsyncFunction"}export{M as default};
|
||||
1
dist/client/_astro/client.BnTlSu1B.js
vendored
Normal file
1
dist/client/_astro/client.BnTlSu1B.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{h as m,s as r,u as y,x as v,S}from"./runtime-dom.esm-bundler.A7MyAQcw.js";const g=()=>{},h=m({props:{value:String,name:String,hydrate:{type:Boolean,default:!0}},setup({name:t,value:s,hydrate:o}){if(!s)return()=>null;let c=o?"astro-slot":"astro-static-slot";return()=>r(c,{name:t,innerHTML:s})}});var A=h;let p=new WeakMap;var H=t=>async(s,o,c,{client:l})=>{if(!t.hasAttribute("ssr"))return;const f=s.name?`${s.name} Host`:void 0,u={};for(const[n,a]of Object.entries(c))u[n]=()=>r(A,{value:a,name:n==="default"?void 0:n});const i=l!=="only",d=i?y:v;let e=p.get(t);if(e)e.props=o,e.slots=u,e.component.$forceUpdate();else{e={props:o,slots:u};const n=d({name:f,render(){let a=r(s,e.props,e.slots);return e.component=this,b(s.setup)&&(a=r(S,null,a)),a}});n.config.idPrefix=t.getAttribute("prefix")??void 0,await g(),n.mount(t,i),p.set(t,e),t.addEventListener("astro:unmount",()=>n.unmount(),{once:!0})}};function b(t){const s=t?.constructor;return s&&s.name==="AsyncFunction"}export{H as default};
|
||||
File diff suppressed because one or more lines are too long
19
dist/client/_astro/runtime-dom.esm-bundler.A7MyAQcw.js
vendored
Normal file
19
dist/client/_astro/runtime-dom.esm-bundler.A7MyAQcw.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user