|
1 | 1 | <script setup> |
2 | | -defineProps({ |
| 2 | +import { computed } from "vue"; |
| 3 | +import * as LucideIcons from "lucide-vue-next"; |
| 4 | +
|
| 5 | +const props = defineProps({ |
3 | 6 | title: String, |
4 | 7 | icon: String, |
5 | 8 | href: String, |
6 | 9 | }); |
| 10 | +
|
| 11 | +// Custom SVG icons for brands |
| 12 | +const customSvgIcons = { |
| 13 | + asana: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18.559 13.605a5.158 5.158 0 1 0 0 10.317 5.158 5.158 0 0 0 0-10.317Zm-13.401.001a5.158 5.158 0 1 0 0 10.315 5.158 5.158 0 0 0 0-10.315Zm11.858-6.448a5.158 5.158 0 1 1-10.316 0 5.158 5.158 0 0 1 10.316 0Z" fill="#F06A6A"/></svg>`, |
| 14 | + clickup: `<svg width="24" height="24" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M2 23.5l4.5-3.5c2.4 3.1 5 4.6 7.8 4.6 2.8 0 5.3-1.4 7.6-4.5l4.6 3.4c-3.3 4.5-7.4 6.9-12.2 6.9-4.7 0-8.9-2.4-12.3-6.9z" fill="url(#clickup-a)" fill-rule="evenodd"/><path clip-rule="evenodd" d="M14.1 8.5l-8 6.9-3.7-4.3L14.1 1l11.7 10.2-3.7 4.3z" fill="url(#clickup-b)" fill-rule="evenodd"/><defs><linearGradient id="clickup-a" x1="2" x2="26.5" y1="26" y2="26" gradientUnits="userSpaceOnUse"><stop stop-color="#8930FD"/><stop offset="1" stop-color="#49CCF9"/></linearGradient><linearGradient id="clickup-b" x1="2.4" x2="25.8" y1="10" y2="10" gradientUnits="userSpaceOnUse"><stop stop-color="#FF02F0"/><stop offset="1" stop-color="#FFC800"/></linearGradient></defs></svg>`, |
| 15 | + confluence: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.724 17.47c-.247.406-.518.892-.754 1.282a.665.665 0 0 0 .227.91l4.96 3.044a.666.666 0 0 0 .91-.216c.2-.334.46-.772.752-1.263 1.87-3.137 3.722-2.756 7.11-1.128l4.986 2.384a.666.666 0 0 0 .88-.31l2.104-4.678a.666.666 0 0 0-.318-.86c-1.33-.636-3.97-1.896-6.01-2.87-5.44-2.598-10.116-2.544-14.847 3.705Z" fill="url(#confluence-a)"/><path d="M21.276 6.53c.247-.406.518-.892.754-1.282a.665.665 0 0 0-.227-.91L16.843 1.294a.666.666 0 0 0-.91.216c-.2.334-.46.772-.752 1.263-1.87 3.137-3.722 2.756-7.11 1.128L3.085 1.517a.666.666 0 0 0-.88.31L.1 6.505a.666.666 0 0 0 .318.86c1.33.636 3.97 1.896 6.01 2.87 5.44 2.598 10.116 2.544 14.847-3.705Z" fill="url(#confluence-b)"/><defs><linearGradient id="confluence-a" x1="22.48" y1="24.04" x2="9.89" y2="15.06" gradientUnits="userSpaceOnUse"><stop stop-color="#0052CC"/><stop offset="1" stop-color="#2684FF"/></linearGradient><linearGradient id="confluence-b" x1="1.52" y1="-.04" x2="14.11" y2="8.94" gradientUnits="userSpaceOnUse"><stop stop-color="#0052CC"/><stop offset="1" stop-color="#2684FF"/></linearGradient></defs></svg>`, |
| 16 | + csv: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6Z" stroke="#006399" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M14 2v6h6M8 13h2M8 17h2M14 13h2M14 17h2" stroke="#006399" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`, |
| 17 | + drawio: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><line x1="12" y1="7.5" x2="7" y2="14.5" stroke="#F08705" stroke-width="1.5"/><line x1="12" y1="7.5" x2="17" y2="14.5" stroke="#F08705" stroke-width="1.5"/><rect x="9" y="3" width="6" height="5" rx="1" fill="#F08705"/><rect x="3" y="14" width="6" height="5" rx="1" fill="#F08705"/><rect x="15" y="14" width="6" height="5" rx="1" fill="#F08705"/></svg>`, |
| 18 | + github: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0 1 12 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12Z" fill="currentColor"/></svg>`, |
| 19 | + gitlab: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.875.875 0 0 0-.994.053.873.873 0 0 0-.29.442l-2.204 6.748H7.528L5.324 1.07a.857.857 0 0 0-.29-.441.875.875 0 0 0-.994-.054.859.859 0 0 0-.336.405L.437 9.507l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.027.019 4.976 3.727 2.462 1.863 1.5 1.132a1.008 1.008 0 0 0 1.22 0l1.5-1.132 2.461-1.863 5.004-3.746.012-.01a6.068 6.068 0 0 0 2.011-7.01Z" fill="#E24329"/><path d="m23.6 9.593-.033-.086a11.093 11.093 0 0 0-4.401 1.972l-7.163 5.427 4.57 3.453 5.004-3.746.012-.01a6.068 6.068 0 0 0 2.011-7.01Z" fill="#FC6D26"/><path d="m7.43 20.36 2.462 1.862 1.5 1.132a1.008 1.008 0 0 0 1.22 0l1.5-1.132 2.46-1.863-4.569-3.453L7.43 20.36Z" fill="#FCA326"/><path d="M4.837 11.479a11.076 11.076 0 0 0-4.4-1.972l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.027.019 4.976 3.727 4.573-3.456-7.166-5.423Z" fill="#FC6D26"/></svg>`, |
| 20 | + jira: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.53 2c0 2.4 1.97 4.35 4.35 4.35h1.78v1.7c0 2.4 1.97 4.35 4.35 4.35V2.88A.88.88 0 0 0 21.12 2H11.53Z" fill="#2684FF"/><path d="M6.77 6.8c0 2.4 1.97 4.34 4.35 4.34h1.78v1.71c0 2.4 1.97 4.35 4.35 4.35V7.68a.88.88 0 0 0-.88-.88H6.77Z" fill="url(#jira-a)"/><path d="M2 11.6c0 2.4 1.97 4.35 4.35 4.35h1.78v1.7c0 2.4 1.97 4.35 4.35 4.35v-9.52a.88.88 0 0 0-.88-.88H2Z" fill="url(#jira-b)"/><defs><linearGradient id="jira-a" x1="16.89" y1="6.82" x2="10.74" y2="12.99" gradientUnits="userSpaceOnUse"><stop stop-color="#0052CC"/><stop offset="1" stop-color="#2684FF"/></linearGradient><linearGradient id="jira-b" x1="12.19" y1="11.61" x2="5.97" y2="17.84" gradientUnits="userSpaceOnUse"><stop stop-color="#0052CC"/><stop offset="1" stop-color="#2684FF"/></linearGradient></defs></svg>`, |
| 21 | + linear: `<svg width="24" height="24" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.9266 16.3713c-.5283.5806-.4933 1.4714.0617 2.0265l68.5946 68.5946c.5551.555 1.4459.59 2.0265.0617 10.0579-9.1522 16.3713-22.3478 16.3713-37.0179C99.9807 22.402 77.5788 0 49.9445 0 35.2744 0 22.0788 6.31337 12.9266 16.3713ZM4.35334 29.3894c-.25348.5589-.12567 1.2142.30824 1.6481L68.9432 95.3191c.4339.4339 1.0892.5617 1.6481.3083 1.485-.6736 2.9312-1.4176 4.3344-2.2277.8341-.4815.9618-1.6195.2808-2.3005L8.88146 24.7742c-.68097-.681-1.81894-.5532-2.30045.2808-.81013 1.4032-1.55411 2.8494-2.22767 4.3344ZM.453579 47.796c-.300979-.301-.46112014-.7158-.4327856-1.1405.1327026-1.9891.3816396-3.9463.7400796-5.865.214926-1.1505 1.620727-1.5497 2.448307-.7222L59.9124 96.7715c.8275.8276.4283 2.2334-.7222 2.4483-1.9187.3585-3.8759.6074-5.865.7401-.4247.0283-.8395-.1318-1.1405-.4328L.453579 47.796ZM3.93331 61.7589c-1.0331-1.0331-2.70028-.1429-2.32193 1.2683C6.22104 80.2203 19.7604 93.7597 36.9535 98.3693c1.4112.3784 2.3014-1.2888 1.2683-2.3219L3.93331 61.7589Z" fill="#5E6AD2"/></svg>`, |
| 22 | + notion: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.459 4.208c.746.606 1.026.56 2.428.466l13.215-.793c.28 0 .047-.28-.046-.326L18.1 2.138c-.42-.373-.934-.653-1.96-.56l-12.8.84c-.467.046-.56.28-.373.466l1.493 1.324Zm.793 2.986v13.868c0 .747.373 1.027 1.213.98l14.523-.84c.84-.046.934-.56.934-1.166V6.148c0-.606-.233-.933-.747-.886l-15.177.886c-.56.047-.746.327-.746.886v.06Zm14.337.56c.093.42 0 .84-.42.886l-.7.14v10.265c-.607.327-1.167.514-1.634.514-.747 0-.933-.234-1.493-.933l-4.573-7.186v6.953l1.447.327s0 .84-1.167.84l-3.22.186c-.093-.186 0-.653.327-.746l.84-.233V9.854L7.373 9.76c-.093-.42.14-1.026.793-1.073l3.454-.233 4.76 7.28v-6.44l-1.213-.14c-.094-.514.28-.886.746-.933l3.453-.186.047-.28v-.047l-.094-.046-.14-.047-.28-.046Z" fill="currentColor"/></svg>`, |
| 23 | + sentry: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.91 1.16c-.41-.7-1.19-.78-1.62-.78-.43 0-1.21.08-1.62.78L7.06 6.64c4.99 2.46 8.33 7.35 8.7 12.86h-2.26c-.37-4.7-3.23-8.86-7.55-10.93l-2.98 5.08c2.42 1.07 4.13 3.28 4.52 5.85H2.23c-.13-.01-.24-.08-.3-.21-.06-.1-.06-.25 0-.36l1.44-2.42c-.49-.4-.94-.84-1.34-1.31L.56 18c-.3.51-.38 1.11-.23 1.67.15.56.51 1.04 1 1.33.33.19.72.29 1.11.29h7.1c.27-3.26-1.19-6.44-3.9-8.35l1.13-1.93c3.4 2.28 5.31 6.2 5.03 10.28h6.01c.28-6.14-2.76-11.97-7.96-15.31l2.28-3.86c.1-.17.33-.23.49-.11.26.14 9.88 16.61 10.06 16.8.07.11.06.25 0 .37-.07.11-.19.18-.33.18h-2.33c.03.61.03 1.23 0 1.84h2.34c.6 0 1.17-.23 1.59-.65.43-.41.66-.98.66-1.57 0-.39-.1-.77-.3-1.1L13.91 1.16Z" fill="currentColor"/></svg>`, |
| 24 | + slack: `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52ZM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313ZM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834ZM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312ZM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834ZM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312ZM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52ZM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313Z" fill="#E01E5A"/><path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52ZM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313Z" fill="#E01E5A"/><path d="M8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834ZM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312Z" fill="#36C5F0"/><path d="M18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834ZM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312Z" fill="#2EB67D"/><path d="M15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52ZM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313Z" fill="#ECB22E"/></svg>`, |
| 25 | +}; |
| 26 | +
|
| 27 | +const IconComponent = computed(() => { |
| 28 | + if (!props.icon) return null; |
| 29 | +
|
| 30 | + // Check if we have a custom SVG for this icon |
| 31 | + if (customSvgIcons[props.icon]) { |
| 32 | + return null; // Will use v-html for custom SVGs |
| 33 | + } |
| 34 | +
|
| 35 | + // Otherwise try to get it from Lucide |
| 36 | + const iconName = props.icon |
| 37 | + .split("-") |
| 38 | + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) |
| 39 | + .join(""); |
| 40 | +
|
| 41 | + return LucideIcons[iconName] || LucideIcons.HelpCircle; |
| 42 | +}); |
7 | 43 | </script> |
8 | 44 |
|
9 | 45 | <template> |
10 | | - <component :is="href ? 'a' : 'div'" :href="href" class="card-link"> |
11 | | - <div class="card-icon"> |
12 | | - <slot name="icon" /> |
| 46 | + <a :href="href" class="card-link"> |
| 47 | + <div v-if="icon" class="card-icon"> |
| 48 | + <!-- Render custom SVG if available --> |
| 49 | + <div v-if="customSvgIcons[icon]" v-html="customSvgIcons[icon]"></div> |
| 50 | + <!-- Otherwise render Lucide icon --> |
| 51 | + <component v-else :is="IconComponent" :size="24" /> |
13 | 52 | </div> |
14 | | - <h3 class="card-title">{{ title }}</h3> |
| 53 | + <h3 class="card-title"> |
| 54 | + {{ title }} |
| 55 | + </h3> |
15 | 56 | <p class="card-description"> |
16 | 57 | <slot /> |
17 | 58 | </p> |
18 | | - </component> |
| 59 | + </a> |
19 | 60 | </template> |
0 commit comments