CodePage.vue (6730B)
1 <template> 2 <div class="bsc-page"> 3 4 <!-- Header --> 5 <div class="bsc-header"> 6 <div class="bsc-header-top"> 7 <div class="bsc-file-icon"> 8 <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" 9 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 10 <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> 11 <polyline points="14 2 14 8 20 8"/> 12 <line x1="10" y1="13" x2="14" y2="13"/> 13 <line x1="10" y1="17" x2="14" y2="17"/> 14 <line x1="10" y1="9" x2="12" y2="9"/> 15 </svg> 16 </div> 17 <h1 class="bsc-filename"><code>{{ fm.title }}</code></h1> 18 </div> 19 20 <!-- Metadata grid --> 21 <div class="bsc-meta"> 22 <div v-if="fm.lang" class="bsc-meta-row"> 23 <span class="bsc-meta-icon"> 24 <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" 25 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 26 <polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/> 27 </svg> 28 </span> 29 <span class="bsc-meta-key">Lang</span> 30 <span class="bsc-meta-val">{{ fm.lang }}</span> 31 </div> 32 <div v-if="fm.author" class="bsc-meta-row"> 33 <span class="bsc-meta-icon"> 34 <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" 35 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 36 <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/> 37 <circle cx="12" cy="7" r="4"/> 38 </svg> 39 </span> 40 <span class="bsc-meta-key">Author</span> 41 <span class="bsc-meta-val">{{ fm.author }}</span> 42 </div> 43 <div v-if="fm.date" class="bsc-meta-row"> 44 <span class="bsc-meta-icon"> 45 <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" 46 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 47 <rect x="3" y="4" width="18" height="18" rx="2" ry="2"/> 48 <line x1="16" y1="2" x2="16" y2="6"/> 49 <line x1="8" y1="2" x2="8" y2="6"/> 50 <line x1="3" y1="10" x2="21" y2="10"/> 51 </svg> 52 </span> 53 <span class="bsc-meta-key">Date</span> 54 <span class="bsc-meta-val">{{ fm.date }}</span> 55 </div> 56 <div v-if="fm.license" class="bsc-meta-row"> 57 <span class="bsc-meta-icon"> 58 <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" 59 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 60 <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> 61 <polyline points="14 2 14 8 20 8"/> 62 </svg> 63 </span> 64 <span class="bsc-meta-key">License</span> 65 <span class="bsc-meta-val">{{ fm.license }}</span> 66 </div> 67 </div> 68 </div> 69 70 <!-- Problem statement --> 71 <div v-if="fm.problem" class="bsc-problem"> 72 <div class="bsc-problem-label"> 73 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" 74 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 75 <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> 76 <polyline points="14 2 14 8 20 8"/> 77 <line x1="16" y1="13" x2="8" y2="13"/> 78 <line x1="16" y1="17" x2="8" y2="17"/> 79 <polyline points="10 9 9 9 8 9"/> 80 </svg> 81 Problem statement 82 </div> 83 <p>{{ fm.problem }}</p> 84 </div> 85 86 <!-- Actions --> 87 <div class="bsc-actions"> 88 <a :href="fm.raw_url" target="_blank" rel="noopener" class="bsc-btn bsc-btn-primary"> 89 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" 90 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 91 <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> 92 <polyline points="14 2 14 8 20 8"/> 93 </svg> 94 Raw 95 </a> 96 <a :href="fm.github_url" target="_blank" rel="noopener" class="bsc-btn"> 97 <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" 98 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 99 <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"/> 100 </svg> 101 View on GitHub 102 </a> 103 <button class="bsc-btn" @click="copyUrl"> 104 <svg v-if="!copied" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" 105 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 106 <rect x="9" y="9" width="13" height="13" rx="2" ry="2"/> 107 <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/> 108 </svg> 109 <svg v-else xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" 110 fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> 111 <polyline points="20 6 9 17 4 12"/> 112 </svg> 113 {{ copied ? 'Copied!' : 'Copy URL' }} 114 </button> 115 </div> 116 117 <!-- Page slot — renders the markdown content (code block) below --> 118 <slot /> 119 120 </div> 121 </template> 122 123 <script setup lang="ts"> 124 import { ref } from 'vue' 125 import { useData } from 'vitepress' 126 127 const { frontmatter: fm } = useData() 128 const copied = ref(false) 129 130 function copyUrl() { 131 navigator.clipboard.writeText(window.location.href) 132 .then(() => { 133 copied.value = true 134 setTimeout(() => { copied.value = false }, 1800) 135 }) 136 .catch(() => { 137 // fallback 138 const ta = document.createElement('textarea') 139 ta.value = window.location.href 140 ta.style.position = 'fixed' 141 ta.style.opacity = '0' 142 document.body.appendChild(ta) 143 ta.focus() 144 ta.select() 145 try { document.execCommand('copy') } catch {} 146 document.body.removeChild(ta) 147 copied.value = true 148 setTimeout(() => { copied.value = false }, 1800) 149 }) 150 } 151 </script>