[autofix.ci] apply automated fixes

This commit is contained in:
autofix-ci[bot]
2026-01-28 10:38:52 +00:00
committed by GitHub
parent d5b0e3193a
commit ad382f1fe5
6 changed files with 4423 additions and 4431 deletions

View File

@@ -1,279 +1,279 @@
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
interface Props { interface Props {
className?: string; className?: string;
} }
export const SlackIcon = ({ className }: Props) => { export const SlackIcon = ({ className }: Props) => {
return ( return (
<svg <svg
viewBox="0 0 2447.6 2452.5" viewBox="0 0 2447.6 2452.5"
className={cn("size-8", className)} className={cn("size-8", className)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<g clipRule="evenodd" fillRule="evenodd"> <g clipRule="evenodd" fillRule="evenodd">
<path <path
d="m897.4 0c-135.3.1-244.8 109.9-244.7 245.2-.1 135.3 109.5 245.1 244.8 245.2h244.8v-245.1c.1-135.3-109.5-245.1-244.9-245.3.1 0 .1 0 0 0m0 654h-652.6c-135.3.1-244.9 109.9-244.8 245.2-.2 135.3 109.4 245.1 244.7 245.3h652.7c135.3-.1 244.9-109.9 244.8-245.2.1-135.4-109.5-245.2-244.8-245.3z" d="m897.4 0c-135.3.1-244.8 109.9-244.7 245.2-.1 135.3 109.5 245.1 244.8 245.2h244.8v-245.1c.1-135.3-109.5-245.1-244.9-245.3.1 0 .1 0 0 0m0 654h-652.6c-135.3.1-244.9 109.9-244.8 245.2-.2 135.3 109.4 245.1 244.7 245.3h652.7c135.3-.1 244.9-109.9 244.8-245.2.1-135.4-109.5-245.2-244.8-245.3z"
fill="#36c5f0" fill="#36c5f0"
/> />
<path <path
d="m2447.6 899.2c.1-135.3-109.5-245.1-244.8-245.2-135.3.1-244.9 109.9-244.8 245.2v245.3h244.8c135.3-.1 244.9-109.9 244.8-245.3zm-652.7 0v-654c.1-135.2-109.4-245-244.7-245.2-135.3.1-244.9 109.9-244.8 245.2v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.3z" d="m2447.6 899.2c.1-135.3-109.5-245.1-244.8-245.2-135.3.1-244.9 109.9-244.8 245.2v245.3h244.8c135.3-.1 244.9-109.9 244.8-245.3zm-652.7 0v-654c.1-135.2-109.4-245-244.7-245.2-135.3.1-244.9 109.9-244.8 245.2v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.3z"
fill="#2eb67d" fill="#2eb67d"
/> />
<path <path
d="m1550.1 2452.5c135.3-.1 244.9-109.9 244.8-245.2.1-135.3-109.5-245.1-244.8-245.2h-244.8v245.2c-.1 135.2 109.5 245 244.8 245.2zm0-654.1h652.7c135.3-.1 244.9-109.9 244.8-245.2.2-135.3-109.4-245.1-244.7-245.3h-652.7c-135.3.1-244.9 109.9-244.8 245.2-.1 135.4 109.4 245.2 244.7 245.3z" d="m1550.1 2452.5c135.3-.1 244.9-109.9 244.8-245.2.1-135.3-109.5-245.1-244.8-245.2h-244.8v245.2c-.1 135.2 109.5 245 244.8 245.2zm0-654.1h652.7c135.3-.1 244.9-109.9 244.8-245.2.2-135.3-109.4-245.1-244.7-245.3h-652.7c-135.3.1-244.9 109.9-244.8 245.2-.1 135.4 109.4 245.2 244.7 245.3z"
fill="#ecb22e" fill="#ecb22e"
/> />
<path <path
d="m0 1553.2c-.1 135.3 109.5 245.1 244.8 245.2 135.3-.1 244.9-109.9 244.8-245.2v-245.2h-244.8c-135.3.1-244.9 109.9-244.8 245.2zm652.7 0v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.2v-653.9c.2-135.3-109.4-245.1-244.7-245.3-135.4 0-244.9 109.8-244.8 245.1 0 0 0 .1 0 0" d="m0 1553.2c-.1 135.3 109.5 245.1 244.8 245.2 135.3-.1 244.9-109.9 244.8-245.2v-245.2h-244.8c-135.3.1-244.9 109.9-244.8 245.2zm652.7 0v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.2v-653.9c.2-135.3-109.4-245.1-244.7-245.3-135.4 0-244.9 109.8-244.8 245.1 0 0 0 .1 0 0"
fill="#e01e5a" fill="#e01e5a"
/> />
</g> </g>
</svg> </svg>
); );
}; };
export const TelegramIcon = ({ className }: Props) => { export const TelegramIcon = ({ className }: Props) => {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48" viewBox="0 0 48 48"
width="48px" width="48px"
height="48px" height="48px"
className={cn("size-9", className)} className={cn("size-9", className)}
> >
<linearGradient <linearGradient
id="BiF7D16UlC0RZ_VqXJHnXa" id="BiF7D16UlC0RZ_VqXJHnXa"
x1="9.858" x1="9.858"
x2="38.142" x2="38.142"
y1="9.858" y1="9.858"
y2="38.142" y2="38.142"
gradientUnits="userSpaceOnUse" gradientUnits="userSpaceOnUse"
> >
<stop offset="0" stopColor="#33bef0" /> <stop offset="0" stopColor="#33bef0" />
<stop offset="1" stopColor="#0a85d9" /> <stop offset="1" stopColor="#0a85d9" />
</linearGradient> </linearGradient>
<path <path
fill="url(#BiF7D16UlC0RZ_VqXJHnXa)" fill="url(#BiF7D16UlC0RZ_VqXJHnXa)"
d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z" d="M44,24c0,11.045-8.955,20-20,20S4,35.045,4,24S12.955,4,24,4S44,12.955,44,24z"
/> />
<path <path
d="M10.119,23.466c8.155-3.695,17.733-7.704,19.208-8.284c3.252-1.279,4.67,0.028,4.448,2.113 c-0.273,2.555-1.567,9.99-2.363,15.317c-0.466,3.117-2.154,4.072-4.059,2.863c-1.445-0.917-6.413-4.17-7.72-5.282 c-0.891-0.758-1.512-1.608-0.88-2.474c0.185-0.253,0.658-0.763,0.921-1.017c1.319-1.278,1.141-1.553-0.454-0.412 c-0.19,0.136-1.292,0.935-1.745,1.237c-1.11,0.74-2.131,0.78-3.862,0.192c-1.416-0.481-2.776-0.852-3.634-1.223 C8.794,25.983,8.34,24.272,10.119,23.466z" d="M10.119,23.466c8.155-3.695,17.733-7.704,19.208-8.284c3.252-1.279,4.67,0.028,4.448,2.113 c-0.273,2.555-1.567,9.99-2.363,15.317c-0.466,3.117-2.154,4.072-4.059,2.863c-1.445-0.917-6.413-4.17-7.72-5.282 c-0.891-0.758-1.512-1.608-0.88-2.474c0.185-0.253,0.658-0.763,0.921-1.017c1.319-1.278,1.141-1.553-0.454-0.412 c-0.19,0.136-1.292,0.935-1.745,1.237c-1.11,0.74-2.131,0.78-3.862,0.192c-1.416-0.481-2.776-0.852-3.634-1.223 C8.794,25.983,8.34,24.272,10.119,23.466z"
opacity=".05" opacity=".05"
/> />
<path <path
d="M10.836,23.591c7.572-3.385,16.884-7.264,18.246-7.813c3.264-1.318,4.465-0.536,4.114,2.011 c-0.326,2.358-1.483,9.654-2.294,14.545c-0.478,2.879-1.874,3.513-3.692,2.337c-1.139-0.734-5.723-3.754-6.835-4.633 c-0.86-0.679-1.751-1.463-0.71-2.598c0.348-0.379,2.27-2.234,3.707-3.614c0.833-0.801,0.536-1.196-0.469-0.508 c-1.843,1.263-4.858,3.262-5.396,3.625c-1.025,0.69-1.988,0.856-3.664,0.329c-1.321-0.416-2.597-0.819-3.262-1.078 C9.095,25.618,9.075,24.378,10.836,23.591z" d="M10.836,23.591c7.572-3.385,16.884-7.264,18.246-7.813c3.264-1.318,4.465-0.536,4.114,2.011 c-0.326,2.358-1.483,9.654-2.294,14.545c-0.478,2.879-1.874,3.513-3.692,2.337c-1.139-0.734-5.723-3.754-6.835-4.633 c-0.86-0.679-1.751-1.463-0.71-2.598c0.348-0.379,2.27-2.234,3.707-3.614c0.833-0.801,0.536-1.196-0.469-0.508 c-1.843,1.263-4.858,3.262-5.396,3.625c-1.025,0.69-1.988,0.856-3.664,0.329c-1.321-0.416-2.597-0.819-3.262-1.078 C9.095,25.618,9.075,24.378,10.836,23.591z"
opacity=".07" opacity=".07"
/> />
<path <path
fill="#fff" fill="#fff"
d="M11.553,23.717c6.99-3.075,16.035-6.824,17.284-7.343c3.275-1.358,4.28-1.098,3.779,1.91 c-0.36,2.162-1.398,9.319-2.226,13.774c-0.491,2.642-1.593,2.955-3.325,1.812c-0.833-0.55-5.038-3.331-5.951-3.984 c-0.833-0.595-1.982-1.311-0.541-2.721c0.513-0.502,3.874-3.712,6.493-6.21c0.343-0.328-0.088-0.867-0.484-0.604 c-3.53,2.341-8.424,5.59-9.047,6.013c-0.941,0.639-1.845,0.932-3.467,0.466c-1.226-0.352-2.423-0.772-2.889-0.932 C9.384,25.282,9.81,24.484,11.553,23.717z" d="M11.553,23.717c6.99-3.075,16.035-6.824,17.284-7.343c3.275-1.358,4.28-1.098,3.779,1.91 c-0.36,2.162-1.398,9.319-2.226,13.774c-0.491,2.642-1.593,2.955-3.325,1.812c-0.833-0.55-5.038-3.331-5.951-3.984 c-0.833-0.595-1.982-1.311-0.541-2.721c0.513-0.502,3.874-3.712,6.493-6.21c0.343-0.328-0.088-0.867-0.484-0.604 c-3.53,2.341-8.424,5.59-9.047,6.013c-0.941,0.639-1.845,0.932-3.467,0.466c-1.226-0.352-2.423-0.772-2.889-0.932 C9.384,25.282,9.81,24.484,11.553,23.717z"
/> />
</svg> </svg>
); );
}; };
export const DiscordIcon = ({ className }: Props) => { export const DiscordIcon = ({ className }: Props) => {
return ( return (
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48" viewBox="0 0 48 48"
width="48px" width="48px"
height="48px" height="48px"
className={cn("size-9", className)} className={cn("size-9", className)}
> >
<path <path
fill="#536dfe" fill="#536dfe"
d="M39.248,10.177c-2.804-1.287-5.812-2.235-8.956-2.778c-0.057-0.01-0.114,0.016-0.144,0.068 c-0.387,0.688-0.815,1.585-1.115,2.291c-3.382-0.506-6.747-0.506-10.059,0c-0.3-0.721-0.744-1.603-1.133-2.291 c-0.03-0.051-0.087-0.077-0.144-0.068c-3.143,0.541-6.15,1.489-8.956,2.778c-0.024,0.01-0.045,0.028-0.059,0.051 c-5.704,8.522-7.267,16.835-6.5,25.044c0.003,0.04,0.026,0.079,0.057,0.103c3.763,2.764,7.409,4.442,10.987,5.554 c0.057,0.017,0.118-0.003,0.154-0.051c0.846-1.156,1.601-2.374,2.248-3.656c0.038-0.075,0.002-0.164-0.076-0.194 c-1.197-0.454-2.336-1.007-3.432-1.636c-0.087-0.051-0.094-0.175-0.014-0.234c0.231-0.173,0.461-0.353,0.682-0.534 c0.04-0.033,0.095-0.04,0.142-0.019c7.201,3.288,14.997,3.288,22.113,0c0.047-0.023,0.102-0.016,0.144,0.017 c0.22,0.182,0.451,0.363,0.683,0.536c0.08,0.059,0.075,0.183-0.012,0.234c-1.096,0.641-2.236,1.182-3.434,1.634 c-0.078,0.03-0.113,0.12-0.075,0.196c0.661,1.28,1.415,2.498,2.246,3.654c0.035,0.049,0.097,0.07,0.154,0.052 c3.595-1.112,7.241-2.79,11.004-5.554c0.033-0.024,0.054-0.061,0.057-0.101c0.917-9.491-1.537-17.735-6.505-25.044 C39.293,10.205,39.272,10.187,39.248,10.177z M16.703,30.273c-2.168,0-3.954-1.99-3.954-4.435s1.752-4.435,3.954-4.435 c2.22,0,3.989,2.008,3.954,4.435C20.658,28.282,18.906,30.273,16.703,30.273z M31.324,30.273c-2.168,0-3.954-1.99-3.954-4.435 s1.752-4.435,3.954-4.435c2.22,0,3.989,2.008,3.954,4.435C35.278,28.282,33.544,30.273,31.324,30.273z" d="M39.248,10.177c-2.804-1.287-5.812-2.235-8.956-2.778c-0.057-0.01-0.114,0.016-0.144,0.068 c-0.387,0.688-0.815,1.585-1.115,2.291c-3.382-0.506-6.747-0.506-10.059,0c-0.3-0.721-0.744-1.603-1.133-2.291 c-0.03-0.051-0.087-0.077-0.144-0.068c-3.143,0.541-6.15,1.489-8.956,2.778c-0.024,0.01-0.045,0.028-0.059,0.051 c-5.704,8.522-7.267,16.835-6.5,25.044c0.003,0.04,0.026,0.079,0.057,0.103c3.763,2.764,7.409,4.442,10.987,5.554 c0.057,0.017,0.118-0.003,0.154-0.051c0.846-1.156,1.601-2.374,2.248-3.656c0.038-0.075,0.002-0.164-0.076-0.194 c-1.197-0.454-2.336-1.007-3.432-1.636c-0.087-0.051-0.094-0.175-0.014-0.234c0.231-0.173,0.461-0.353,0.682-0.534 c0.04-0.033,0.095-0.04,0.142-0.019c7.201,3.288,14.997,3.288,22.113,0c0.047-0.023,0.102-0.016,0.144,0.017 c0.22,0.182,0.451,0.363,0.683,0.536c0.08,0.059,0.075,0.183-0.012,0.234c-1.096,0.641-2.236,1.182-3.434,1.634 c-0.078,0.03-0.113,0.12-0.075,0.196c0.661,1.28,1.415,2.498,2.246,3.654c0.035,0.049,0.097,0.07,0.154,0.052 c3.595-1.112,7.241-2.79,11.004-5.554c0.033-0.024,0.054-0.061,0.057-0.101c0.917-9.491-1.537-17.735-6.505-25.044 C39.293,10.205,39.272,10.187,39.248,10.177z M16.703,30.273c-2.168,0-3.954-1.99-3.954-4.435s1.752-4.435,3.954-4.435 c2.22,0,3.989,2.008,3.954,4.435C20.658,28.282,18.906,30.273,16.703,30.273z M31.324,30.273c-2.168,0-3.954-1.99-3.954-4.435 s1.752-4.435,3.954-4.435c2.22,0,3.989,2.008,3.954,4.435C35.278,28.282,33.544,30.273,31.324,30.273z"
/> />
</svg> </svg>
); );
}; };
export const LarkIcon = ({ className }: Props) => { export const LarkIcon = ({ className }: Props) => {
return ( return (
<svg <svg
width="1em" width="1em"
height="1em" height="1em"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
data-icon="LarkLogoColorful" data-icon="LarkLogoColorful"
className={cn("size-9", className)} className={cn("size-9", className)}
> >
<path <path
d="m12.924 12.803.056-.054c.038-.034.076-.072.11-.11l.077-.076.23-.227 1.334-1.319.335-.331c.063-.063.13-.123.195-.183a7.777 7.777 0 0 1 1.823-1.24 7.607 7.607 0 0 1 1.014-.4 13.177 13.177 0 0 0-2.5-5.013 1.203 1.203 0 0 0-.94-.448h-9.65c-.173 0-.246.224-.107.325a28.23 28.23 0 0 1 8 9.098c.007-.006.016-.013.023-.022Z" d="m12.924 12.803.056-.054c.038-.034.076-.072.11-.11l.077-.076.23-.227 1.334-1.319.335-.331c.063-.063.13-.123.195-.183a7.777 7.777 0 0 1 1.823-1.24 7.607 7.607 0 0 1 1.014-.4 13.177 13.177 0 0 0-2.5-5.013 1.203 1.203 0 0 0-.94-.448h-9.65c-.173 0-.246.224-.107.325a28.23 28.23 0 0 1 8 9.098c.007-.006.016-.013.023-.022Z"
fill="#00D6B9" fill="#00D6B9"
/> />
<path <path
d="M9.097 21.299a13.258 13.258 0 0 0 11.82-7.247 5.576 5.576 0 0 1-.731 1.076 5.315 5.315 0 0 1-.745.7 5.117 5.117 0 0 1-.615.404 4.626 4.626 0 0 1-.726.331 5.312 5.312 0 0 1-1.883.312 5.892 5.892 0 0 1-.524-.031 6.509 6.509 0 0 1-.729-.126c-.06-.016-.12-.029-.18-.044-.166-.044-.33-.092-.494-.14-.082-.024-.164-.046-.246-.072-.123-.038-.247-.072-.366-.11l-.3-.095-.284-.094-.192-.067c-.08-.025-.155-.053-.234-.082a3.49 3.49 0 0 1-.167-.06c-.11-.04-.221-.079-.328-.12-.063-.025-.126-.047-.19-.072l-.252-.098c-.088-.035-.18-.07-.268-.107l-.174-.07c-.072-.028-.141-.06-.214-.088l-.164-.07c-.057-.024-.114-.05-.17-.075l-.149-.066-.135-.06-.14-.063a90.183 90.183 0 0 1-.141-.066 4.808 4.808 0 0 0-.18-.083c-.063-.028-.123-.06-.186-.088a5.697 5.697 0 0 1-.199-.098 27.762 27.762 0 0 1-8.067-5.969.18.18 0 0 0-.312.123l.006 9.21c0 .4.199.779.533 1a13.177 13.177 0 0 0 7.326 2.205Z" d="M9.097 21.299a13.258 13.258 0 0 0 11.82-7.247 5.576 5.576 0 0 1-.731 1.076 5.315 5.315 0 0 1-.745.7 5.117 5.117 0 0 1-.615.404 4.626 4.626 0 0 1-.726.331 5.312 5.312 0 0 1-1.883.312 5.892 5.892 0 0 1-.524-.031 6.509 6.509 0 0 1-.729-.126c-.06-.016-.12-.029-.18-.044-.166-.044-.33-.092-.494-.14-.082-.024-.164-.046-.246-.072-.123-.038-.247-.072-.366-.11l-.3-.095-.284-.094-.192-.067c-.08-.025-.155-.053-.234-.082a3.49 3.49 0 0 1-.167-.06c-.11-.04-.221-.079-.328-.12-.063-.025-.126-.047-.19-.072l-.252-.098c-.088-.035-.18-.07-.268-.107l-.174-.07c-.072-.028-.141-.06-.214-.088l-.164-.07c-.057-.024-.114-.05-.17-.075l-.149-.066-.135-.06-.14-.063a90.183 90.183 0 0 1-.141-.066 4.808 4.808 0 0 0-.18-.083c-.063-.028-.123-.06-.186-.088a5.697 5.697 0 0 1-.199-.098 27.762 27.762 0 0 1-8.067-5.969.18.18 0 0 0-.312.123l.006 9.21c0 .4.199.779.533 1a13.177 13.177 0 0 0 7.326 2.205Z"
fill="#3370FF" fill="#3370FF"
/> />
<path <path
d="M23.732 9.295a7.55 7.55 0 0 0-3.35-.776 7.521 7.521 0 0 0-2.284.35c-.054.016-.107.035-.158.05a8.297 8.297 0 0 0-.855.35 7.14 7.14 0 0 0-.552.297 6.716 6.716 0 0 0-.533.347c-.123.089-.243.18-.363.275-.13.104-.252.211-.375.321-.067.06-.13.123-.196.184l-.334.328-1.338 1.321-.23.228-.076.075c-.038.038-.076.073-.11.11l-.057.054a1.914 1.914 0 0 1-.085.08c-.032.028-.063.06-.095.088a13.286 13.286 0 0 1-2.748 1.946c.06.028.12.057.18.082l.142.066c.044.022.091.041.139.063l.135.06.149.067.17.075.164.07c.073.031.142.06.215.088.056.025.116.047.173.07.088.034.177.072.268.107.085.031.168.066.253.098l.189.072c.11.041.218.082.328.12.057.019.11.041.167.06.08.028.155.053.234.082l.192.066.284.095.3.095c.123.037.243.075.366.11l.246.072c.164.048.331.095.495.14.06.015.12.03.18.043.114.029.227.05.34.07.13.022.26.04.389.057a5.815 5.815 0 0 0 .994.019 5.172 5.172 0 0 0 1.413-.3 5.405 5.405 0 0 0 .726-.334c.06-.035.122-.07.182-.108a7.96 7.96 0 0 0 .432-.297 5.362 5.362 0 0 0 .577-.517 5.285 5.285 0 0 0 .37-.429 5.797 5.797 0 0 0 .527-.827l.13-.258 1.166-2.325-.003.006a7.391 7.391 0 0 1 1.527-2.186Z" d="M23.732 9.295a7.55 7.55 0 0 0-3.35-.776 7.521 7.521 0 0 0-2.284.35c-.054.016-.107.035-.158.05a8.297 8.297 0 0 0-.855.35 7.14 7.14 0 0 0-.552.297 6.716 6.716 0 0 0-.533.347c-.123.089-.243.18-.363.275-.13.104-.252.211-.375.321-.067.06-.13.123-.196.184l-.334.328-1.338 1.321-.23.228-.076.075c-.038.038-.076.073-.11.11l-.057.054a1.914 1.914 0 0 1-.085.08c-.032.028-.063.06-.095.088a13.286 13.286 0 0 1-2.748 1.946c.06.028.12.057.18.082l.142.066c.044.022.091.041.139.063l.135.06.149.067.17.075.164.07c.073.031.142.06.215.088.056.025.116.047.173.07.088.034.177.072.268.107.085.031.168.066.253.098l.189.072c.11.041.218.082.328.12.057.019.11.041.167.06.08.028.155.053.234.082l.192.066.284.095.3.095c.123.037.243.075.366.11l.246.072c.164.048.331.095.495.14.06.015.12.03.18.043.114.029.227.05.34.07.13.022.26.04.389.057a5.815 5.815 0 0 0 .994.019 5.172 5.172 0 0 0 1.413-.3 5.405 5.405 0 0 0 .726-.334c.06-.035.122-.07.182-.108a7.96 7.96 0 0 0 .432-.297 5.362 5.362 0 0 0 .577-.517 5.285 5.285 0 0 0 .37-.429 5.797 5.797 0 0 0 .527-.827l.13-.258 1.166-2.325-.003.006a7.391 7.391 0 0 1 1.527-2.186Z"
fill="#133C9A" fill="#133C9A"
/> />
</svg> </svg>
); );
}; };
export const GotifyIcon = ({ className }: Props) => { export const GotifyIcon = ({ className }: Props) => {
return ( return (
<svg <svg
viewBox="0 0 500 500" viewBox="0 0 500 500"
className={cn("size-8", className)} className={cn("size-8", className)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<defs> <defs>
<style> <style>
{` {`
.gotify-st0{fill:#DDCBA2;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .gotify-st0{fill:#DDCBA2;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}
.gotify-st1{fill:#71CAEE;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .gotify-st1{fill:#71CAEE;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}
.gotify-st2{fill:#FFFFFF;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .gotify-st2{fill:#FFFFFF;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}
.gotify-st3{fill:#888E93;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .gotify-st3{fill:#888E93;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}
.gotify-st4{fill:#F0F0F0;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .gotify-st4{fill:#F0F0F0;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}
.gotify-st5{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .gotify-st5{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;}
.gotify-st8{fill:#FFFFFF;} .gotify-st8{fill:#FFFFFF;}
`} `}
</style> </style>
<linearGradient <linearGradient
id="gotify-gradient" id="gotify-gradient"
x1="265" x1="265"
y1="280" y1="280"
x2="275" x2="275"
y2="302" y2="302"
gradientUnits="userSpaceOnUse" gradientUnits="userSpaceOnUse"
> >
<stop offset="0" stopColor="#71CAEE" /> <stop offset="0" stopColor="#71CAEE" />
<stop offset="0.04" stopColor="#83CAE2" /> <stop offset="0.04" stopColor="#83CAE2" />
<stop offset="0.12" stopColor="#9FCACE" /> <stop offset="0.12" stopColor="#9FCACE" />
<stop offset="0.21" stopColor="#B6CBBE" /> <stop offset="0.21" stopColor="#B6CBBE" />
<stop offset="0.31" stopColor="#C7CBB1" /> <stop offset="0.31" stopColor="#C7CBB1" />
<stop offset="0.44" stopColor="#D4CBA8" /> <stop offset="0.44" stopColor="#D4CBA8" />
<stop offset="0.61" stopColor="#DBCBA3" /> <stop offset="0.61" stopColor="#DBCBA3" />
<stop offset="1" stopColor="#DDCBA2" /> <stop offset="1" stopColor="#DDCBA2" />
</linearGradient> </linearGradient>
</defs> </defs>
<g transform="matrix(2.33,0,0,2.33,-432,-323)"> <g transform="matrix(2.33,0,0,2.33,-432,-323)">
<g transform="translate(-25,26)"> <g transform="translate(-25,26)">
<path <path
className="gotify-st1" className="gotify-st1"
d="m258.9,119.7c-3,-0.9-6,-1.8-9,-2.7-4.6,-1.4-9.2,-2.8-14,-2.5-2.8,0.2-6.1,1.3-6.9,4-0.6,2-1.6,7.3-1.3,7.9 1.5,3.4 13.9,6.7 18.3,6.7" d="m258.9,119.7c-3,-0.9-6,-1.8-9,-2.7-4.6,-1.4-9.2,-2.8-14,-2.5-2.8,0.2-6.1,1.3-6.9,4-0.6,2-1.6,7.3-1.3,7.9 1.5,3.4 13.9,6.7 18.3,6.7"
/> />
<path d="m392.6,177.9c-1.4,1.4-2.2,3.5-2.5,5.5-0.2,1.4-0.1,3 0.5,4.3 0.6,1.3 1.8,2.3 3.1,3 1.3,0.6 2.8,0.9 4.3,0.9 1.1,0 2.3,-0.1 3.1,-0.9 0.6,-0.7 0.8,-1.6 0.9,-2.5 0.2,-2.3-0.1,-4.7-0.9,-6.9-0.4,-1.1-0.9,-2.3-1.8,-3.1-1.7,-1.8-4.5,-2.2-6.4,-0.5-0.1,0-0.2,0.1-0.3,0.2z" /> <path d="m392.6,177.9c-1.4,1.4-2.2,3.5-2.5,5.5-0.2,1.4-0.1,3 0.5,4.3 0.6,1.3 1.8,2.3 3.1,3 1.3,0.6 2.8,0.9 4.3,0.9 1.1,0 2.3,-0.1 3.1,-0.9 0.6,-0.7 0.8,-1.6 0.9,-2.5 0.2,-2.3-0.1,-4.7-0.9,-6.9-0.4,-1.1-0.9,-2.3-1.8,-3.1-1.7,-1.8-4.5,-2.2-6.4,-0.5-0.1,0-0.2,0.1-0.3,0.2z" />
<path <path
className="gotify-st2" className="gotify-st2"
d="m358.5,164.2c-1,-1 0,-2.7 1,-3.7 5.8,-5.2 15.1,-4.6 21.8,-0.6 10.9,6.6 15.6,19.9 17.2,32.5 0.6,5.2 0.9,10.6-0.5,15.7-1.4,5.1-4.6,9.9-9.3,12.1-1.1,0.5-2.3,0.9-3.4,0.5-1.1,-0.4-1.9,-1.8-1.2,-2.8-9.4,-13.6-19,-26.8-20.9,-43.2-0.5,-4.1-1.8,-7.4-4.7,-10.5z" d="m358.5,164.2c-1,-1 0,-2.7 1,-3.7 5.8,-5.2 15.1,-4.6 21.8,-0.6 10.9,6.6 15.6,19.9 17.2,32.5 0.6,5.2 0.9,10.6-0.5,15.7-1.4,5.1-4.6,9.9-9.3,12.1-1.1,0.5-2.3,0.9-3.4,0.5-1.1,-0.4-1.9,-1.8-1.2,-2.8-9.4,-13.6-19,-26.8-20.9,-43.2-0.5,-4.1-1.8,-7.4-4.7,-10.5z"
/> />
<path <path
className="gotify-st1" className="gotify-st1"
d="m220.1,133c34.6,-18 79.3,-19.6 112.2,-8.7 23.7,7.9 41.3,26.7 49.5,50 7.1,20.6 7.1,43.6 3,65.7-7.5,40.2-26.2,77.9-49,112.6-12.6,19-24.6,36-44.2,48.5-38.7,24.6-88.9,22.1-129.3,11.5-19.5,-5.1-38.4,-17.3-44.3,-37.3-3.8,-12.8-2.1,-27.6 4.6,-40 13.5,-24.8 46.2,-38.4 50.8,-67.9 1.4,-8.7-0.3,-17.3-1.6,-25.7-3.8,-23.4-5.4,-45.8 6.7,-68.7 9.5,-17.7 24.3,-31 41.7,-40z" d="m220.1,133c34.6,-18 79.3,-19.6 112.2,-8.7 23.7,7.9 41.3,26.7 49.5,50 7.1,20.6 7.1,43.6 3,65.7-7.5,40.2-26.2,77.9-49,112.6-12.6,19-24.6,36-44.2,48.5-38.7,24.6-88.9,22.1-129.3,11.5-19.5,-5.1-38.4,-17.3-44.3,-37.3-3.8,-12.8-2.1,-27.6 4.6,-40 13.5,-24.8 46.2,-38.4 50.8,-67.9 1.4,-8.7-0.3,-17.3-1.6,-25.7-3.8,-23.4-5.4,-45.8 6.7,-68.7 9.5,-17.7 24.3,-31 41.7,-40z"
/> />
<path <path
className="gotify-st2" className="gotify-st2"
d="m264.5,174.9c-0.5,0.5-0.9,1-1.3,1.6-9,11.6-12,27.9-9.3,42.1 1.7,9 5.9,17.9 13.2,23.4 19.3,14.6 51.5,13.5 68.4,-1.5 24.4,-21.7 13,-67.6-14,-78.8-17.6,-7.2-43.7,-1.6-57,13.2z" d="m264.5,174.9c-0.5,0.5-0.9,1-1.3,1.6-9,11.6-12,27.9-9.3,42.1 1.7,9 5.9,17.9 13.2,23.4 19.3,14.6 51.5,13.5 68.4,-1.5 24.4,-21.7 13,-67.6-14,-78.8-17.6,-7.2-43.7,-1.6-57,13.2z"
/> />
<path <path
className="gotify-st2" className="gotify-st2"
d="m382.1,237.1c1.4,-0.1 2.9,-0.1 4.3,0.1 0.3,0 0.7,0.1 1,0.4 0.2,0.3 0.4,0.7 0.5,1.1 1,3.9 0.5,8.2 0.1,12.4-0.1,0.9-0.2,1.8-0.6,2.6-1,2.1-3.1,2.7-4.7,2.7-0.1,0-0.2,0-0.3,-0.1-0.3,-0.2-0.3,-0.7-0.2,-1.2 0.3,-5.9-0.1,-11.9-0.1,-18z" d="m382.1,237.1c1.4,-0.1 2.9,-0.1 4.3,0.1 0.3,0 0.7,0.1 1,0.4 0.2,0.3 0.4,0.7 0.5,1.1 1,3.9 0.5,8.2 0.1,12.4-0.1,0.9-0.2,1.8-0.6,2.6-1,2.1-3.1,2.7-4.7,2.7-0.1,0-0.2,0-0.3,-0.1-0.3,-0.2-0.3,-0.7-0.2,-1.2 0.3,-5.9-0.1,-11.9-0.1,-18z"
/> />
<path <path
className="gotify-st2" className="gotify-st2"
d="m378.7,236.8c-1.4,0.4-2.5,2-2.8,4.4-0.5,4.4-0.7,8.9-0.5,13.4 0,0.9 0.1,1.9 0.5,2.4 0.2,0.3 0.5,0.4 0.8,0.4 1.6,0.3 4.1,-0.6 5.6,-1 0,0 0,-5.2-0.1,-8-0.1,-2.8-0.1,-6.1-0.2,-8.9 0,-0.6 0,-1.5 0,-2.2 0.1,-0.7-2.6,-0.7-3.3,-0.5z" d="m378.7,236.8c-1.4,0.4-2.5,2-2.8,4.4-0.5,4.4-0.7,8.9-0.5,13.4 0,0.9 0.1,1.9 0.5,2.4 0.2,0.3 0.5,0.4 0.8,0.4 1.6,0.3 4.1,-0.6 5.6,-1 0,0 0,-5.2-0.1,-8-0.1,-2.8-0.1,-6.1-0.2,-8.9 0,-0.6 0,-1.5 0,-2.2 0.1,-0.7-2.6,-0.7-3.3,-0.5z"
/> />
<path <path
className="gotify-st0" className="gotify-st0"
d="m358.3,231.8c-0.3,2.2 0.1,4.7 1.7,7.4 2.6,4.4 7,6.1 11.9,5.8 8.9,-0.6 25.3,-5.4 27.5,-15.7 0.6,-3-0.3,-6.1-2.2,-8.5-6.2,-7.8-17.8,-5.7-25.6,-2-5.9,2.7-12.4,7-13.3,13z" d="m358.3,231.8c-0.3,2.2 0.1,4.7 1.7,7.4 2.6,4.4 7,6.1 11.9,5.8 8.9,-0.6 25.3,-5.4 27.5,-15.7 0.6,-3-0.3,-6.1-2.2,-8.5-6.2,-7.8-17.8,-5.7-25.6,-2-5.9,2.7-12.4,7-13.3,13z"
/> />
<path <path
className="gotify-st3" className="gotify-st3"
d="m386.4,208.6c2.2,1.4 3.7,3.8 4,7 0.3,3.6-1.4,7.5-5,8.8-2.9,1.1-6.2,0.6-9.1,-0.4-2.9,-1-5.8,-2.8-6.8,-5.7-0.7,-2-0.3,-4.3 0.7,-6.1 1.1,-1.8 2.8,-3.2 4.7,-4.1 3.9,-1.8 8.4,-1.6 11.5,0.5z" d="m386.4,208.6c2.2,1.4 3.7,3.8 4,7 0.3,3.6-1.4,7.5-5,8.8-2.9,1.1-6.2,0.6-9.1,-0.4-2.9,-1-5.8,-2.8-6.8,-5.7-0.7,-2-0.3,-4.3 0.7,-6.1 1.1,-1.8 2.8,-3.2 4.7,-4.1 3.9,-1.8 8.4,-1.6 11.5,0.5z"
/> />
<path <path
className="gotify-st0" className="gotify-st0"
d="m414.7,262.6c2.4,0.6 4.8,2.1 5.6,4.4 0.8,2.3 0.1,4.9-1.6,6.7-1.7,1.8-4.2,2.5-6.6,2.5-0.8,0-1.7,-0.1-2.4,-0.5-2.5,-1.1-3.5,-4-4.2,-6.6-1.8,-6.8 3.6,-7.8 9.2,-6.5z" d="m414.7,262.6c2.4,0.6 4.8,2.1 5.6,4.4 0.8,2.3 0.1,4.9-1.6,6.7-1.7,1.8-4.2,2.5-6.6,2.5-0.8,0-1.7,-0.1-2.4,-0.5-2.5,-1.1-3.5,-4-4.2,-6.6-1.8,-6.8 3.6,-7.8 9.2,-6.5z"
/> />
<path <path
className="gotify-st4" className="gotify-st4"
d="m267.1,284.7c2.3,-4.5 141.3,-36.2 144.7,-31.6 3.4,4.5 15.8,88.2 9,90.4-6.8,2.3-119.8,37.3-126.6,35-6.8,-2.3-29.4,-89.3-27.1,-93.8z" d="m267.1,284.7c2.3,-4.5 141.3,-36.2 144.7,-31.6 3.4,4.5 15.8,88.2 9,90.4-6.8,2.3-119.8,37.3-126.6,35-6.8,-2.3-29.4,-89.3-27.1,-93.8z"
/> />
<path <path
className="gotify-st5" className="gotify-st5"
d="m294.2,378.5c0,0 54.3,-74.6 59.9,-76.9 5.7,-2.3 67.3,41.3 67.3,41.3" d="m294.2,378.5c0,0 54.3,-74.6 59.9,-76.9 5.7,-2.3 67.3,41.3 67.3,41.3"
/> />
<path <path
className="gotify-st4" className="gotify-st4"
d="m267,287.7c0,0 86,38.8 91.6,36.6 5.7,-2.3 53.1,-71.2 53.1,-71.2" d="m267,287.7c0,0 86,38.8 91.6,36.6 5.7,-2.3 53.1,-71.2 53.1,-71.2"
/> />
<path <path
fill="url(#gotify-gradient)" fill="url(#gotify-gradient)"
d="m261.9,283.5c-0.1,4.2 4.3,7.3 8.4,7.6 4.1,0.3 8.2,-1.3 12.2,-2.6 1.4,-0.4 2.9,-0.8 4.2,-0.2 1.8,0.9 2.7,4.1 1.8,5.9-0.9,1.8-3.4,3.5-5.3,4.4-6.5,3-12.9,3.6-19.9,2-5.3,-1.2-11.3,-4.3-13,-13.5" d="m261.9,283.5c-0.1,4.2 4.3,7.3 8.4,7.6 4.1,0.3 8.2,-1.3 12.2,-2.6 1.4,-0.4 2.9,-0.8 4.2,-0.2 1.8,0.9 2.7,4.1 1.8,5.9-0.9,1.8-3.4,3.5-5.3,4.4-6.5,3-12.9,3.6-19.9,2-5.3,-1.2-11.3,-4.3-13,-13.5"
/> />
<path d="m318.4,198.4c-2,-0.3-4.1,0.1-5.9,1.3-3.2,2.1-4.7,6.2-4.7,9.9 0,1.9 0.4,3.8 1.4,5.3 1.2,1.7 3.1,2.9 5.2,3.4 3.4,0.8 8.2,0.7 10.5,-2.5 1,-1.5 1.4,-3.3 1.5,-5.1 0.5,-5.7-1.8,-11.4-8,-12.3z" /> <path d="m318.4,198.4c-2,-0.3-4.1,0.1-5.9,1.3-3.2,2.1-4.7,6.2-4.7,9.9 0,1.9 0.4,3.8 1.4,5.3 1.2,1.7 3.1,2.9 5.2,3.4 3.4,0.8 8.2,0.7 10.5,-2.5 1,-1.5 1.4,-3.3 1.5,-5.1 0.5,-5.7-1.8,-11.4-8,-12.3z" />
<path <path
className="gotify-st8" className="gotify-st8"
d="m320.4,203.3c0.9,0.3 1.7,0.8 2.1,1.7 0.4,0.8 0.4,1.7 0.3,2.5-0.1,1-0.6,2-1.5,2.7-0.7,0.5-1.7,0.7-2.6,0.5-0.9,-0.2-1.7,-0.8-2.2,-1.6-1.1,-1.6-0.9,-4.4 0.9,-5.5 0.9,-0.4 2,-0.6 3,-0.3z" d="m320.4,203.3c0.9,0.3 1.7,0.8 2.1,1.7 0.4,0.8 0.4,1.7 0.3,2.5-0.1,1-0.6,2-1.5,2.7-0.7,0.5-1.7,0.7-2.6,0.5-0.9,-0.2-1.7,-0.8-2.2,-1.6-1.1,-1.6-0.9,-4.4 0.9,-5.5 0.9,-0.4 2,-0.6 3,-0.3z"
/> />
</g> </g>
</g> </g>
</svg> </svg>
); );
}; };
export const NtfyIcon = ({ className }: Props) => { export const NtfyIcon = ({ className }: Props) => {
return ( return (
<svg <svg
viewBox="0 0 24 24" viewBox="0 0 24 24"
className={cn("size-8", className)} className={cn("size-8", className)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
fill="currentColor" fill="currentColor"
d="M12.597 13.693v2.156h6.205v-2.156ZM5.183 6.549v2.363l3.591 1.901 0.023 0.01 -0.023 0.009 -3.591 1.901v2.35l0.386 -0.211 5.456 -2.969V9.729ZM3.659 2.037C1.915 2.037 0.42 3.41 0.42 5.154v0.002L0.438 18.73 0 21.963l5.956 -1.583h14.806c1.744 0 3.238 -1.374 3.238 -3.118V5.154c0 -1.744 -1.493 -3.116 -3.237 -3.117h-0.001zm0 2.2h17.104c0.613 0.001 1.037 0.447 1.037 0.917v12.108c0 0.47 -0.424 0.916 -1.038 0.916H5.633l-3.026 0.915 0.031 -0.179 -0.017 -13.76c0 -0.47 0.424 -0.917 1.038 -0.917z" d="M12.597 13.693v2.156h6.205v-2.156ZM5.183 6.549v2.363l3.591 1.901 0.023 0.01 -0.023 0.009 -3.591 1.901v2.35l0.386 -0.211 5.456 -2.969V9.729ZM3.659 2.037C1.915 2.037 0.42 3.41 0.42 5.154v0.002L0.438 18.73 0 21.963l5.956 -1.583h14.806c1.744 0 3.238 -1.374 3.238 -3.118V5.154c0 -1.744 -1.493 -3.116 -3.237 -3.117h-0.001zm0 2.2h17.104c0.613 0.001 1.037 0.447 1.037 0.917v12.108c0 0.47 -0.424 0.916 -1.038 0.916H5.633l-3.026 0.915 0.031 -0.179 -0.017 -13.76c0 -0.47 0.424 -0.917 1.038 -0.917z"
/> />
</svg> </svg>
); );
}; };
export const PushoverIcon = ({ className }: Props) => { export const PushoverIcon = ({ className }: Props) => {
return ( return (
<svg <svg
viewBox="0 0 600 600" viewBox="0 0 600 600"
className={cn("size-8", className)} className={cn("size-8", className)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<g stroke="none" strokeWidth="1"> <g stroke="none" strokeWidth="1">
<ellipse <ellipse
style={{ fillRule: "evenodd" }} style={{ fillRule: "evenodd" }}
fill="#249DF1" fill="#249DF1"
transform="matrix(-0.674571, 0.73821, -0.73821, -0.674571, 556.833239, 241.613465)" transform="matrix(-0.674571, 0.73821, -0.73821, -0.674571, 556.833239, 241.613465)"
cx="216.308" cx="216.308"
cy="152.076" cy="152.076"
rx="296.855" rx="296.855"
ry="296.855" ry="296.855"
/> />
<path <path
fill="#FFFFFF" fill="#FFFFFF"
d="M 280.949 172.514 L 355.429 162.714 L 282.909 326.374 L 282.909 326.374 C 295.649 325.394 308.142 321.067 320.389 313.394 L 320.389 313.394 L 320.389 313.394 C 332.642 305.714 343.916 296.077 354.209 284.484 L 354.209 284.484 L 354.209 284.484 C 364.496 272.884 373.396 259.981 380.909 245.774 L 380.909 245.774 L 380.909 245.774 C 388.422 231.561 393.812 217.594 397.079 203.874 L 397.079 203.874 L 397.079 203.874 C 399.039 195.381 399.939 187.214 399.779 179.374 L 399.779 179.374 L 399.779 179.374 C 399.612 171.534 397.569 164.674 393.649 158.794 L 393.649 158.794 L 393.649 158.794 C 389.729 152.914 383.766 148.177 375.759 144.584 L 375.759 144.584 L 375.759 144.584 C 367.759 140.991 356.899 139.194 343.179 139.194 L 343.179 139.194 L 343.179 139.194 C 327.172 139.194 311.409 141.807 295.889 147.034 L 295.889 147.034 L 295.889 147.034 C 280.376 152.261 266.002 159.857 252.769 169.824 L 252.769 169.824 L 252.769 169.824 C 239.542 179.784 228.029 192.197 218.229 207.064 L 218.229 207.064 L 218.229 207.064 C 208.429 221.924 201.406 238.827 197.159 257.774 L 197.159 257.774 L 197.159 257.774 C 195.526 263.981 194.546 268.961 194.219 272.714 L 194.219 272.714 L 194.219 272.714 C 193.892 276.474 193.812 279.577 193.979 282.024 L 193.979 282.024 L 193.979 282.024 C 194.139 284.477 194.462 286.357 194.949 287.664 L 194.949 287.664 L 194.949 287.664 C 195.442 288.971 195.852 290.277 196.179 291.584 L 196.179 291.584 L 196.179 291.584 C 179.519 291.584 167.349 288.234 159.669 281.534 L 159.669 281.534 L 159.669 281.534 C 151.996 274.841 150.119 263.164 154.039 246.504 L 154.039 246.504 L 154.039 246.504 C 157.959 229.191 166.862 212.694 180.749 197.014 L 180.749 197.014 L 180.749 197.014 C 194.629 181.334 211.122 167.531 230.229 155.604 L 230.229 155.604 L 230.229 155.604 C 249.342 143.684 270.249 134.214 292.949 127.194 L 292.949 127.194 L 292.949 127.194 C 315.656 120.167 337.789 116.654 359.349 116.654 L 359.349 116.654 L 359.349 116.654 C 378.296 116.654 394.219 119.347 407.119 124.734 L 407.119 124.734 L 407.119 124.734 C 420.026 130.127 430.072 137.234 437.259 146.054 L 437.259 146.054 L 437.259 146.054 C 444.446 154.874 448.936 165.164 450.729 176.924 L 450.729 176.924 L 450.729 176.924 C 452.529 188.684 451.959 200.934 449.019 213.674 L 449.019 213.674 L 449.019 213.674 C 445.426 229.027 438.646 244.464 428.679 259.984 L 428.679 259.984 L 428.679 259.984 C 418.719 275.497 406.226 289.544 391.199 302.124 L 391.199 302.124 L 391.199 302.124 C 376.172 314.697 358.939 324.904 339.499 332.744 L 339.499 332.744 L 339.499 332.744 C 320.066 340.584 299.406 344.504 277.519 344.504 L 277.519 344.504 L 275.069 344.504 L 212.839 484.154 L 142.279 484.154 L 280.949 172.514 Z" d="M 280.949 172.514 L 355.429 162.714 L 282.909 326.374 L 282.909 326.374 C 295.649 325.394 308.142 321.067 320.389 313.394 L 320.389 313.394 L 320.389 313.394 C 332.642 305.714 343.916 296.077 354.209 284.484 L 354.209 284.484 L 354.209 284.484 C 364.496 272.884 373.396 259.981 380.909 245.774 L 380.909 245.774 L 380.909 245.774 C 388.422 231.561 393.812 217.594 397.079 203.874 L 397.079 203.874 L 397.079 203.874 C 399.039 195.381 399.939 187.214 399.779 179.374 L 399.779 179.374 L 399.779 179.374 C 399.612 171.534 397.569 164.674 393.649 158.794 L 393.649 158.794 L 393.649 158.794 C 389.729 152.914 383.766 148.177 375.759 144.584 L 375.759 144.584 L 375.759 144.584 C 367.759 140.991 356.899 139.194 343.179 139.194 L 343.179 139.194 L 343.179 139.194 C 327.172 139.194 311.409 141.807 295.889 147.034 L 295.889 147.034 L 295.889 147.034 C 280.376 152.261 266.002 159.857 252.769 169.824 L 252.769 169.824 L 252.769 169.824 C 239.542 179.784 228.029 192.197 218.229 207.064 L 218.229 207.064 L 218.229 207.064 C 208.429 221.924 201.406 238.827 197.159 257.774 L 197.159 257.774 L 197.159 257.774 C 195.526 263.981 194.546 268.961 194.219 272.714 L 194.219 272.714 L 194.219 272.714 C 193.892 276.474 193.812 279.577 193.979 282.024 L 193.979 282.024 L 193.979 282.024 C 194.139 284.477 194.462 286.357 194.949 287.664 L 194.949 287.664 L 194.949 287.664 C 195.442 288.971 195.852 290.277 196.179 291.584 L 196.179 291.584 L 196.179 291.584 C 179.519 291.584 167.349 288.234 159.669 281.534 L 159.669 281.534 L 159.669 281.534 C 151.996 274.841 150.119 263.164 154.039 246.504 L 154.039 246.504 L 154.039 246.504 C 157.959 229.191 166.862 212.694 180.749 197.014 L 180.749 197.014 L 180.749 197.014 C 194.629 181.334 211.122 167.531 230.229 155.604 L 230.229 155.604 L 230.229 155.604 C 249.342 143.684 270.249 134.214 292.949 127.194 L 292.949 127.194 L 292.949 127.194 C 315.656 120.167 337.789 116.654 359.349 116.654 L 359.349 116.654 L 359.349 116.654 C 378.296 116.654 394.219 119.347 407.119 124.734 L 407.119 124.734 L 407.119 124.734 C 420.026 130.127 430.072 137.234 437.259 146.054 L 437.259 146.054 L 437.259 146.054 C 444.446 154.874 448.936 165.164 450.729 176.924 L 450.729 176.924 L 450.729 176.924 C 452.529 188.684 451.959 200.934 449.019 213.674 L 449.019 213.674 L 449.019 213.674 C 445.426 229.027 438.646 244.464 428.679 259.984 L 428.679 259.984 L 428.679 259.984 C 418.719 275.497 406.226 289.544 391.199 302.124 L 391.199 302.124 L 391.199 302.124 C 376.172 314.697 358.939 324.904 339.499 332.744 L 339.499 332.744 L 339.499 332.744 C 320.066 340.584 299.406 344.504 277.519 344.504 L 277.519 344.504 L 275.069 344.504 L 212.839 484.154 L 142.279 484.154 L 280.949 172.514 Z"
/> />
</g> </g>
</svg> </svg>
); );
}; };
export const ResendIcon = ({ className }: Props) => { export const ResendIcon = ({ className }: Props) => {
return ( return (
<svg <svg
viewBox="0 0 24 24" viewBox="0 0 24 24"
className={cn("size-8", className)} className={cn("size-8", className)}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<circle cx="12" cy="12" r="10" fill="currentColor" opacity="0.12" /> <circle cx="12" cy="12" r="10" fill="currentColor" opacity="0.12" />
<path <path
d="M8 17V7h6a3 3 0 0 1 0 6H8m6 0 2 4" d="M8 17V7h6a3 3 0 0 1 0 6H8m6 0 2 4"
stroke="currentColor" stroke="currentColor"
strokeWidth="1.6" strokeWidth="1.6"
strokeLinecap="round" strokeLinecap="round"
strokeLinejoin="round" strokeLinejoin="round"
fill="none" fill="none"
/> />
</svg> </svg>
); );
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
import type { import type {
custom, custom,
discord, discord,
email, email,
gotify, gotify,
lark, lark,
ntfy, ntfy,
pushover, pushover,
@@ -10,275 +10,275 @@ import type {
slack, slack,
telegram, telegram,
} from "@dokploy/server/db/schema"; } from "@dokploy/server/db/schema";
import nodemailer from "nodemailer"; import nodemailer from "nodemailer";
import { Resend } from "resend"; import { Resend } from "resend";
export const sendEmailNotification = async ( export const sendEmailNotification = async (
connection: typeof email.$inferInsert, connection: typeof email.$inferInsert,
subject: string, subject: string,
htmlContent: string, htmlContent: string,
) => { ) => {
try { try {
const { const {
smtpServer, smtpServer,
smtpPort, smtpPort,
username, username,
password, password,
fromAddress, fromAddress,
toAddresses, toAddresses,
} = connection; } = connection;
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
host: smtpServer, host: smtpServer,
port: smtpPort, port: smtpPort,
auth: { user: username, pass: password }, auth: { user: username, pass: password },
}); });
await transporter.sendMail({ await transporter.sendMail({
from: fromAddress, from: fromAddress,
to: toAddresses.join(", "), to: toAddresses.join(", "),
subject, subject,
html: htmlContent, html: htmlContent,
textEncoding: "base64", textEncoding: "base64",
}); });
} catch (err) { } catch (err) {
console.log(err); console.log(err);
throw new Error( throw new Error(
`Failed to send email notification ${err instanceof Error ? err.message : "Unknown error"}`, `Failed to send email notification ${err instanceof Error ? err.message : "Unknown error"}`,
); );
} }
}; };
export const sendResendNotification = async ( export const sendResendNotification = async (
connection: typeof resend.$inferInsert, connection: typeof resend.$inferInsert,
subject: string, subject: string,
htmlContent: string, htmlContent: string,
) => { ) => {
try { try {
const client = new Resend(connection.apiKey); const client = new Resend(connection.apiKey);
const result = await client.emails.send({ const result = await client.emails.send({
from: connection.fromAddress, from: connection.fromAddress,
to: connection.toAddresses, to: connection.toAddresses,
subject, subject,
html: htmlContent, html: htmlContent,
}); });
if (result.error) { if (result.error) {
throw new Error(result.error.message); throw new Error(result.error.message);
} }
} catch (err) { } catch (err) {
console.log(err); console.log(err);
throw new Error( throw new Error(
`Failed to send Resend notification ${err instanceof Error ? err.message : "Unknown error"}`, `Failed to send Resend notification ${err instanceof Error ? err.message : "Unknown error"}`,
); );
} }
}; };
export const sendDiscordNotification = async ( export const sendDiscordNotification = async (
connection: typeof discord.$inferInsert, connection: typeof discord.$inferInsert,
embed: any, embed: any,
) => { ) => {
try { try {
const response = await fetch(connection.webhookUrl, { const response = await fetch(connection.webhookUrl, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ embeds: [embed] }), body: JSON.stringify({ embeds: [embed] }),
}); });
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
`Failed to send discord notification ${response.statusText}`, `Failed to send discord notification ${response.statusText}`,
); );
} }
} catch (err) { } catch (err) {
console.log("error", err); console.log("error", err);
throw new Error( throw new Error(
`Failed to send discord notification ${err instanceof Error ? err.message : "Unknown error"}`, `Failed to send discord notification ${err instanceof Error ? err.message : "Unknown error"}`,
); );
} }
}; };
export const sendTelegramNotification = async ( export const sendTelegramNotification = async (
connection: typeof telegram.$inferInsert, connection: typeof telegram.$inferInsert,
messageText: string, messageText: string,
inlineButton?: { inlineButton?: {
text: string; text: string;
url: string; url: string;
}[][], }[][],
) => { ) => {
try { try {
const url = `https://api.telegram.org/bot${connection.botToken}/sendMessage`; const url = `https://api.telegram.org/bot${connection.botToken}/sendMessage`;
await fetch(url, { await fetch(url, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
chat_id: connection.chatId, chat_id: connection.chatId,
message_thread_id: connection.messageThreadId, message_thread_id: connection.messageThreadId,
text: messageText, text: messageText,
parse_mode: "HTML", parse_mode: "HTML",
disable_web_page_preview: true, disable_web_page_preview: true,
reply_markup: { reply_markup: {
inline_keyboard: inlineButton, inline_keyboard: inlineButton,
}, },
}), }),
}); });
} catch (err) { } catch (err) {
console.log(err); console.log(err);
} }
}; };
export const sendSlackNotification = async ( export const sendSlackNotification = async (
connection: typeof slack.$inferInsert, connection: typeof slack.$inferInsert,
message: any, message: any,
) => { ) => {
try { try {
const response = await fetch(connection.webhookUrl, { const response = await fetch(connection.webhookUrl, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(message), body: JSON.stringify(message),
}); });
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
`Failed to send slack notification ${response.statusText}`, `Failed to send slack notification ${response.statusText}`,
); );
} }
} catch (err) { } catch (err) {
console.log("error", err); console.log("error", err);
throw new Error( throw new Error(
`Failed to send slack notification ${err instanceof Error ? err.message : "Unknown error"}`, `Failed to send slack notification ${err instanceof Error ? err.message : "Unknown error"}`,
); );
} }
}; };
export const sendGotifyNotification = async ( export const sendGotifyNotification = async (
connection: typeof gotify.$inferInsert, connection: typeof gotify.$inferInsert,
title: string, title: string,
message: string, message: string,
) => { ) => {
const response = await fetch(`${connection.serverUrl}/message`, { const response = await fetch(`${connection.serverUrl}/message`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"X-Gotify-Key": connection.appToken, "X-Gotify-Key": connection.appToken,
}, },
body: JSON.stringify({ body: JSON.stringify({
title: title, title: title,
message: message, message: message,
priority: connection.priority, priority: connection.priority,
extras: { extras: {
"client::display": { "client::display": {
contentType: "text/plain", contentType: "text/plain",
}, },
}, },
}), }),
}); });
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
`Failed to send Gotify notification: ${response.statusText}`, `Failed to send Gotify notification: ${response.statusText}`,
); );
} }
}; };
export const sendNtfyNotification = async ( export const sendNtfyNotification = async (
connection: typeof ntfy.$inferInsert, connection: typeof ntfy.$inferInsert,
title: string, title: string,
tags: string, tags: string,
actions: string, actions: string,
message: string, message: string,
) => { ) => {
const response = await fetch(`${connection.serverUrl}/${connection.topic}`, { const response = await fetch(`${connection.serverUrl}/${connection.topic}`, {
method: "POST", method: "POST",
headers: { headers: {
...(connection.accessToken && { ...(connection.accessToken && {
Authorization: `Bearer ${connection.accessToken}`, Authorization: `Bearer ${connection.accessToken}`,
}), }),
"X-Priority": connection.priority?.toString() || "3", "X-Priority": connection.priority?.toString() || "3",
"X-Title": title, "X-Title": title,
"X-Tags": tags, "X-Tags": tags,
"X-Actions": actions, "X-Actions": actions,
}, },
body: message, body: message,
}); });
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to send ntfy notification: ${response.statusText}`); throw new Error(`Failed to send ntfy notification: ${response.statusText}`);
} }
}; };
export const sendCustomNotification = async ( export const sendCustomNotification = async (
connection: typeof custom.$inferInsert, connection: typeof custom.$inferInsert,
payload: Record<string, any>, payload: Record<string, any>,
) => { ) => {
try { try {
// Merge default headers with custom headers (now already an object from jsonb) // Merge default headers with custom headers (now already an object from jsonb)
const headers: Record<string, string> = { const headers: Record<string, string> = {
"Content-Type": "application/json", "Content-Type": "application/json",
...(connection.headers || {}), ...(connection.headers || {}),
}; };
// Default body with payload // Default body with payload
const body = JSON.stringify(payload); const body = JSON.stringify(payload);
const response = await fetch(connection.endpoint, { const response = await fetch(connection.endpoint, {
method: "POST", method: "POST",
headers, headers,
body, body,
}); });
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
`Failed to send custom notification: ${response.statusText}`, `Failed to send custom notification: ${response.statusText}`,
); );
} }
return response; return response;
} catch (error) { } catch (error) {
console.error("Error sending custom notification:", error); console.error("Error sending custom notification:", error);
throw error; throw error;
} }
}; };
export const sendLarkNotification = async ( export const sendLarkNotification = async (
connection: typeof lark.$inferInsert, connection: typeof lark.$inferInsert,
message: any, message: any,
) => { ) => {
try { try {
await fetch(connection.webhookUrl, { await fetch(connection.webhookUrl, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(message), body: JSON.stringify(message),
}); });
} catch (err) { } catch (err) {
console.log(err); console.log(err);
} }
}; };
export const sendPushoverNotification = async ( export const sendPushoverNotification = async (
connection: typeof pushover.$inferInsert, connection: typeof pushover.$inferInsert,
title: string, title: string,
message: string, message: string,
) => { ) => {
const formData = new URLSearchParams(); const formData = new URLSearchParams();
formData.append("token", connection.apiToken); formData.append("token", connection.apiToken);
formData.append("user", connection.userKey); formData.append("user", connection.userKey);
formData.append("title", title); formData.append("title", title);
formData.append("message", message); formData.append("message", message);
formData.append("priority", connection.priority?.toString() || "0"); formData.append("priority", connection.priority?.toString() || "0");
// For emergency priority (2), retry and expire are required // For emergency priority (2), retry and expire are required
if (connection.priority === 2) { if (connection.priority === 2) {
formData.append("retry", connection.retry?.toString() || "30"); formData.append("retry", connection.retry?.toString() || "30");
formData.append("expire", connection.expire?.toString() || "3600"); formData.append("expire", connection.expire?.toString() || "3600");
} }
const response = await fetch("https://api.pushover.net/1/messages.json", { const response = await fetch("https://api.pushover.net/1/messages.json", {
method: "POST", method: "POST",
body: formData, body: formData,
}); });
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
`Failed to send Pushover notification: ${response.statusText}`, `Failed to send Pushover notification: ${response.statusText}`,
); );
} }
}; };

View File

@@ -1,11 +1,11 @@
import { db } from "@dokploy/server/db"; import { db } from "@dokploy/server/db";
import { notifications } from "@dokploy/server/db/schema"; import { notifications } from "@dokploy/server/db/schema";
import { VolumeBackupEmail } from "@dokploy/server/emails/emails/volume-backup"; import { VolumeBackupEmail } from "@dokploy/server/emails/emails/volume-backup";
import { renderAsync } from "@react-email/components"; import { renderAsync } from "@react-email/components";
import { format } from "date-fns"; import { format } from "date-fns";
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import { import {
sendDiscordNotification, sendDiscordNotification,
sendEmailNotification, sendEmailNotification,
sendGotifyNotification, sendGotifyNotification,
sendNtfyNotification, sendNtfyNotification,
@@ -14,287 +14,279 @@ import {
sendSlackNotification, sendSlackNotification,
sendTelegramNotification, sendTelegramNotification,
} from "./utils"; } from "./utils";
export const sendVolumeBackupNotifications = async ({ export const sendVolumeBackupNotifications = async ({
projectName, projectName,
applicationName, applicationName,
volumeName, volumeName,
serviceType, serviceType,
type, type,
errorMessage, errorMessage,
organizationId, organizationId,
backupSize, backupSize,
}: { }: {
projectName: string; projectName: string;
applicationName: string; applicationName: string;
volumeName: string; volumeName: string;
serviceType: serviceType:
| "application" | "application"
| "postgres" | "postgres"
| "mysql" | "mysql"
| "mongodb" | "mongodb"
| "mariadb" | "mariadb"
| "redis" | "redis"
| "compose"; | "compose";
type: "error" | "success"; type: "error" | "success";
organizationId: string; organizationId: string;
errorMessage?: string; errorMessage?: string;
backupSize?: string; backupSize?: string;
}) => { }) => {
const date = new Date(); const date = new Date();
const unixDate = ~~(Number(date) / 1000); const unixDate = ~~(Number(date) / 1000);
const notificationList = await db.query.notifications.findMany({ const notificationList = await db.query.notifications.findMany({
where: and( where: and(
eq(notifications.volumeBackup, true), eq(notifications.volumeBackup, true),
eq(notifications.organizationId, organizationId), eq(notifications.organizationId, organizationId),
), ),
with: { with: {
email: true, email: true,
discord: true, discord: true,
telegram: true, telegram: true,
slack: true, slack: true,
resend: true, resend: true,
gotify: true, gotify: true,
ntfy: true, ntfy: true,
pushover: true, pushover: true,
}, },
}); });
for (const notification of notificationList) { for (const notification of notificationList) {
const { const { email, resend, discord, telegram, slack, gotify, ntfy, pushover } =
email, notification;
resend,
discord, if (email || resend) {
telegram, const subject = `Volume Backup ${type === "success" ? "Successful" : "Failed"} - ${applicationName}`;
slack, const htmlContent = await renderAsync(
gotify, VolumeBackupEmail({
ntfy, projectName,
pushover, applicationName,
} = notification; volumeName,
serviceType,
if (email || resend) { type,
const subject = `Volume Backup ${type === "success" ? "Successful" : "Failed"} - ${applicationName}`; errorMessage,
const htmlContent = await renderAsync( backupSize,
VolumeBackupEmail({ date: date.toISOString(),
projectName, }),
applicationName, );
volumeName, if (email) {
serviceType, await sendEmailNotification(email, subject, htmlContent);
type, }
errorMessage, if (resend) {
backupSize, await sendResendNotification(resend, subject, htmlContent);
date: date.toISOString(), }
}), }
);
if (email) { if (discord) {
await sendEmailNotification(email, subject, htmlContent); const decorate = (decoration: string, text: string) =>
} `${discord.decoration ? decoration : ""} ${text}`.trim();
if (resend) {
await sendResendNotification(resend, subject, htmlContent); await sendDiscordNotification(discord, {
} title:
} type === "success"
? decorate(">", "`✅` Volume Backup Successful")
if (discord) { : decorate(">", "`❌` Volume Backup Failed"),
const decorate = (decoration: string, text: string) => color: type === "success" ? 0x57f287 : 0xed4245,
`${discord.decoration ? decoration : ""} ${text}`.trim(); fields: [
{
await sendDiscordNotification(discord, { name: decorate("`🛠️`", "Project"),
title: value: projectName,
type === "success" inline: true,
? decorate(">", "`✅` Volume Backup Successful") },
: decorate(">", "`❌` Volume Backup Failed"), {
color: type === "success" ? 0x57f287 : 0xed4245, name: decorate("`⚙️`", "Application"),
fields: [ value: applicationName,
{ inline: true,
name: decorate("`🛠️`", "Project"), },
value: projectName, {
inline: true, name: decorate("`💾`", "Volume Name"),
}, value: volumeName,
{ inline: true,
name: decorate("`⚙️`", "Application"), },
value: applicationName, {
inline: true, name: decorate("`🔧`", "Service Type"),
}, value: serviceType,
{ inline: true,
name: decorate("`💾`", "Volume Name"), },
value: volumeName, ...(backupSize
inline: true, ? [
}, {
{ name: decorate("`📊`", "Backup Size"),
name: decorate("`🔧`", "Service Type"), value: backupSize,
value: serviceType, inline: true,
inline: true, },
}, ]
...(backupSize : []),
? [ {
{ name: decorate("`📅`", "Date"),
name: decorate("`📊`", "Backup Size"), value: `<t:${unixDate}:D>`,
value: backupSize, inline: true,
inline: true, },
}, {
] name: decorate("`⌚`", "Time"),
: []), value: `<t:${unixDate}:t>`,
{ inline: true,
name: decorate("`📅`", "Date"), },
value: `<t:${unixDate}:D>`, {
inline: true, name: decorate("`❓`", "Type"),
}, value: type
{ .replace("error", "Failed")
name: decorate("`⌚`", "Time"), .replace("success", "Successful"),
value: `<t:${unixDate}:t>`, inline: true,
inline: true, },
}, ...(type === "error" && errorMessage
{ ? [
name: decorate("`❓`", "Type"), {
value: type name: decorate("`⚠️`", "Error Message"),
.replace("error", "Failed") value: `\`\`\`${errorMessage}\`\`\``,
.replace("success", "Successful"), },
inline: true, ]
}, : []),
...(type === "error" && errorMessage ],
? [ timestamp: date.toISOString(),
{ footer: {
name: decorate("`⚠️`", "Error Message"), text: "Dokploy Volume Backup Notification",
value: `\`\`\`${errorMessage}\`\`\``, },
}, });
] }
: []),
], if (gotify) {
timestamp: date.toISOString(), const decorate = (decoration: string, text: string) =>
footer: { `${gotify.decoration ? decoration : ""} ${text}\n`;
text: "Dokploy Volume Backup Notification",
}, await sendGotifyNotification(
}); gotify,
} decorate(
type === "success" ? "✅" : "❌",
if (gotify) { `Volume Backup ${type === "success" ? "Successful" : "Failed"}`,
const decorate = (decoration: string, text: string) => ),
`${gotify.decoration ? decoration : ""} ${text}\n`; `${decorate("🛠️", `Project: ${projectName}`)}` +
`${decorate("⚙️", `Application: ${applicationName}`)}` +
await sendGotifyNotification( `${decorate("💾", `Volume Name: ${volumeName}`)}` +
gotify, `${decorate("🔧", `Service Type: ${serviceType}`)}` +
decorate( `${backupSize ? decorate("📊", `Backup Size: ${backupSize}`) : ""}` +
type === "success" ? "✅" : "❌", `${decorate("🕒", `Date: ${date.toLocaleString()}`)}` +
`Volume Backup ${type === "success" ? "Successful" : "Failed"}`, `${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`,
), );
`${decorate("🛠️", `Project: ${projectName}`)}` + }
`${decorate("⚙️", `Application: ${applicationName}`)}` +
`${decorate("💾", `Volume Name: ${volumeName}`)}` + if (ntfy) {
`${decorate("🔧", `Service Type: ${serviceType}`)}` + await sendNtfyNotification(
`${backupSize ? decorate("📊", `Backup Size: ${backupSize}`) : ""}` + ntfy,
`${decorate("🕒", `Date: ${date.toLocaleString()}`)}` + `Volume Backup ${type === "success" ? "Successful" : "Failed"}`,
`${type === "error" && errorMessage ? decorate("❌", `Error:\n${errorMessage}`) : ""}`, `${type === "success" ? "white_check_mark" : "x"}`,
); "",
} `🛠Project: ${projectName}\n` +
`Application: ${applicationName}\n` +
if (ntfy) { `💾Volume Name: ${volumeName}\n` +
await sendNtfyNotification( `🔧Service Type: ${serviceType}\n` +
ntfy, `${backupSize ? `📊Backup Size: ${backupSize}\n` : ""}` +
`Volume Backup ${type === "success" ? "Successful" : "Failed"}`, `🕒Date: ${date.toLocaleString()}\n` +
`${type === "success" ? "white_check_mark" : "x"}`, `${type === "error" && errorMessage ? `❌Error:\n${errorMessage}` : ""}`,
"", );
`🛠Project: ${projectName}\n` + }
`Application: ${applicationName}\n` +
`💾Volume Name: ${volumeName}\n` + if (telegram) {
`🔧Service Type: ${serviceType}\n` + const isError = type === "error" && errorMessage;
`${backupSize ? `📊Backup Size: ${backupSize}\n` : ""}` +
`🕒Date: ${date.toLocaleString()}\n` + const statusEmoji = type === "success" ? "✅" : "❌";
`${type === "error" && errorMessage ? `❌Error:\n${errorMessage}` : ""}`, const typeStatus = type === "success" ? "Successful" : "Failed";
); const errorMsg = isError
} ? `\n\n<b>Error:</b>\n<pre>${errorMessage}</pre>`
: "";
if (telegram) { const sizeInfo = backupSize ? `\n<b>Backup Size:</b> ${backupSize}` : "";
const isError = type === "error" && errorMessage;
const messageText = `<b>${statusEmoji} Volume Backup ${typeStatus}</b>\n\n<b>Project:</b> ${projectName}\n<b>Application:</b> ${applicationName}\n<b>Volume Name:</b> ${volumeName}\n<b>Service Type:</b> ${serviceType}${sizeInfo}\n<b>Date:</b> ${format(date, "PP")}\n<b>Time:</b> ${format(date, "pp")}${isError ? errorMsg : ""}`;
const statusEmoji = type === "success" ? "✅" : "❌";
const typeStatus = type === "success" ? "Successful" : "Failed"; await sendTelegramNotification(telegram, messageText);
const errorMsg = isError }
? `\n\n<b>Error:</b>\n<pre>${errorMessage}</pre>`
: ""; if (slack) {
const sizeInfo = backupSize ? `\n<b>Backup Size:</b> ${backupSize}` : ""; const { channel } = slack;
await sendSlackNotification(slack, {
const messageText = `<b>${statusEmoji} Volume Backup ${typeStatus}</b>\n\n<b>Project:</b> ${projectName}\n<b>Application:</b> ${applicationName}\n<b>Volume Name:</b> ${volumeName}\n<b>Service Type:</b> ${serviceType}${sizeInfo}\n<b>Date:</b> ${format(date, "PP")}\n<b>Time:</b> ${format(date, "pp")}${isError ? errorMsg : ""}`; channel: channel,
attachments: [
await sendTelegramNotification(telegram, messageText); {
} color: type === "success" ? "#00FF00" : "#FF0000",
pretext:
if (slack) { type === "success"
const { channel } = slack; ? ":white_check_mark: *Volume Backup Successful*"
await sendSlackNotification(slack, { : ":x: *Volume Backup Failed*",
channel: channel, fields: [
attachments: [ ...(type === "error" && errorMessage
{ ? [
color: type === "success" ? "#00FF00" : "#FF0000", {
pretext: title: "Error Message",
type === "success" value: errorMessage,
? ":white_check_mark: *Volume Backup Successful*" short: false,
: ":x: *Volume Backup Failed*", },
fields: [ ]
...(type === "error" && errorMessage : []),
? [ {
{ title: "Project",
title: "Error Message", value: projectName,
value: errorMessage, short: true,
short: false, },
}, {
] title: "Application",
: []), value: applicationName,
{ short: true,
title: "Project", },
value: projectName, {
short: true, title: "Volume Name",
}, value: volumeName,
{ short: true,
title: "Application", },
value: applicationName, {
short: true, title: "Service Type",
}, value: serviceType,
{ short: true,
title: "Volume Name", },
value: volumeName, ...(backupSize
short: true, ? [
}, {
{ title: "Backup Size",
title: "Service Type", value: backupSize,
value: serviceType, short: true,
short: true, },
}, ]
...(backupSize : []),
? [ {
{ title: "Time",
title: "Backup Size", value: date.toLocaleString(),
value: backupSize, short: true,
short: true, },
}, {
] title: "Type",
: []), value: type,
{ short: true,
title: "Time", },
value: date.toLocaleString(), {
short: true, title: "Status",
}, value: type === "success" ? "Successful" : "Failed",
{ short: true,
title: "Type", },
value: type, ],
short: true, },
}, ],
{ });
title: "Status", }
value: type === "success" ? "Successful" : "Failed",
short: true, if (pushover) {
}, await sendPushoverNotification(
], pushover,
}, `Volume Backup ${type === "success" ? "Successful" : "Failed"}`,
], `Project: ${projectName}\nApplication: ${applicationName}\nVolume: ${volumeName}\nService Type: ${serviceType}${backupSize ? `\nBackup Size: ${backupSize}` : ""}\nDate: ${date.toLocaleString()}${type === "error" && errorMessage ? `\nError: ${errorMessage}` : ""}`,
}); );
} }
}
if (pushover) { };
await sendPushoverNotification(
pushover,
`Volume Backup ${type === "success" ? "Successful" : "Failed"}`,
`Project: ${projectName}\nApplication: ${applicationName}\nVolume: ${volumeName}\nService Type: ${serviceType}${backupSize ? `\nBackup Size: ${backupSize}` : ""}\nDate: ${date.toLocaleString()}${type === "error" && errorMessage ? `\nError: ${errorMessage}` : ""}`,
);
}
}
};