PageSourceSearch

https://treningsvideoer.no/assets/videoer._slug-DhZ2KE2V.js

js treningsvideoer.no collected 2026-10-08 07:01:32 UTC 9,427 bytes, 1 lines download raw bytes

1import{u as b,r as d,j as t,L as f,l as v,s as x,n as y,d as j}from"./main-CiqKJGD5.js";import{u as w,d as _}from"./import.functions-Ctz9ETnf.js";import{V as N}from"./VideoCard-BsvCK9pb.js";import{l as k,f as S}from"./format-C6qjlnZW.js";import{u as L}from"./useFavorites-a6IHUFgc.js";import{a as $}from"./useWatchProgress-CiUEOCgr.js";import{a as F,b as C}from"./useVideoRating-C1Gd7F2C.js";function q({videoId:r}){const{user:e}=b(),{myRating:n,average:i,count:a,setRating:c,loading:u}=F(r),[g,o]=d.useState(null),m=g??n??Math.round(i??0);return t.jsxs("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1 mb-6",children:[t.jsx("div",{className:"flex items-center gap-0.5",onMouseLeave:()=>o(null),role:e?"radiogroup":void 0,"aria-label":"Stjernerating",children:[1,2,3,4,5].map(l=>{const s=l<=m;return t.jsx("button",{type:"button",disabled:!e||u,onMouseEnter:()=>e&&o(l),onClick:()=>{c(l)},className:`p-0.5 ${e?"cursor-pointer":"cursor-default"} ${s?"text-band-lime":"text-muted-foreground/40"} hover:scale-110 transition-transform`,"aria-label":`Gi ${l} av 5 stjerner`,title:e?`Gi ${l} av 5 stjerner`:"Logg inn for å gi rating",children:t.jsx("svg",{width:"22",height:"22",viewBox:"0 0 24 24",fill:"currentColor",children:t.jsx("path",{d:"M12 2l2.9 6.95 7.6.65-5.78 5L18.4 22 12 18.1 5.6 22l1.7-7.4L1.5 9.6l7.6-.65L12 2z"})})},l)})}),t.jsx("div",{className:"text-sm text-muted-foreground tabular-nums",children:a>0?t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"font-semibold text-foreground",children:i?.toFixed(1)}),t.jsx("span",{className:"mx-1",children:"·"}),t.jsxs("span",{children:[a," ",a===1?"stemme":"stemmer"]})]}):t.jsx("span",{children:"Ingen ratings ennå"})}),!e&&t.jsx(f,{to:"/logg-inn",className:"text-xs text-accent hover:underline",children:"Logg inn for å gi rating"})]})}function z(){const{slug:r}=v.useParams(),[e,n]=d.useState(null),[i,a]=d.useState([]),[c,u]=d.useState([]),[g,o]=d.useState(!0),[m,l]=d.useState(!1);if($(e?.id??null,e?.youtube_id??null),C(e?.id??null),d.useEffect(()=>{(async()=>{o(!0);const{data:s}=await x.from("videos").select("id, slug, title, description, content_html, youtube_id, duration_seconds, level, muscle_group, meta_title, meta_description, category:categories(id, name, slug), instructor:instructors(name, slug, bio)").eq("slug",r).eq("published",!0).maybeSingle();if(!s){l(!0),o(!1);return}n(s);const{data:p}=await x.from("video_tags").select("tag").eq("video_id",s.id);if(u((p??[]).map(h=>h.tag).filter(Boolean)),s.category?.id){const{data:h}=await x.from("videos").select("slug, title, duration_seconds, level, muscle_group, youtube_id, thumbnail_url, instructor:instructors(name), category:categories(name, slug)").eq("category_id",s.category.id).eq("published",!0).neq("slug",r).limit(3);a(h??[])}o(!1)})()},[r]),d.useEffect(()=>{if(e){document.title=`${e.meta_title||e.title} — Treningsvideoer.no`;const s=document.getElementById("ldjson-video");if(s&&s.remove(),e.youtube_id){const p=document.createElement("script");p.id="ldjson-video",p.type="application/ld+json",p.textContent=JSON.stringify({"@context":"https://schema.org","@type":"VideoObject",name:e.title,description:e.description||e.meta_description||e.title,thumbnailUrl:`https://i.ytimg.com/vi/${e.youtube_id}/maxresdefault.jpg`,embedUrl:`https://www.youtube.com/embed/${e.youtube_id}`,uploadDate:new Date().toISOString()}),document.head.appendChild(p)}}},[e]),m)throw y();return g||!e?t.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-6 py-12",children:[t.jsx("div",{className:"aspect-video bg-secondary rounded-2xl animate-pulse mb-6"}),t.jsx("div",{className:"h-8 bg-secondary rounded w-2/3 animate-pulse"})]}):t.jsxs("article",{className:"max-w-5xl mx-auto px-4 sm:px-6 pt-8 md:pt-12 pb-20",children:[t.jsxs("nav",{className:"text-sm text-muted-foreground mb-4",children:[t.jsx(f,{to:"/",className:"hover:text-foreground",children:"Forsiden"}),e.category&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"mx-2",children:"/"}),t.jsx(f,{to:"/$category",params:{category:e.category.slug},className:"hover:text-foreground",children:e.category.name})]})]}),t.jsx("div",{className:"relative aspect-video bg-foreground rounded-2xl overflow-hidden mb-6",children:e.youtube_id?t.jsx("iframe",{src:`https://www.youtube.com/embed/${e.youtube_id}?rel=0&enablejsapi=1`,"data-yt-id":e.youtube_id,title:e.title,allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",allowFullScreen:!0,loading:"lazy",className:"w-full h-full"}):t.jsx("div",{className:"w-full h-full flex items-center justify-center text-background",children:"Ingen video tilgjengelig"})}),t.jsxs("div",{className:"flex flex-wrap items-center gap-2 mb-3",children:[e.level&&t.jsx("span",{className:"px-2.5 py-1 text-[11px] font-bold uppercase tracking-wider bg-band-lime text-oak-900 rounded-md",children:k(e.level)}),e.muscle_group&&t.jsx("span",{className:"px-2.5 py-1 text-[11px] font-bold uppercase tracking-wider bg-secondary text-foreground rounded-md",children:e.muscle_group}),t.jsx("span",{className:"text-xs text-muted-foreground tabular-nums",children:S(e.duration_seconds)})]}),t.jsx("h1",{className:"font-display font-bold text-3xl md:text-5xl tracking-tight text-balance mb-3",children:e.title}),e.instructor&&t.jsxs("p",{className:"text-muted-foreground mb-6",children:["Med ",t.jsx("span",{className:"text-foreground font-medium",children:e.instructor.name})]}),t.jsx(D,{videoId:e.id}),t.jsx(q,{videoId:e.id}),t.jsx(E,{videoId:e.id,durationSeconds:e.duration_seconds}),t.jsx(R,{videoId:e.id,title:e.title}
1),e.description&&t.jsx("p",{className:"text-lg text-foreground/90 mb-8",children:e.description}),c.length>0&&t.jsxs("div",{className:"mb-8",children:[t.jsx("h2",{className:"text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2",children:"Muskelgrupper"}),t.jsx("div",{className:"flex flex-wrap gap-2",children:c.map(s=>t.jsx("span",{className:"inline-flex items-center px-3 py-1 text-xs font-medium bg-accent/15 text-foreground border border-accent/30 rounded-full capitalize",children:s},s))})]}),e.content_html&&t.jsx("div",{className:"prose prose-neutral max-w-none mb-12",dangerouslySetInnerHTML:{__html:e.content_html}}),t.jsxs("aside",{className:"mt-8 mb-12 p-4 rounded-xl bg-secondary/50 border border-border text-sm text-muted-foreground",children:["Trening på eget ansvar."," ",t.jsx(f,{to:"/treningsansvar",className:"text-accent underline underline-offset-2 hover:text-foreground",children:"Les om treningsansvar →"})]}),i.length>0&&t.jsxs("section",{className:"mt-16 pt-12 border-t border-border",children:[t.jsx("h2",{className:"font-display text-2xl font-bold mb-8",children:"Relaterte videoer"}),t.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-6 gap-y-10",children:i.map(s=>t.jsx(N,{video:s},s.slug))})]})]})}function D({videoId:r}){const{user:e}=b(),{isFavorite:n,toggle:i}=L(),a=n(r);return e?t.jsx("button",{onClick:()=>{i(r)},className:`inline-flex items-center gap-2 px-4 py-2 rounded-full border text-sm font-medium transition-colors mb-8 ${a?"bg-accent text-accent-foreground border-accent":"bg-secondary border-border hover:border-accent"}`,children:a?"♥ Lagret som favoritt":"♡ Legg til favoritter"}):t.jsx(f,{to:"/logg-inn",className:"inline-flex items-center gap-2 px-4 py-2 rounded-full bg-secondary border border-border text-sm font-medium hover:border-accent transition-colors mb-8",children:"♡ Logg inn for å lagre som favoritt"})}function E({videoId:r,durationSeconds:e}){const{user:n}=b(),[i,a]=d.useState(!1),[c,u]=d.useState(!1),[g,o]=d.useState(!1);if(d.useEffect(()=>{if(!n){o(!0);return}let l=!0;return x.from("workout_completions").select("id").eq("user_id",n.id).eq("video_id",r).gte("completed_at",new Date(new Date().setHours(0,0,0,0)).toISOString()).limit(1).maybeSingle().then(({data:s})=>{l&&(a(!!s),o(!0))}),()=>{l=!1}},[n,r]),!n||!g)return null;async function m(){if(n){if(u(!0),i){const l=new Date(new Date().setHours(0,0,0,0)).toISOString();await x.from("workout_completions").delete().eq("user_id",n.id).eq("video_id",r).gte("completed_at",l),a(!1)}else await x.from("workout_completions").insert({user_id:n.id,video_id:r,duration_seconds:e??0}),a(!0);u(!1)}}return t.jsx("button",{onClick:()=>{m()},disabled:c,className:`ml-2 inline-flex items-center gap-2 px-4 py-2 rounded-full border text-sm font-medium transition-colors mb-8 disabled:opacity-50 ${i?"bg-band-lime text-oak-900 border-band-lime":"bg-secondary border-border hover:border-accent"}`,children:i?"✓ Fullført i dag":"✓ Marker som fullført"})}function R({videoId:r,title:e}){const{isAdmin:n}=b(),i=j(),a=w(_),[c,u]=d.useState(!1);if(!n)return null;async function g(){if(confirm(`Slette videoen "${e}"? Dette kan ikke angres.`)){u(!0);try{const{data:{session:o}}=await x.auth.getSession(),m=o?.access_token;if(!m)throw new Error("Ikke innlogget");await a({data:{accessToken:m,videoId:r}}),i({to:"/"})}catch(o){alert(`Kunne ikke slette: ${o instanceof Error?o.message:String(o)}`),u(!1)}}}return t.jsx("button",{onClick:g,disabled:c,className:"ml-2 inline-flex items-center gap-2 px-4 py-2 rounded-full border border-destructive/40 bg-destructive/10 text-destructive text-sm font-medium hover:bg-destructive hover:text-destructive-foreground transition-colors mb-8 disabled:opacity-50",children:c?"Sletter...":"🗑 Slett video (admin)"})}export{z as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.