Initial Labels Page & API

This commit is contained in:
allanice001
2025-09-03 17:09:39 +01:00
parent 26aef56d1d
commit b99a0684fd
20 changed files with 834 additions and 109 deletions

BIN
autoglue

Binary file not shown.

View File

@@ -953,6 +953,233 @@ const docTemplate = `{
} }
} }
}, },
"/api/v1/labels/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns one label. Add ` + "`" + `include=node_pools` + "`" + ` to include node groups.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"labels"
],
"summary": "Get label by ID (org scoped)",
"parameters": [
{
"type": "string",
"description": "Organization UUID",
"name": "X-Org-ID",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Label ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Optional: node_pools",
"name": "include",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/labels.labelResponse"
}
},
"400": {
"description": "invalid id",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "string"
}
},
"403": {
"description": "organization required",
"schema": {
"type": "string"
}
},
"404": {
"description": "not found",
"schema": {
"type": "string"
}
},
"500": {
"description": "fetch failed",
"schema": {
"type": "string"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Permanently deletes the label.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"labels"
],
"summary": "Delete label (org scoped)",
"parameters": [
{
"type": "string",
"description": "Organization UUID",
"name": "X-Org-ID",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Label ID (UUID)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content",
"schema": {
"type": "string"
}
},
"400": {
"description": "invalid id",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "string"
}
},
"403": {
"description": "organization required",
"schema": {
"type": "string"
}
},
"500": {
"description": "delete failed",
"schema": {
"type": "string"
}
}
}
},
"patch": {
"security": [
{
"BearerAuth": []
}
],
"description": "Partially update label fields.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"labels"
],
"summary": "Update label (org scoped)",
"parameters": [
{
"type": "string",
"description": "Organization UUID",
"name": "X-Org-ID",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Label ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/labels.updateLabelRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/labels.labelResponse"
}
},
"400": {
"description": "invalid id / invalid json",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "string"
}
},
"403": {
"description": "organization required",
"schema": {
"type": "string"
}
},
"404": {
"description": "not found",
"schema": {
"type": "string"
}
},
"500": {
"description": "update failed",
"schema": {
"type": "string"
}
}
}
}
},
"/api/v1/node-pools": { "/api/v1/node-pools": {
"get": { "get": {
"security": [ "security": [
@@ -3647,6 +3874,17 @@ const docTemplate = `{
} }
} }
}, },
"labels.updateLabelRequest": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"models.Member": { "models.Member": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@@ -949,6 +949,233 @@
} }
} }
}, },
"/api/v1/labels/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Returns one label. Add `include=node_pools` to include node groups.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"labels"
],
"summary": "Get label by ID (org scoped)",
"parameters": [
{
"type": "string",
"description": "Organization UUID",
"name": "X-Org-ID",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Label ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Optional: node_pools",
"name": "include",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/labels.labelResponse"
}
},
"400": {
"description": "invalid id",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "string"
}
},
"403": {
"description": "organization required",
"schema": {
"type": "string"
}
},
"404": {
"description": "not found",
"schema": {
"type": "string"
}
},
"500": {
"description": "fetch failed",
"schema": {
"type": "string"
}
}
}
},
"delete": {
"security": [
{
"BearerAuth": []
}
],
"description": "Permanently deletes the label.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"labels"
],
"summary": "Delete label (org scoped)",
"parameters": [
{
"type": "string",
"description": "Organization UUID",
"name": "X-Org-ID",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Label ID (UUID)",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content",
"schema": {
"type": "string"
}
},
"400": {
"description": "invalid id",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "string"
}
},
"403": {
"description": "organization required",
"schema": {
"type": "string"
}
},
"500": {
"description": "delete failed",
"schema": {
"type": "string"
}
}
}
},
"patch": {
"security": [
{
"BearerAuth": []
}
],
"description": "Partially update label fields.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"labels"
],
"summary": "Update label (org scoped)",
"parameters": [
{
"type": "string",
"description": "Organization UUID",
"name": "X-Org-ID",
"in": "header",
"required": true
},
{
"type": "string",
"description": "Label ID (UUID)",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Fields to update",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/labels.updateLabelRequest"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/labels.labelResponse"
}
},
"400": {
"description": "invalid id / invalid json",
"schema": {
"type": "string"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"type": "string"
}
},
"403": {
"description": "organization required",
"schema": {
"type": "string"
}
},
"404": {
"description": "not found",
"schema": {
"type": "string"
}
},
"500": {
"description": "update failed",
"schema": {
"type": "string"
}
}
}
}
},
"/api/v1/node-pools": { "/api/v1/node-pools": {
"get": { "get": {
"security": [ "security": [
@@ -3643,6 +3870,17 @@
} }
} }
}, },
"labels.updateLabelRequest": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"models.Member": { "models.Member": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@@ -183,6 +183,13 @@ definitions:
name: name:
type: string type: string
type: object type: object
labels.updateLabelRequest:
properties:
key:
type: string
value:
type: string
type: object
models.Member: models.Member:
properties: properties:
created_at: created_at:
@@ -1106,6 +1113,154 @@ paths:
summary: Create label (org scoped) summary: Create label (org scoped)
tags: tags:
- labels - labels
/api/v1/labels/{id}:
delete:
consumes:
- application/json
description: Permanently deletes the label.
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
required: true
type: string
- description: Label ID (UUID)
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"204":
description: No Content
schema:
type: string
"400":
description: invalid id
schema:
type: string
"401":
description: Unauthorized
schema:
type: string
"403":
description: organization required
schema:
type: string
"500":
description: delete failed
schema:
type: string
security:
- BearerAuth: []
summary: Delete label (org scoped)
tags:
- labels
get:
consumes:
- application/json
description: Returns one label. Add `include=node_pools` to include node groups.
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
required: true
type: string
- description: Label ID (UUID)
in: path
name: id
required: true
type: string
- description: 'Optional: node_pools'
in: query
name: include
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/labels.labelResponse'
"400":
description: invalid id
schema:
type: string
"401":
description: Unauthorized
schema:
type: string
"403":
description: organization required
schema:
type: string
"404":
description: not found
schema:
type: string
"500":
description: fetch failed
schema:
type: string
security:
- BearerAuth: []
summary: Get label by ID (org scoped)
tags:
- labels
patch:
consumes:
- application/json
description: Partially update label fields.
parameters:
- description: Organization UUID
in: header
name: X-Org-ID
required: true
type: string
- description: Label ID (UUID)
in: path
name: id
required: true
type: string
- description: Fields to update
in: body
name: body
required: true
schema:
$ref: '#/definitions/labels.updateLabelRequest'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/labels.labelResponse'
"400":
description: invalid id / invalid json
schema:
type: string
"401":
description: Unauthorized
schema:
type: string
"403":
description: organization required
schema:
type: string
"404":
description: not found
schema:
type: string
"500":
description: update failed
schema:
type: string
security:
- BearerAuth: []
summary: Update label (org scoped)
tags:
- labels
/api/v1/node-pools: /api/v1/node-pools:
get: get:
consumes: consumes:

4
go.sum
View File

@@ -81,12 +81,8 @@ github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=

View File

@@ -118,6 +118,8 @@ func RegisterRoutes(r chi.Router) {
l.Get("/", labels.ListLabels) l.Get("/", labels.ListLabels)
l.Post("/", labels.CreateLabel) l.Post("/", labels.CreateLabel)
l.Get("/{id}", labels.GetLabel) l.Get("/{id}", labels.GetLabel)
l.Patch("/{id}", labels.UpdateLabel)
l.Delete("/{id}", labels.DeleteLabel)
}) })
}) })
}) })

View File

@@ -19,3 +19,8 @@ type createLabelRequest struct {
Value string `json:"value"` Value string `json:"value"`
NodePoolIDs []string `json:"node_pool_ids,omitempty"` NodePoolIDs []string `json:"node_pool_ids,omitempty"`
} }
type updateLabelRequest struct {
Key *string `json:"key"`
Value *string `json:"value"`
}

View File

@@ -79,7 +79,6 @@ func ListLabels(w http.ResponseWriter, r *http.Request) {
// @Failure 404 {string} string "not found" // @Failure 404 {string} string "not found"
// @Failure 500 {string} string "fetch failed" // @Failure 500 {string} string "fetch failed"
// @Router /api/v1/labels/{id} [get] // @Router /api/v1/labels/{id} [get]
func GetLabel(w http.ResponseWriter, r *http.Request) { func GetLabel(w http.ResponseWriter, r *http.Request) {
ac := middleware.GetAuthContext(r) ac := middleware.GetAuthContext(r)
if ac == nil || ac.OrganizationID == uuid.Nil { if ac == nil || ac.OrganizationID == uuid.Nil {
@@ -176,5 +175,99 @@ func CreateLabel(w http.ResponseWriter, r *http.Request) {
} }
_ = response.JSON(w, http.StatusCreated, toResp(t, false)) _ = response.JSON(w, http.StatusCreated, toResp(t, false))
}
// UpdateLabel godoc
// @Summary Update label (org scoped)
// @Description Partially update label fields.
// @Tags labels
// @Accept json
// @Produce json
// @Param X-Org-ID header string true "Organization UUID"
// @Param id path string true "Label ID (UUID)"
// @Param body body updateLabelRequest true "Fields to update"
// @Security BearerAuth
// @Success 200 {object} labelResponse
// @Failure 400 {string} string "invalid id / invalid json"
// @Failure 401 {string} string "Unauthorized"
// @Failure 403 {string} string "organization required"
// @Failure 404 {string} string "not found"
// @Failure 500 {string} string "update failed"
// @Router /api/v1/labels/{id} [patch]
func UpdateLabel(w http.ResponseWriter, r *http.Request) {
ac := middleware.GetAuthContext(r)
if ac == nil || ac.OrganizationID == uuid.Nil {
http.Error(w, "organization required", http.StatusForbidden)
return
}
id, err := uuid.Parse(chi.URLParam(r, "id"))
if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest)
return
}
var t models.Label
if err := db.DB.Where("id = ? AND organization_id = ?", id, ac.OrganizationID).First(&t).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
http.Error(w, "not found", http.StatusNotFound)
return
}
http.Error(w, "fetch failed", http.StatusInternalServerError)
return
}
var req updateLabelRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid json or missing key/value", http.StatusBadRequest)
return
}
if req.Key != nil {
t.Key = strings.TrimSpace(*req.Key)
}
if req.Value != nil {
t.Value = strings.TrimSpace(*req.Value)
}
if err := db.DB.Save(&t).Error; err != nil {
http.Error(w, "update failed", http.StatusInternalServerError)
return
}
_ = response.JSON(w, http.StatusOK, toResp(t, false))
}
// DeleteLabel godoc
// @Summary Delete label (org scoped)
// @Description Permanently deletes the label.
// @Tags labels
// @Accept json
// @Produce json
// @Param X-Org-ID header string true "Organization UUID"
// @Param id path string true "Label ID (UUID)"
// @Security BearerAuth
// @Success 204 {string} string "No Content"
// @Failure 400 {string} string "invalid id"
// @Failure 401 {string} string "Unauthorized"
// @Failure 403 {string} string "organization required"
// @Failure 500 {string} string "delete failed"
// @Router /api/v1/labels/{id} [delete]
func DeleteLabel(w http.ResponseWriter, r *http.Request) {
ac := middleware.GetAuthContext(r)
if ac == nil || ac.OrganizationID == uuid.Nil {
http.Error(w, "organization required", http.StatusForbidden)
return
}
id, err := uuid.Parse(chi.URLParam(r, "id"))
if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest)
return
}
if err := db.DB.Where("id = ? AND organization_id = ?", id, ac.OrganizationID).Delete(&models.Taint{}).Error; err != nil {
http.Error(w, "delete failed", http.StatusInternalServerError)
return
}
response.NoContent(w)
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import{r as i}from"./vendor-DBKlM1wc.js";function Zt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}/** import{r as i}from"./vendor-DvippHRz.js";function Zt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}/**
* react-router v7.8.2 * react-router v7.8.2
* *
* Copyright (c) Remix Software Inc. * Copyright (c) Remix Software Inc.

File diff suppressed because one or more lines are too long

View File

@@ -5,12 +5,12 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AutoGlue</title> <title>AutoGlue</title>
<script type="module" crossorigin src="/assets/index-eleTxiqf.js"></script> <script type="module" crossorigin src="/assets/index-CmZFDWt2.js"></script>
<link rel="modulepreload" crossorigin href="/assets/router-CQ4G2GmP.js"> <link rel="modulepreload" crossorigin href="/assets/router-CANfZtzM.js">
<link rel="modulepreload" crossorigin href="/assets/vendor-DBKlM1wc.js"> <link rel="modulepreload" crossorigin href="/assets/vendor-DvippHRz.js">
<link rel="modulepreload" crossorigin href="/assets/radix-BnAuhYuH.js"> <link rel="modulepreload" crossorigin href="/assets/radix-DRmH1vcw.js">
<link rel="modulepreload" crossorigin href="/assets/icons-CNkJtX2d.js"> <link rel="modulepreload" crossorigin href="/assets/icons-DQ1I1M7X.js">
<link rel="stylesheet" crossorigin href="/assets/index-D2Vr0ZQJ.css"> <link rel="stylesheet" crossorigin href="/assets/index--a4aJrTK.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -50,10 +50,10 @@
"prettier": "^3.6.2", "prettier": "^3.6.2",
"prettier-plugin-tailwindcss": "^0.6.14", "prettier-plugin-tailwindcss": "^0.6.14",
"rollup-plugin-visualizer": "^6.0.3", "rollup-plugin-visualizer": "^6.0.3",
"shadcn": "^3.0.0", "shadcn": "^3.1.0",
"tw-animate-css": "^1.3.7", "tw-animate-css": "^1.3.8",
"typescript": "~5.9.2", "typescript": "~5.9.2",
"typescript-eslint": "^8.41.0", "typescript-eslint": "^8.42.0",
"vite": "^7.1.3" "vite": "^7.1.4"
} }
} }

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1430,79 +1430,79 @@
resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.6.tgz#66748315cc9a96d63403baa8671b2c124f8633aa" resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.6.tgz#66748315cc9a96d63403baa8671b2c124f8633aa"
integrity sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA== integrity sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==
"@typescript-eslint/eslint-plugin@8.41.0": "@typescript-eslint/eslint-plugin@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.41.0.tgz#42209e2ce3e2274de0f5f9b75c777deedacaa558" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.42.0.tgz#2172d0496c42eee8c7294b6661681100953fa88f"
integrity sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw== integrity sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==
dependencies: dependencies:
"@eslint-community/regexpp" "^4.10.0" "@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "8.41.0" "@typescript-eslint/scope-manager" "8.42.0"
"@typescript-eslint/type-utils" "8.41.0" "@typescript-eslint/type-utils" "8.42.0"
"@typescript-eslint/utils" "8.41.0" "@typescript-eslint/utils" "8.42.0"
"@typescript-eslint/visitor-keys" "8.41.0" "@typescript-eslint/visitor-keys" "8.42.0"
graphemer "^1.4.0" graphemer "^1.4.0"
ignore "^7.0.0" ignore "^7.0.0"
natural-compare "^1.4.0" natural-compare "^1.4.0"
ts-api-utils "^2.1.0" ts-api-utils "^2.1.0"
"@typescript-eslint/parser@8.41.0": "@typescript-eslint/parser@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.41.0.tgz#677f5b2b3fa947ee1eac4129220c051b1990d898" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.42.0.tgz#20ea66f4867981fb5bb62cbe1454250fc4a440ab"
integrity sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg== integrity sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==
dependencies: dependencies:
"@typescript-eslint/scope-manager" "8.41.0" "@typescript-eslint/scope-manager" "8.42.0"
"@typescript-eslint/types" "8.41.0" "@typescript-eslint/types" "8.42.0"
"@typescript-eslint/typescript-estree" "8.41.0" "@typescript-eslint/typescript-estree" "8.42.0"
"@typescript-eslint/visitor-keys" "8.41.0" "@typescript-eslint/visitor-keys" "8.42.0"
debug "^4.3.4" debug "^4.3.4"
"@typescript-eslint/project-service@8.41.0": "@typescript-eslint/project-service@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.41.0.tgz#08ebf882d413a038926e73fda36e00c3dba84882" resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.42.0.tgz#636eb3418b6c42c98554dce884943708bf41a583"
integrity sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ== integrity sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==
dependencies: dependencies:
"@typescript-eslint/tsconfig-utils" "^8.41.0" "@typescript-eslint/tsconfig-utils" "^8.42.0"
"@typescript-eslint/types" "^8.41.0" "@typescript-eslint/types" "^8.42.0"
debug "^4.3.4" debug "^4.3.4"
"@typescript-eslint/scope-manager@8.41.0": "@typescript-eslint/scope-manager@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.41.0.tgz#c8aba12129cb9cead1f1727f58e6a0fcebeecdb5" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.42.0.tgz#36016757bc85b46ea42bae47b61f9421eddedde3"
integrity sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ== integrity sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==
dependencies: dependencies:
"@typescript-eslint/types" "8.41.0" "@typescript-eslint/types" "8.42.0"
"@typescript-eslint/visitor-keys" "8.41.0" "@typescript-eslint/visitor-keys" "8.42.0"
"@typescript-eslint/tsconfig-utils@8.41.0", "@typescript-eslint/tsconfig-utils@^8.41.0": "@typescript-eslint/tsconfig-utils@8.42.0", "@typescript-eslint/tsconfig-utils@^8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.41.0.tgz#134dee36eb16cdd78095a20bca0516d10b5dda75" resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.42.0.tgz#21a3e74396fd7443ff930bc41b27789ba7e9236e"
integrity sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw== integrity sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==
"@typescript-eslint/type-utils@8.41.0": "@typescript-eslint/type-utils@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.41.0.tgz#68d401e38fccf239925447e97bdbd048a9891ae5" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.42.0.tgz#d6733e7a9fbdf5af60c09c6038dffde13f4e4253"
integrity sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ== integrity sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==
dependencies: dependencies:
"@typescript-eslint/types" "8.41.0" "@typescript-eslint/types" "8.42.0"
"@typescript-eslint/typescript-estree" "8.41.0" "@typescript-eslint/typescript-estree" "8.42.0"
"@typescript-eslint/utils" "8.41.0" "@typescript-eslint/utils" "8.42.0"
debug "^4.3.4" debug "^4.3.4"
ts-api-utils "^2.1.0" ts-api-utils "^2.1.0"
"@typescript-eslint/types@8.41.0", "@typescript-eslint/types@^8.41.0": "@typescript-eslint/types@8.42.0", "@typescript-eslint/types@^8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.41.0.tgz#9935afeaae65e535abcbcee95383fa649c64d16d" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.42.0.tgz#ae15c09cebda20473772902033328e87372db008"
integrity sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag== integrity sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==
"@typescript-eslint/typescript-estree@8.41.0": "@typescript-eslint/typescript-estree@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.41.0.tgz#7c9cff8b4334ce96f14e9689692e8cf426ce4d59" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.42.0.tgz#593c3af87d4462252c0d7239d1720b84a1b56864"
integrity sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ== integrity sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==
dependencies: dependencies:
"@typescript-eslint/project-service" "8.41.0" "@typescript-eslint/project-service" "8.42.0"
"@typescript-eslint/tsconfig-utils" "8.41.0" "@typescript-eslint/tsconfig-utils" "8.42.0"
"@typescript-eslint/types" "8.41.0" "@typescript-eslint/types" "8.42.0"
"@typescript-eslint/visitor-keys" "8.41.0" "@typescript-eslint/visitor-keys" "8.42.0"
debug "^4.3.4" debug "^4.3.4"
fast-glob "^3.3.2" fast-glob "^3.3.2"
is-glob "^4.0.3" is-glob "^4.0.3"
@@ -1510,22 +1510,22 @@
semver "^7.6.0" semver "^7.6.0"
ts-api-utils "^2.1.0" ts-api-utils "^2.1.0"
"@typescript-eslint/utils@8.41.0": "@typescript-eslint/utils@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.41.0.tgz#17cb3b766c1626311004ea41ffd8c27eb226b953" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.42.0.tgz#95f8e0c697ff2f7da5f72e16135011f878d815c0"
integrity sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A== integrity sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==
dependencies: dependencies:
"@eslint-community/eslint-utils" "^4.7.0" "@eslint-community/eslint-utils" "^4.7.0"
"@typescript-eslint/scope-manager" "8.41.0" "@typescript-eslint/scope-manager" "8.42.0"
"@typescript-eslint/types" "8.41.0" "@typescript-eslint/types" "8.42.0"
"@typescript-eslint/typescript-estree" "8.41.0" "@typescript-eslint/typescript-estree" "8.42.0"
"@typescript-eslint/visitor-keys@8.41.0": "@typescript-eslint/visitor-keys@8.42.0":
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.41.0.tgz#16eb99b55d207f6688002a2cf425e039579aa9a9" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.42.0.tgz#87c6caaa1ac307bc73a87c1fc469f88f0162f27e"
integrity sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg== integrity sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==
dependencies: dependencies:
"@typescript-eslint/types" "8.41.0" "@typescript-eslint/types" "8.42.0"
eslint-visitor-keys "^4.2.1" eslint-visitor-keys "^4.2.1"
"@vitejs/plugin-react@^5.0.2": "@vitejs/plugin-react@^5.0.2":
@@ -3539,10 +3539,10 @@ setprototypeof@1.2.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
shadcn@^3.0.0: shadcn@^3.1.0:
version "3.0.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/shadcn/-/shadcn-3.0.0.tgz#71e123c81c31980fbef5dba4ca7bf8f630a50bc7" resolved "https://registry.yarnpkg.com/shadcn/-/shadcn-3.1.0.tgz#e2174a17f78b0aa47ade6b958f5999bd79e67a0d"
integrity sha512-GhMwMwcxR3GpDO2ctocvyetQ7BJAxSakaznBtYM/1mPRTjN0I0TAZCGSXdfj0VXOW4PaHbFEHsyUCnFcEf/1Ag== integrity sha512-tYem+5cR8kSo0g3V3JbVpZ5NmblrH+b52UX9pgYkpyalotjejldZCAIoCszF3VoKTvHRRxrifmTO8gdOpmkz1w==
dependencies: dependencies:
"@antfu/ni" "^25.0.0" "@antfu/ni" "^25.0.0"
"@babel/core" "^7.28.0" "@babel/core" "^7.28.0"
@@ -3851,10 +3851,10 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
tw-animate-css@^1.3.7: tw-animate-css@^1.3.8:
version "1.3.7" version "1.3.8"
resolved "https://registry.yarnpkg.com/tw-animate-css/-/tw-animate-css-1.3.7.tgz#39bd63799cf5a67d17de33fd1b9714f1e2c60967" resolved "https://registry.yarnpkg.com/tw-animate-css/-/tw-animate-css-1.3.8.tgz#9d0c4820630fa04e8afe7a4670ab31d84ec44593"
integrity sha512-lvLb3hTIpB5oGsk8JmLoAjeCHV58nKa2zHYn8yWOoG5JJusH3bhJlF2DLAZ/5NmJ+jyH3ssiAx/2KmbhavJy/A== integrity sha512-Qrk3PZ7l7wUcGYhwZloqfkWCmaXZAoqjkdbIDvzfGshwGtexa/DAs9koXxIkrpEasyevandomzCBAV1Yyop5rw==
type-check@^0.4.0, type-check@~0.4.0: type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0" version "0.4.0"
@@ -3882,15 +3882,15 @@ type-is@^2.0.0, type-is@^2.0.1:
media-typer "^1.1.0" media-typer "^1.1.0"
mime-types "^3.0.0" mime-types "^3.0.0"
typescript-eslint@^8.41.0: typescript-eslint@^8.42.0:
version "8.41.0" version "8.42.0"
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.41.0.tgz#a13879a5998717140fefb0d808c8c2fbde1cb769" resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.42.0.tgz#e92f6c88569e202b361d5ca1655ad8e33a0554ea"
integrity sha512-n66rzs5OBXW3SFSnZHr2T685q1i4ODm2nulFJhMZBotaTavsS8TrI3d7bDlRSs9yWo7HmyWrN9qDu14Qv7Y0Dw== integrity sha512-ozR/rQn+aQXQxh1YgbCzQWDFrsi9mcg+1PM3l/z5o1+20P7suOIaNg515bpr/OYt6FObz/NHcBstydDLHWeEKg==
dependencies: dependencies:
"@typescript-eslint/eslint-plugin" "8.41.0" "@typescript-eslint/eslint-plugin" "8.42.0"
"@typescript-eslint/parser" "8.41.0" "@typescript-eslint/parser" "8.42.0"
"@typescript-eslint/typescript-estree" "8.41.0" "@typescript-eslint/typescript-estree" "8.42.0"
"@typescript-eslint/utils" "8.41.0" "@typescript-eslint/utils" "8.42.0"
typescript@~5.9.2: typescript@~5.9.2:
version "5.9.2" version "5.9.2"
@@ -3952,10 +3952,10 @@ vary@^1, vary@^1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
vite@^7.1.3: vite@^7.1.4:
version "7.1.3" version "7.1.4"
resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.3.tgz#8d70cb02fd6346b4bf1329a6760800538ef0faea" resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.4.tgz#354944affb55e1aff0157406b74e0d0a3232df9a"
integrity sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw== integrity sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw==
dependencies: dependencies:
esbuild "^0.25.0" esbuild "^0.25.0"
fdir "^6.5.0" fdir "^6.5.0"