@necrolab/dashboard 0.4.220 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +27 -1
- package/.vscode/extensions.json +1 -1
- package/README.md +64 -2
- package/artwork/image.png +0 -0
- package/backend/api.js +26 -24
- package/backend/auth.js +2 -2
- package/backend/batching.js +1 -1
- package/backend/endpoints.js +8 -11
- package/backend/index.js +2 -2
- package/backend/mock-data.js +27 -36
- package/backend/mock-src/classes/logger.js +5 -7
- package/backend/mock-src/classes/utils.js +3 -2
- package/backend/mock-src/ticketmaster.js +4 -4
- package/backend/validator.js +2 -2
- package/config/configs.json +0 -1
- package/dev-server.js +134 -0
- package/exit +209 -0
- package/index.html +78 -8
- package/index.js +1 -1
- package/jsconfig.json +16 -0
- package/package.json +39 -25
- package/postcss.config.js +1 -1
- package/postinstall.js +124 -20
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/img/logo_trans.png +0 -0
- package/public/img/necro_logo.png +0 -0
- package/public/manifest.json +16 -10
- package/run +176 -9
- package/src/App.vue +498 -85
- package/src/assets/css/base/reset.scss +43 -0
- package/src/assets/css/base/scroll.scss +114 -0
- package/src/assets/css/base/typography.scss +37 -0
- package/src/assets/css/components/buttons.scss +216 -0
- package/src/assets/css/components/forms.scss +221 -0
- package/src/assets/css/components/modals.scss +13 -0
- package/src/assets/css/components/tables.scss +27 -0
- package/src/assets/css/components/toasts.scss +100 -0
- package/src/assets/css/main.scss +201 -122
- package/src/assets/img/background.svg +2 -2
- package/src/assets/img/background.svg.backup +11 -0
- package/src/assets/img/logo_trans.png +0 -0
- package/src/components/Auth/LoginForm.vue +62 -11
- package/src/components/Editors/Account/Account.vue +116 -40
- package/src/components/Editors/Account/AccountCreator.vue +88 -39
- package/src/components/Editors/Account/AccountView.vue +102 -34
- package/src/components/Editors/Account/CreateAccount.vue +80 -32
- package/src/components/Editors/Profile/CreateProfile.vue +269 -83
- package/src/components/Editors/Profile/Profile.vue +132 -47
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +82 -20
- package/src/components/Editors/Profile/ProfileView.vue +89 -32
- package/src/components/Editors/TagLabel.vue +67 -6
- package/src/components/Editors/TagToggle.vue +7 -2
- package/src/components/Filter/Filter.vue +288 -71
- package/src/components/Filter/FilterPreview.vue +202 -31
- package/src/components/Filter/PriceSortToggle.vue +76 -6
- package/src/components/Table/Header.vue +1 -1
- package/src/components/Table/Row.vue +1 -1
- package/src/components/Table/Table.vue +19 -2
- package/src/components/Tasks/CheckStock.vue +6 -8
- package/src/components/Tasks/Controls/DesktopControls.vue +27 -17
- package/src/components/Tasks/Controls/MobileControls.vue +8 -45
- package/src/components/Tasks/CreateTaskAXS.vue +80 -72
- package/src/components/Tasks/CreateTaskTM.vue +95 -141
- package/src/components/Tasks/MassEdit.vue +4 -6
- package/src/components/Tasks/QuickSettings.vue +199 -30
- package/src/components/Tasks/ScrapeVenue.vue +5 -6
- package/src/components/Tasks/Stats.vue +50 -24
- package/src/components/Tasks/Task.vue +384 -179
- package/src/components/Tasks/TaskLabel.vue +2 -2
- package/src/components/Tasks/TaskView.vue +136 -48
- package/src/components/Tasks/Utilities.vue +25 -10
- package/src/components/Tasks/ViewTask.vue +321 -0
- package/src/components/icons/Bag.vue +1 -1
- package/src/components/icons/Check.vue +5 -0
- package/src/components/icons/Close.vue +21 -0
- package/src/components/icons/CloseX.vue +5 -0
- package/src/components/icons/Eye.vue +6 -0
- package/src/components/icons/Key.vue +21 -0
- package/src/components/icons/Loyalty.vue +1 -1
- package/src/components/icons/Mail.vue +2 -2
- package/src/components/icons/Pencil.vue +21 -0
- package/src/components/icons/Play.vue +2 -2
- package/src/components/icons/Profile.vue +18 -0
- package/src/components/icons/Reload.vue +4 -5
- package/src/components/icons/Sandclock.vue +2 -2
- package/src/components/icons/Sell.vue +21 -0
- package/src/components/icons/Spinner.vue +42 -0
- package/src/components/icons/SquareCheck.vue +18 -0
- package/src/components/icons/SquareUncheck.vue +18 -0
- package/src/components/icons/Stadium.vue +1 -1
- package/src/components/icons/Wildcard.vue +18 -0
- package/src/components/icons/index.js +26 -1
- package/src/components/ui/Modal.vue +107 -13
- package/src/components/ui/Navbar.vue +175 -40
- package/src/components/ui/ReconnectIndicator.vue +351 -55
- package/src/components/ui/Splash.vue +5 -35
- package/src/components/ui/controls/CountryChooser.vue +200 -62
- package/src/components/ui/controls/atomic/Checkbox.vue +119 -10
- package/src/components/ui/controls/atomic/Dropdown.vue +216 -39
- package/src/components/ui/controls/atomic/LoadingButton.vue +45 -0
- package/src/components/ui/controls/atomic/MultiDropdown.vue +300 -37
- package/src/components/ui/controls/atomic/Switch.vue +53 -25
- package/src/composables/useClickOutside.js +21 -0
- package/src/composables/useDropdownPosition.js +174 -0
- package/src/libs/Filter.js +60 -24
- package/src/registerServiceWorker.js +1 -1
- package/src/stores/connection.js +4 -4
- package/src/stores/sampleData.js +172 -199
- package/src/stores/ui.js +55 -20
- package/src/stores/utils.js +30 -4
- package/src/types/index.js +41 -0
- package/src/utils/debug.js +1 -0
- package/src/views/Accounts.vue +116 -50
- package/src/views/Console.vue +394 -79
- package/src/views/Editor.vue +1176 -123
- package/src/views/FilterBuilder.vue +528 -250
- package/src/views/Login.vue +76 -14
- package/src/views/Profiles.vue +119 -34
- package/src/views/Tasks.vue +266 -98
- package/static/offline.html +192 -50
- package/switch-branch.sh +41 -0
- package/tailwind.config.js +119 -27
- package/vite.config.js +73 -16
- package/workbox-config.cjs +63 -0
- package/ICONS.md +0 -21
- package/public/img/background.svg +0 -14
- package/public/img/logo.png +0 -0
- package/public/img/logo_icon.png +0 -0
- package/public/img/logo_icon_2.png +0 -0
- package/src/assets/css/_input.scss +0 -143
- package/src/assets/img/logo.png +0 -0
- package/src/assets/img/logo_icon.png +0 -0
- package/src/assets/img/logo_icon_2.png +0 -0
- package/vue.config.js +0 -32
- package/workbox-config.js +0 -7
package/exit
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# 🎯 Necro Dashboard Exit - Fire Edition 🔥
|
|
4
|
+
# Enhanced exit script with style and robust functionality
|
|
5
|
+
|
|
6
|
+
# Colors for that fire output 🌈
|
|
7
|
+
RED='\033[0;31m'
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
YELLOW='\033[1;33m'
|
|
10
|
+
BLUE='\033[0;34m'
|
|
11
|
+
PURPLE='\033[0;35m'
|
|
12
|
+
CYAN='\033[0;36m'
|
|
13
|
+
WHITE='\033[1;37m'
|
|
14
|
+
BOLD='\033[1m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
# Fire emojis for maximum style
|
|
18
|
+
FIRE="🔥"
|
|
19
|
+
STOP="🛑"
|
|
20
|
+
GEAR="⚙️"
|
|
21
|
+
CHECK="✅"
|
|
22
|
+
CROSS="❌"
|
|
23
|
+
LIGHTNING="⚡"
|
|
24
|
+
SKULL="💀"
|
|
25
|
+
|
|
26
|
+
# Banner function
|
|
27
|
+
show_banner() {
|
|
28
|
+
echo -e "${RED}${BOLD}"
|
|
29
|
+
echo " ███╗ ██╗███████╗ ██████╗██████╗ ██████╗ "
|
|
30
|
+
echo " ████╗ ██║██╔════╝██╔════╝██╔══██╗██╔═══██╗"
|
|
31
|
+
echo " ██╔██╗ ██║█████╗ ██║ ██████╔╝██║ ██║"
|
|
32
|
+
echo " ██║╚██╗██║██╔══╝ ██║ ██╔══██╗██║ ██║"
|
|
33
|
+
echo " ██║ ╚████║███████╗╚██████╗██║ ██║╚██████╔╝"
|
|
34
|
+
echo " ╚═╝ ╚═══╝╚══════╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝ "
|
|
35
|
+
echo -e "${NC}"
|
|
36
|
+
echo -e "${RED}${BOLD}Dashboard Exit ${SKULL} v2.0${NC}"
|
|
37
|
+
echo -e "${WHITE}────────────────────────────────────────────${NC}"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Success message
|
|
41
|
+
success() {
|
|
42
|
+
echo -e "${GREEN}${BOLD}${CHECK} $1${NC}"
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Error message
|
|
46
|
+
error() {
|
|
47
|
+
echo -e "${RED}${BOLD}${CROSS} $1${NC}"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Info message
|
|
51
|
+
info() {
|
|
52
|
+
echo -e "${CYAN}${BOLD}${LIGHTNING} $1${NC}"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# Warning message
|
|
56
|
+
warn() {
|
|
57
|
+
echo -e "${YELLOW}${BOLD}⚠️ $1${NC}"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Check if lsof is available
|
|
61
|
+
check_lsof() {
|
|
62
|
+
if ! command -v lsof &> /dev/null; then
|
|
63
|
+
error "lsof is not installed or not in PATH"
|
|
64
|
+
warn "Install with: brew install lsof (macOS) or apt-get install lsof (Linux)"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Function to kill process on a specific port with enhanced feedback
|
|
70
|
+
kill_port() {
|
|
71
|
+
local port=$1
|
|
72
|
+
local service_name=$2
|
|
73
|
+
|
|
74
|
+
info "Checking for processes on port ${port} (${service_name})..."
|
|
75
|
+
|
|
76
|
+
# Get PID using lsof
|
|
77
|
+
local pid=$(lsof -ti:$port 2>/dev/null)
|
|
78
|
+
|
|
79
|
+
if [ -n "$pid" ]; then
|
|
80
|
+
# Get process name for better feedback
|
|
81
|
+
local process_name=$(ps -p $pid -o comm= 2>/dev/null || echo "unknown")
|
|
82
|
+
|
|
83
|
+
warn "Found process: ${process_name} (PID: ${pid}) on port ${port}"
|
|
84
|
+
|
|
85
|
+
# Try graceful termination first
|
|
86
|
+
info "Attempting graceful shutdown..."
|
|
87
|
+
if kill -TERM $pid 2>/dev/null; then
|
|
88
|
+
sleep 2
|
|
89
|
+
|
|
90
|
+
# Check if process is still running
|
|
91
|
+
if kill -0 $pid 2>/dev/null; then
|
|
92
|
+
warn "Process still running, forcing termination..."
|
|
93
|
+
if kill -9 $pid 2>/dev/null; then
|
|
94
|
+
success "Process ${pid} forcefully terminated on port ${port}"
|
|
95
|
+
else
|
|
96
|
+
error "Failed to kill process ${pid} on port ${port}"
|
|
97
|
+
return 1
|
|
98
|
+
fi
|
|
99
|
+
else
|
|
100
|
+
success "Process ${pid} gracefully terminated on port ${port}"
|
|
101
|
+
fi
|
|
102
|
+
else
|
|
103
|
+
error "Failed to send termination signal to process ${pid}"
|
|
104
|
+
return 1
|
|
105
|
+
fi
|
|
106
|
+
else
|
|
107
|
+
info "No process found on port ${port} (${service_name})"
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
return 0
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Function to kill all Node.js processes
|
|
114
|
+
kill_all_node() {
|
|
115
|
+
info "Searching for Node.js processes..."
|
|
116
|
+
|
|
117
|
+
local node_pids=$(pgrep -f "node" 2>/dev/null)
|
|
118
|
+
|
|
119
|
+
if [ -n "$node_pids" ]; then
|
|
120
|
+
warn "Found Node.js processes, terminating..."
|
|
121
|
+
echo "$node_pids" | while read -r pid; do
|
|
122
|
+
if [ -n "$pid" ]; then
|
|
123
|
+
local process_info=$(ps -p $pid -o args= 2>/dev/null || echo "unknown")
|
|
124
|
+
info "Killing Node.js process: $pid ($process_info)"
|
|
125
|
+
kill -TERM $pid 2>/dev/null || kill -9 $pid 2>/dev/null
|
|
126
|
+
fi
|
|
127
|
+
done
|
|
128
|
+
success "All Node.js processes terminated"
|
|
129
|
+
else
|
|
130
|
+
info "No Node.js processes found"
|
|
131
|
+
fi
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Function to clean up development servers
|
|
135
|
+
cleanup_dev_servers() {
|
|
136
|
+
info "Cleaning up development servers ${GEAR}"
|
|
137
|
+
|
|
138
|
+
# Kill specific ports used by the dashboard
|
|
139
|
+
kill_port 5173 "Vite Dev Server"
|
|
140
|
+
kill_port 8081 "Backend Server"
|
|
141
|
+
kill_port 3000 "Alternative Dev Server"
|
|
142
|
+
kill_port 8080 "Alternative Backend"
|
|
143
|
+
|
|
144
|
+
echo ""
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Help function
|
|
148
|
+
show_help() {
|
|
149
|
+
echo -e "${WHITE}${BOLD}Usage:${NC}"
|
|
150
|
+
echo -e " ${CYAN}./exit${NC} ${WHITE}Stop dashboard servers (ports 5173, 8081)${NC}"
|
|
151
|
+
echo -e " ${CYAN}./exit all${NC} ${WHITE}Stop all Node.js processes${NC}"
|
|
152
|
+
echo -e " ${CYAN}./exit port <n>${NC} ${WHITE}Stop process on specific port${NC}"
|
|
153
|
+
echo -e " ${CYAN}./exit help${NC} ${WHITE}Show this help message${NC}"
|
|
154
|
+
echo ""
|
|
155
|
+
echo -e "${WHITE}${BOLD}Examples:${NC}"
|
|
156
|
+
echo -e " ${YELLOW}./exit${NC} ${GREEN}# Stop dashboard servers${NC}"
|
|
157
|
+
echo -e " ${YELLOW}./exit all${NC} ${GREEN}# Nuclear option - kill all Node.js${NC}"
|
|
158
|
+
echo -e " ${YELLOW}./exit port 3000${NC} ${GREEN}# Stop specific port${NC}"
|
|
159
|
+
echo ""
|
|
160
|
+
echo -e "${RED}Made with ${SKULL} for clean shutdowns${NC}"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# Main execution flow
|
|
164
|
+
main() {
|
|
165
|
+
# Clear screen for clean output
|
|
166
|
+
clear
|
|
167
|
+
|
|
168
|
+
# Show the banner
|
|
169
|
+
show_banner
|
|
170
|
+
|
|
171
|
+
# Check dependencies
|
|
172
|
+
check_lsof
|
|
173
|
+
|
|
174
|
+
case "${1:-}" in
|
|
175
|
+
"all")
|
|
176
|
+
kill_all_node
|
|
177
|
+
;;
|
|
178
|
+
"port")
|
|
179
|
+
if [ -z "$2" ]; then
|
|
180
|
+
error "Port number required"
|
|
181
|
+
echo -e "${CYAN}Usage: ./exit port <port_number>${NC}"
|
|
182
|
+
exit 1
|
|
183
|
+
fi
|
|
184
|
+
kill_port "$2" "Custom Port"
|
|
185
|
+
;;
|
|
186
|
+
"help"|"-h"|"--help")
|
|
187
|
+
show_help
|
|
188
|
+
;;
|
|
189
|
+
"")
|
|
190
|
+
cleanup_dev_servers
|
|
191
|
+
;;
|
|
192
|
+
*)
|
|
193
|
+
warn "Unknown command: $1"
|
|
194
|
+
echo ""
|
|
195
|
+
show_help
|
|
196
|
+
exit 1
|
|
197
|
+
;;
|
|
198
|
+
esac
|
|
199
|
+
|
|
200
|
+
echo ""
|
|
201
|
+
success "Exit sequence completed ${STOP}"
|
|
202
|
+
echo -e "${PURPLE}Dashboard processes have been terminated ${FIRE}${NC}"
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# Error handling for script interruption
|
|
206
|
+
trap 'echo -e "\n${YELLOW}${BOLD}${LIGHTNING} Exit script interrupted${NC}"; exit 0' INT
|
|
207
|
+
|
|
208
|
+
# Run the main function
|
|
209
|
+
main "$@"
|
package/index.html
CHANGED
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
/>
|
|
10
10
|
<meta name="description" content="Necro Lab - dashboard" />
|
|
11
11
|
<title>Necro Lab - Dashboard</title>
|
|
12
|
+
<!-- DNS prefetch for external resources -->
|
|
13
|
+
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
|
|
14
|
+
<link rel="dns-prefetch" href="https://fonts.gstatic.com" />
|
|
15
|
+
|
|
16
|
+
<!-- Preconnect for critical external resources -->
|
|
12
17
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
13
18
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
14
19
|
<link
|
|
@@ -16,26 +21,91 @@
|
|
|
16
21
|
rel="stylesheet"
|
|
17
22
|
/>
|
|
18
23
|
|
|
19
|
-
<!--
|
|
20
|
-
<link
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
<!-- Preload critical fonts -->
|
|
25
|
+
<link
|
|
26
|
+
rel="preload"
|
|
27
|
+
href="https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiA.woff2"
|
|
28
|
+
as="font"
|
|
29
|
+
type="font/woff2"
|
|
30
|
+
crossorigin
|
|
31
|
+
/>
|
|
32
|
+
|
|
33
|
+
<!-- Preload critical assets -->
|
|
34
|
+
<link rel="preload" as="image" href="/img/background.svg" />
|
|
35
|
+
<link rel="preload" as="image" href="/img/logo_trans.png" />
|
|
36
|
+
|
|
37
|
+
<!-- Prefetch core navigation icons -->
|
|
23
38
|
<link rel="prefetch" as="image" href="/img/close.svg" />
|
|
24
39
|
<link rel="prefetch" as="image" href="/img/mail.svg" />
|
|
40
|
+
<link rel="prefetch" as="image" href="/img/groups.svg" />
|
|
41
|
+
<link rel="prefetch" as="image" href="/img/reload.svg" />
|
|
42
|
+
|
|
43
|
+
<!-- Prefetch task-related icons -->
|
|
44
|
+
<link rel="prefetch" as="image" href="/img/pencil.svg" />
|
|
45
|
+
<link rel="prefetch" as="image" href="/img/scanner.svg" />
|
|
25
46
|
<link rel="prefetch" as="image" href="/img/key.svg" />
|
|
26
47
|
<link rel="prefetch" as="image" href="/img/camera.svg" />
|
|
27
48
|
<link rel="prefetch" as="image" href="/img/timer.svg" />
|
|
28
|
-
<link rel="prefetch" as="image" href="/img/groups.svg" />
|
|
29
49
|
<link rel="prefetch" as="image" href="/img/hand.svg" />
|
|
30
50
|
<link rel="prefetch" as="image" href="/img/savings.svg" />
|
|
31
51
|
<link rel="prefetch" as="image" href="/img/loyalty.svg" />
|
|
32
52
|
<link rel="prefetch" as="image" href="/img/shield.svg" />
|
|
33
53
|
<link rel="prefetch" as="image" href="/img/ski.svg" />
|
|
34
54
|
<link rel="prefetch" as="image" href="/img/sell.svg" />
|
|
35
|
-
<link rel="prefetch" as="image" href="/img/
|
|
55
|
+
<link rel="prefetch" as="image" href="/img/award.svg" />
|
|
56
|
+
<link rel="prefetch" as="image" href="/img/stadium.svg" />
|
|
57
|
+
<link rel="prefetch" as="image" href="/img/stadium_w.svg" />
|
|
58
|
+
<link rel="prefetch" as="image" href="/img/bag_w.svg" />
|
|
59
|
+
<link rel="prefetch" as="image" href="/img/sandclock.svg" />
|
|
60
|
+
<link rel="prefetch" as="image" href="/img/profile.svg" />
|
|
61
|
+
|
|
62
|
+
<!-- Prefetch control icons -->
|
|
63
|
+
<link rel="prefetch" as="image" href="/img/controls/enable.svg" />
|
|
64
|
+
<link rel="prefetch" as="image" href="/img/controls/disable.svg" />
|
|
65
|
+
|
|
66
|
+
<!-- Prefetch payment icons -->
|
|
67
|
+
<link rel="prefetch" as="image" href="/img/banks/visa.svg" />
|
|
68
|
+
<link rel="prefetch" as="image" href="/img/banks/mastercard.svg" />
|
|
69
|
+
<link rel="prefetch" as="image" href="/img/banks/amex.svg" />
|
|
70
|
+
|
|
71
|
+
<!-- Prefetch all flag icons (country selector) -->
|
|
72
|
+
<link rel="prefetch" as="image" href="/flags/us.svg" />
|
|
73
|
+
<link rel="prefetch" as="image" href="/flags/uk.svg" />
|
|
74
|
+
<link rel="prefetch" as="image" href="/flags/au.svg" />
|
|
75
|
+
<link rel="prefetch" as="image" href="/flags/de.svg" />
|
|
76
|
+
<link rel="prefetch" as="image" href="/flags/nl.svg" />
|
|
77
|
+
<link rel="prefetch" as="image" href="/flags/at.svg" />
|
|
78
|
+
<link rel="prefetch" as="image" href="/flags/be.svg" />
|
|
79
|
+
<link rel="prefetch" as="image" href="/flags/ch.svg" />
|
|
80
|
+
<link rel="prefetch" as="image" href="/flags/cz.svg" />
|
|
81
|
+
<link rel="prefetch" as="image" href="/flags/dk.svg" />
|
|
82
|
+
<link rel="prefetch" as="image" href="/flags/es.svg" />
|
|
83
|
+
<link rel="prefetch" as="image" href="/flags/no.svg" />
|
|
84
|
+
<link rel="prefetch" as="image" href="/flags/nz.svg" />
|
|
85
|
+
<link rel="prefetch" as="image" href="/flags/pl.svg" />
|
|
86
|
+
<link rel="prefetch" as="image" href="/flags/se.svg" />
|
|
87
|
+
<link rel="prefetch" as="image" href="/flags/ae.svg" />
|
|
88
|
+
|
|
89
|
+
<!-- Prefetch other logo variants -->
|
|
90
|
+
<link rel="prefetch" as="image" href="/android-chrome-192x192.png" />
|
|
91
|
+
|
|
92
|
+
<!-- Prefetch PWA resources -->
|
|
93
|
+
<link rel="prefetch" as="script" href="/sw.js" />
|
|
94
|
+
|
|
95
|
+
<!-- Preload critical PWA manifest -->
|
|
96
|
+
<link rel="preload" as="fetch" href="/manifest.json" crossorigin />
|
|
36
97
|
<link rel="manifest" href="/manifest.json" />
|
|
37
|
-
<meta name="theme-color" content="
|
|
38
|
-
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
98
|
+
<meta name="theme-color" content="#1a1b1e" />
|
|
99
|
+
<link rel="apple-touch-icon" href="/apple-touch-icon.png?v=2" />
|
|
100
|
+
|
|
101
|
+
<!-- Prism.js for syntax highlighting -->
|
|
102
|
+
<link
|
|
103
|
+
rel="stylesheet"
|
|
104
|
+
href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css"
|
|
105
|
+
/>
|
|
106
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script>
|
|
107
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script>
|
|
108
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-json.min.js"></script>
|
|
39
109
|
</head>
|
|
40
110
|
|
|
41
111
|
<body class="w-full">
|
package/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import api from "./backend/index.js";
|
|
2
2
|
api.start();
|
package/jsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"baseUrl": ".",
|
|
4
|
+
"paths": {
|
|
5
|
+
"@/*": ["src/*"]
|
|
6
|
+
},
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"checkJs": false,
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"moduleResolution": "node",
|
|
11
|
+
"target": "ESNext",
|
|
12
|
+
"jsx": "preserve"
|
|
13
|
+
},
|
|
14
|
+
"exclude": ["node_modules", "dist"],
|
|
15
|
+
"include": ["src/**/*"]
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@necrolab/dashboard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"scripts": {
|
|
5
|
-
"build": "npx workbox-cli generateSW workbox-config.
|
|
6
|
-
"dev": "
|
|
7
|
-
"bot": "
|
|
8
|
-
"expose": "
|
|
6
|
+
"build": "rm -rf dist && npx workbox-cli generateSW workbox-config.cjs && vite build",
|
|
7
|
+
"dev": "node dev-server.js",
|
|
8
|
+
"bot": "node dev-server.js",
|
|
9
|
+
"expose": "node dev-server.js",
|
|
9
10
|
"postinstall": "node postinstall.js",
|
|
10
11
|
"updaterenderer": "npm i @necrolab/tm-renderer@latest",
|
|
11
12
|
"preview": "vite preview",
|
|
12
13
|
"lint": "npx eslint src/ --fix"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
|
-
"@faker-js/faker": "^7.6.0",
|
|
16
16
|
"@msgpack/msgpack": "^3.0.0-beta2",
|
|
17
|
-
"@necrolab/tm-renderer": "^0.1.
|
|
18
|
-
"@vitejs/plugin-vue": "^5.
|
|
19
|
-
"@vueuse/core": "^
|
|
20
|
-
"autoprefixer": "^10.4.
|
|
21
|
-
"caniuse-lite": "^1.0.
|
|
22
|
-
"cookie-parser": "^1.4.
|
|
17
|
+
"@necrolab/tm-renderer": "^0.1.12",
|
|
18
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
19
|
+
"@vueuse/core": "^11.3.0",
|
|
20
|
+
"autoprefixer": "^10.4.21",
|
|
21
|
+
"caniuse-lite": "^1.0.30001692",
|
|
22
|
+
"cookie-parser": "^1.4.7",
|
|
23
23
|
"cors": "^2.8.5",
|
|
24
|
-
"
|
|
25
|
-
"express": "^4.19.1",
|
|
24
|
+
"express": "^4.21.2",
|
|
26
25
|
"express-ws": "^5.0.2",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
26
|
+
"ipaddr.js": "^2.2.0",
|
|
27
|
+
"pinia": "^2.3.0",
|
|
28
|
+
"postcss": "^8.4.49",
|
|
29
|
+
"prettier": "^3.5.3",
|
|
30
|
+
"prettier-plugin-tailwindcss": "^0.6.12",
|
|
29
31
|
"register-service-worker": "^1.7.2",
|
|
30
|
-
"sass": "^1.
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"vue": "^
|
|
35
|
-
"vue-router": "^4.2.5",
|
|
32
|
+
"sass": "^1.83.0",
|
|
33
|
+
"tailwindcss": "^3.4.17",
|
|
34
|
+
"vite": "^6.3.5",
|
|
35
|
+
"vue": "^3.5.14",
|
|
36
|
+
"vue-router": "^4.5.0",
|
|
36
37
|
"vue-smoothie": "^1.2.0",
|
|
37
38
|
"vue-virtual-scroller": "^2.0.0-beta.8",
|
|
38
39
|
"vue3-toastify": "^0.0.4",
|
|
@@ -41,8 +42,21 @@
|
|
|
41
42
|
},
|
|
42
43
|
"main": "index.js",
|
|
43
44
|
"devDependencies": {
|
|
44
|
-
"
|
|
45
|
-
"eslint": "^
|
|
46
|
-
"
|
|
45
|
+
"eslint": "^9.17.0",
|
|
46
|
+
"eslint-plugin-vue": "^9.32.0",
|
|
47
|
+
"workbox-cli": "^7.3.0"
|
|
48
|
+
},
|
|
49
|
+
"overrides": {
|
|
50
|
+
"glob": "^11.0.0",
|
|
51
|
+
"braces": "^3.0.3",
|
|
52
|
+
"micromatch": "^4.0.8",
|
|
53
|
+
"postcss": "^8.4.49",
|
|
54
|
+
"cookie-parser": "^1.4.7",
|
|
55
|
+
"express": "^4.21.2",
|
|
56
|
+
"body-parser": "^1.20.3",
|
|
57
|
+
"whatwg-url": "^14.0.0",
|
|
58
|
+
"ws": "^8.17.1",
|
|
59
|
+
"path-to-regexp": "^0.1.12",
|
|
60
|
+
"tmp": "^0.2.3"
|
|
47
61
|
}
|
|
48
62
|
}
|
package/postcss.config.js
CHANGED
package/postinstall.js
CHANGED
|
@@ -1,20 +1,124 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
// Read package.json to get current version
|
|
9
|
+
const packageJsonPath = path.join(__dirname, "package.json");
|
|
10
|
+
let currentVersion = "0.0.0";
|
|
11
|
+
try {
|
|
12
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
13
|
+
currentVersion = packageJson.version;
|
|
14
|
+
} catch (e) {
|
|
15
|
+
console.error(`Failed to read package.json version: ${e.message}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
// Detect if we're running inside the project itself or as a dependency
|
|
20
|
+
const isInsideProject = __dirname.includes('node_modules') === false;
|
|
21
|
+
|
|
22
|
+
let distPath, versionFilePath;
|
|
23
|
+
|
|
24
|
+
if (isInsideProject) {
|
|
25
|
+
// Running inside the project itself - build to ./dist
|
|
26
|
+
distPath = path.join(__dirname, "dist");
|
|
27
|
+
versionFilePath = path.join(distPath, "version.txt");
|
|
28
|
+
} else {
|
|
29
|
+
// Running as a dependency - build to parent project's dashboard/dist
|
|
30
|
+
const projectRoot = path.resolve(__dirname, "../../..");
|
|
31
|
+
const dashboardDir = path.join(projectRoot, "dashboard");
|
|
32
|
+
distPath = path.join(dashboardDir, "dist");
|
|
33
|
+
versionFilePath = path.join(distPath, "version.txt");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Check if we can skip logic
|
|
37
|
+
console.log(`Checking version at ${distPath}...`);
|
|
38
|
+
if (fs.existsSync(versionFilePath)) {
|
|
39
|
+
try {
|
|
40
|
+
const installedVersion = fs.readFileSync(versionFilePath, "utf-8").trim();
|
|
41
|
+
if (installedVersion === currentVersion) {
|
|
42
|
+
console.log(`Version ${currentVersion} is already installed at ${distPath}. Skipping build.`);
|
|
43
|
+
process.exit(0);
|
|
44
|
+
} else {
|
|
45
|
+
console.log(
|
|
46
|
+
`Version mismatch (Installed: ${installedVersion}, Target: ${currentVersion}). Proceeding with build.`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
} catch (readErr) {
|
|
50
|
+
console.log("Could not read version file. Proceeding with build.");
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
console.log("No version file found. Proceeding with build.");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log("Running postinstall build...");
|
|
57
|
+
|
|
58
|
+
// Service Worker
|
|
59
|
+
console.log("Generating service worker...");
|
|
60
|
+
try {
|
|
61
|
+
execSync(`npx workbox-cli generateSW workbox-config.cjs`, {
|
|
62
|
+
cwd: __dirname,
|
|
63
|
+
stdio: "inherit"
|
|
64
|
+
});
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error("Failed to generate service worker.");
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Build
|
|
71
|
+
console.log("Building with Vite...");
|
|
72
|
+
try {
|
|
73
|
+
execSync(`npx vite build`, {
|
|
74
|
+
cwd: __dirname,
|
|
75
|
+
stdio: "inherit"
|
|
76
|
+
});
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error("Failed to build with Vite.");
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const buildPath = path.join(__dirname, "dist");
|
|
83
|
+
|
|
84
|
+
if (!fs.existsSync(buildPath)) {
|
|
85
|
+
throw new Error(`Build failed: ${buildPath} does not exist.`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (isInsideProject) {
|
|
89
|
+
// Running inside project - dist is already in the right place, just write version
|
|
90
|
+
console.log("Build artifacts already in correct location.");
|
|
91
|
+
fs.writeFileSync(versionFilePath, currentVersion);
|
|
92
|
+
console.log(`Written version ${currentVersion} to ${versionFilePath}`);
|
|
93
|
+
} else {
|
|
94
|
+
// Running as dependency - move dist to parent project
|
|
95
|
+
console.log("Moving build artifacts...");
|
|
96
|
+
|
|
97
|
+
// Ensure target directory exists
|
|
98
|
+
const dashboardDir = path.dirname(distPath);
|
|
99
|
+
if (!fs.existsSync(dashboardDir)) {
|
|
100
|
+
console.log(`Creating target directory: ${dashboardDir}`);
|
|
101
|
+
fs.mkdirSync(dashboardDir, { recursive: true });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Clean destination
|
|
105
|
+
if (fs.existsSync(distPath)) {
|
|
106
|
+
fs.rmSync(distPath, { recursive: true, force: true });
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Copy
|
|
110
|
+
fs.cpSync(buildPath, distPath, { recursive: true });
|
|
111
|
+
|
|
112
|
+
// Write version file
|
|
113
|
+
fs.writeFileSync(versionFilePath, currentVersion);
|
|
114
|
+
console.log(`Written version ${currentVersion} to ${versionFilePath}`);
|
|
115
|
+
|
|
116
|
+
// Cleanup source dist
|
|
117
|
+
fs.rmSync(buildPath, { recursive: true, force: true });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.log("Postinstall completed successfully.");
|
|
121
|
+
} catch (e) {
|
|
122
|
+
console.error(`An error occurred: ${e.message}`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/public/favicon-16x16.png
CHANGED
|
Binary file
|
package/public/favicon-32x32.png
CHANGED
|
Binary file
|
package/public/favicon.ico
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/public/manifest.json
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
{
|
|
2
|
-
"short_name": "
|
|
3
|
-
"name": "
|
|
4
|
-
"icons": [
|
|
5
|
-
|
|
2
|
+
"short_name": "Necro",
|
|
3
|
+
"name": "Necro Dashboard",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "/android-chrome-192x192.png?v=2",
|
|
6
7
|
"type": "image/png",
|
|
7
8
|
"sizes": "192x192"
|
|
8
9
|
},
|
|
9
10
|
{
|
|
10
|
-
"src": "/android-chrome-192x192.png",
|
|
11
|
+
"src": "/android-chrome-192x192.png?v=2",
|
|
11
12
|
"type": "image/png",
|
|
12
13
|
"sizes": "192x192",
|
|
13
14
|
"purpose": "any maskable"
|
|
14
|
-
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
|
-
"src": "/android-chrome-512x512.png",
|
|
17
|
+
"src": "/android-chrome-512x512.png?v=2",
|
|
18
18
|
"type": "image/png",
|
|
19
19
|
"sizes": "512x512"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"src": "/apple-touch-icon.png?v=2",
|
|
23
|
+
"type": "image/png",
|
|
24
|
+
"sizes": "180x180"
|
|
20
25
|
}
|
|
21
26
|
],
|
|
22
27
|
"start_url": "/",
|
|
23
|
-
"background_color": "#
|
|
28
|
+
"background_color": "#2e2f32",
|
|
24
29
|
"display": "standalone",
|
|
25
30
|
"scope": "/",
|
|
26
|
-
"theme_color": "#
|
|
27
|
-
|
|
31
|
+
"theme_color": "#2e2f32",
|
|
32
|
+
"description": "Necro Lab"
|
|
33
|
+
}
|