Improve login page UI and fix hot-dev script for macOS
This commit is contained in:
parent
1626b0e3ae
commit
1e229d5f38
3 changed files with 131 additions and 61 deletions
|
|
@ -368,7 +368,7 @@ const LoginForm: Component<{
|
||||||
<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 via-white to-cyan-50 dark:from-gray-900 dark:via-gray-800 dark:to-blue-900 py-12 px-4 sm:px-6 lg:px-8">
|
<div class="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 via-white to-cyan-50 dark:from-gray-900 dark:via-gray-800 dark:to-blue-900 py-12 px-4 sm:px-6 lg:px-8">
|
||||||
<div class="max-w-md w-full space-y-8">
|
<div class="max-w-md w-full space-y-8">
|
||||||
<div class="animate-fade-in">
|
<div class="animate-fade-in">
|
||||||
<div class="flex justify-center mb-4">
|
<div class="flex justify-center mb-8">
|
||||||
<div class="relative group">
|
<div class="relative group">
|
||||||
<div class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-cyan-600 rounded-full blur opacity-25 group-hover:opacity-75 transition duration-1000 group-hover:duration-200 animate-pulse-slow"></div>
|
<div class="absolute -inset-1 bg-gradient-to-r from-blue-600 to-cyan-600 rounded-full blur opacity-25 group-hover:opacity-75 transition duration-1000 group-hover:duration-200 animate-pulse-slow"></div>
|
||||||
<img
|
<img
|
||||||
|
|
@ -378,10 +378,12 @@ const LoginForm: Component<{
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mt-6 text-center text-3xl font-extrabold bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent">
|
|
||||||
|
<h2 class="mt-6 text-center text-4xl font-extrabold bg-gradient-to-r from-blue-600 to-cyan-600 bg-clip-text text-transparent animate-fade-in delay-100 pb-1">
|
||||||
Welcome to Pulse
|
Welcome to Pulse
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-2 text-center text-sm text-gray-600 dark:text-gray-400">
|
|
||||||
|
<p class="mt-3 text-center text-sm text-gray-600 dark:text-gray-400 animate-fade-in delay-200">
|
||||||
Enter your credentials to continue
|
Enter your credentials to continue
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -524,11 +526,10 @@ const LoginForm: Component<{
|
||||||
|
|
||||||
<Show when={error()}>
|
<Show when={error()}>
|
||||||
<div
|
<div
|
||||||
class={`rounded-md p-4 ${
|
class={`rounded-md p-4 ${error().includes('locked')
|
||||||
error().includes('locked')
|
? 'bg-orange-50 dark:bg-orange-900/20'
|
||||||
? 'bg-orange-50 dark:bg-orange-900/20'
|
: 'bg-red-50 dark:bg-red-900/20'
|
||||||
: 'bg-red-50 dark:bg-red-900/20'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex-shrink-0">
|
<div class="flex-shrink-0">
|
||||||
|
|
@ -555,11 +556,10 @@ const LoginForm: Component<{
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-3">
|
<div class="ml-3">
|
||||||
<p
|
<p
|
||||||
class={`text-sm ${
|
class={`text-sm ${error().includes('locked')
|
||||||
error().includes('locked')
|
? 'text-orange-800 dark:text-orange-200'
|
||||||
? 'text-orange-800 dark:text-orange-200'
|
: 'text-red-800 dark:text-red-200'
|
||||||
: 'text-red-800 dark:text-red-200'
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
{error()}
|
{error()}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
@ -25,6 +26,7 @@
|
||||||
transform: translateX(100%) scale(0.95);
|
transform: translateX(100%) scale(0.95);
|
||||||
filter: blur(4px);
|
filter: blur(4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateX(0) scale(1);
|
transform: translateX(0) scale(1);
|
||||||
|
|
@ -80,7 +82,8 @@
|
||||||
/* Slider thumb styles with value display */
|
/* Slider thumb styles with value display */
|
||||||
.threshold-slider::-webkit-slider-thumb {
|
.threshold-slider::-webkit-slider-thumb {
|
||||||
@apply appearance-none w-12 h-5 rounded-full cursor-pointer relative;
|
@apply appearance-none w-12 h-5 rounded-full cursor-pointer relative;
|
||||||
margin-top: -2.5px; /* Center thumb on track */
|
margin-top: -2.5px;
|
||||||
|
/* Center thumb on track */
|
||||||
background: white;
|
background: white;
|
||||||
border: 2px solid currentColor;
|
border: 2px solid currentColor;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
|
|
@ -99,15 +102,18 @@
|
||||||
|
|
||||||
/* Color coding for different metrics */
|
/* Color coding for different metrics */
|
||||||
.threshold-slider.slider-cpu {
|
.threshold-slider.slider-cpu {
|
||||||
color: #3b82f6; /* blue-500 */
|
color: #3b82f6;
|
||||||
|
/* blue-500 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.threshold-slider.slider-memory {
|
.threshold-slider.slider-memory {
|
||||||
color: #10b981; /* green-500 */
|
color: #10b981;
|
||||||
|
/* green-500 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.threshold-slider.slider-disk {
|
.threshold-slider.slider-disk {
|
||||||
color: #f59e0b; /* amber-500 */
|
color: #f59e0b;
|
||||||
|
/* amber-500 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Value display inside thumb */
|
/* Value display inside thumb */
|
||||||
|
|
@ -227,20 +233,24 @@
|
||||||
/* Global scrollbar styling */
|
/* Global scrollbar styling */
|
||||||
* {
|
* {
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: rgba(156, 163, 175, 0.5) transparent; /* gray-400 with transparency */
|
scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
|
||||||
|
/* gray-400 with transparency */
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark * {
|
.dark * {
|
||||||
scrollbar-color: rgba(55, 65, 81, 0.5) transparent; /* gray-700 with transparency */
|
scrollbar-color: rgba(55, 65, 81, 0.5) transparent;
|
||||||
|
/* gray-700 with transparency */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make scrollbars even more subtle on hover */
|
/* Make scrollbars even more subtle on hover */
|
||||||
*:hover {
|
*:hover {
|
||||||
scrollbar-color: rgba(156, 163, 175, 0.7) rgba(243, 244, 246, 0.5); /* Slightly more visible on hover */
|
scrollbar-color: rgba(156, 163, 175, 0.7) rgba(243, 244, 246, 0.5);
|
||||||
|
/* Slightly more visible on hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark *:hover {
|
.dark *:hover {
|
||||||
scrollbar-color: rgba(75, 85, 99, 0.7) rgba(31, 41, 55, 0.3); /* dark mode hover */
|
scrollbar-color: rgba(75, 85, 99, 0.7) rgba(31, 41, 55, 0.3);
|
||||||
|
/* dark mode hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-webkit-scrollbar {
|
*::-webkit-scrollbar {
|
||||||
|
|
@ -311,20 +321,24 @@ body,
|
||||||
0% {
|
0% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
25% {
|
25% {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse-ring {
|
@keyframes pulse-ring {
|
||||||
|
|
||||||
0%,
|
0%,
|
||||||
100% {
|
100% {
|
||||||
opacity: 0.92;
|
opacity: 0.92;
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
|
|
@ -376,6 +390,7 @@ body,
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-10px);
|
transform: translateY(-10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
|
|
@ -387,6 +402,7 @@ body,
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(20px);
|
transform: translateY(20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
|
|
@ -394,17 +410,19 @@ body,
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes pulse-slow {
|
@keyframes pulse-slow {
|
||||||
|
|
||||||
0%,
|
0%,
|
||||||
100% {
|
100% {
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-fade-in {
|
.animate-fade-in {
|
||||||
animation: fade-in 0.6s ease-out;
|
animation: fade-in 0.6s ease-out forwards;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animate-slide-up {
|
.animate-slide-up {
|
||||||
|
|
@ -414,3 +432,50 @@ body,
|
||||||
.animate-pulse-slow {
|
.animate-pulse-slow {
|
||||||
animation: pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
animation: pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* New Premium Animations */
|
||||||
|
@keyframes float {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-float {
|
||||||
|
animation: float 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gradient-x {
|
||||||
|
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
background-size: 200% 200%;
|
||||||
|
background-position: left center;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-size: 200% 200%;
|
||||||
|
background-position: right center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-gradient-x {
|
||||||
|
animation: gradient-x 3s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delay-100 {
|
||||||
|
animation-delay: 100ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delay-200 {
|
||||||
|
animation-delay: 200ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delay-300 {
|
||||||
|
animation-delay: 300ms;
|
||||||
|
}
|
||||||
|
|
@ -123,14 +123,14 @@ kill_port() {
|
||||||
printf "[hot-dev] Cleaning up existing processes...\n"
|
printf "[hot-dev] Cleaning up existing processes...\n"
|
||||||
|
|
||||||
# Don't stop ourselves if we're running under systemd
|
# Don't stop ourselves if we're running under systemd
|
||||||
if [[ -z "${INVOCATION_ID:-}" ]]; then
|
# if [[ -z "${INVOCATION_ID:-}" ]]; then
|
||||||
# Not running under systemd, safe to stop the service
|
# Not running under systemd, safe to stop the service
|
||||||
sudo systemctl stop pulse-hot-dev 2>/dev/null || true
|
# sudo systemctl stop pulse-hot-dev 2>/dev/null || true
|
||||||
fi
|
# fi
|
||||||
|
|
||||||
sudo systemctl stop pulse-backend 2>/dev/null || true
|
# sudo systemctl stop pulse-backend 2>/dev/null || true
|
||||||
sudo systemctl stop pulse 2>/dev/null || true
|
# sudo systemctl stop pulse 2>/dev/null || true
|
||||||
sudo systemctl stop pulse-frontend 2>/dev/null || true
|
# sudo systemctl stop pulse-frontend 2>/dev/null || true
|
||||||
|
|
||||||
pkill -f "backend-watch.sh" 2>/dev/null || true
|
pkill -f "backend-watch.sh" 2>/dev/null || true
|
||||||
pkill -f vite 2>/dev/null || true
|
pkill -f vite 2>/dev/null || true
|
||||||
|
|
@ -271,47 +271,52 @@ printf "[hot-dev] Starting backend file watcher...\n"
|
||||||
cd "${ROOT_DIR}"
|
cd "${ROOT_DIR}"
|
||||||
while true; do
|
while true; do
|
||||||
# Watch for changes to .go files (excluding vendor and node_modules)
|
# Watch for changes to .go files (excluding vendor and node_modules)
|
||||||
inotifywait -r -e modify,create,delete,move \
|
if command -v inotifywait >/dev/null 2>&1; then
|
||||||
--exclude '(vendor/|node_modules/|\.git/|\.swp$|\.tmp$|~$)' \
|
inotifywait -r -e modify,create,delete,move \
|
||||||
--format '%e %w%f' \
|
--exclude '(vendor/|node_modules/|\.git/|\.swp$|\.tmp$|~$)' \
|
||||||
"${ROOT_DIR}/cmd" "${ROOT_DIR}/internal" "${ROOT_DIR}/pkg" 2>/dev/null | \
|
--format '%e %w%f' \
|
||||||
while read -r event changed_file; do
|
"${ROOT_DIR}/cmd" "${ROOT_DIR}/internal" "${ROOT_DIR}/pkg" 2>/dev/null | \
|
||||||
# Rebuild on any .go file change OR any create/delete event (catches new files)
|
while read -r event changed_file; do
|
||||||
if [[ "$changed_file" == *.go ]] || [[ "$event" =~ CREATE|DELETE|MOVED ]]; then
|
# Rebuild on any .go file change OR any create/delete event (catches new files)
|
||||||
echo ""
|
if [[ "$changed_file" == *.go ]] || [[ "$event" =~ CREATE|DELETE|MOVED ]]; then
|
||||||
echo "[hot-dev] 🔄 Change detected: $event $(basename "$changed_file")"
|
echo ""
|
||||||
echo "[hot-dev] Rebuilding backend..."
|
echo "[hot-dev] 🔄 Change detected: $event $(basename "$changed_file")"
|
||||||
|
echo "[hot-dev] Rebuilding backend..."
|
||||||
|
|
||||||
# Rebuild the binary
|
# Rebuild the binary
|
||||||
if go build -o pulse ./cmd/pulse 2>&1 | grep -v "^#"; then
|
if go build -o pulse ./cmd/pulse 2>&1 | grep -v "^#"; then
|
||||||
echo "[hot-dev] ✓ Build successful, restarting backend..."
|
echo "[hot-dev] ✓ Build successful, restarting backend..."
|
||||||
|
|
||||||
# Find and kill old backend
|
# Find and kill old backend
|
||||||
OLD_PID=$(pgrep -f "^\./pulse$" || true)
|
OLD_PID=$(pgrep -f "^\./pulse$" || true)
|
||||||
if [[ -n "$OLD_PID" ]]; then
|
if [[ -n "$OLD_PID" ]]; then
|
||||||
kill "$OLD_PID" 2>/dev/null || true
|
kill "$OLD_PID" 2>/dev/null || true
|
||||||
sleep 1
|
sleep 1
|
||||||
if kill -0 "$OLD_PID" 2>/dev/null; then
|
if kill -0 "$OLD_PID" 2>/dev/null; then
|
||||||
kill -9 "$OLD_PID" 2>/dev/null || true
|
kill -9 "$OLD_PID" 2>/dev/null || true
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Start new backend with same environment
|
# Start new backend with same environment
|
||||||
FRONTEND_PORT=${PULSE_DEV_API_PORT} PORT=${PULSE_DEV_API_PORT} PULSE_DATA_DIR=${PULSE_DATA_DIR} ./pulse &
|
FRONTEND_PORT=${PULSE_DEV_API_PORT} PORT=${PULSE_DEV_API_PORT} PULSE_DATA_DIR=${PULSE_DATA_DIR} ./pulse &
|
||||||
NEW_PID=$!
|
NEW_PID=$!
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
if kill -0 "$NEW_PID" 2>/dev/null; then
|
if kill -0 "$NEW_PID" 2>/dev/null; then
|
||||||
echo "[hot-dev] ✓ Backend restarted (PID: $NEW_PID)"
|
echo "[hot-dev] ✓ Backend restarted (PID: $NEW_PID)"
|
||||||
|
else
|
||||||
|
echo "[hot-dev] ✗ Backend failed to start!"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo "[hot-dev] ✗ Backend failed to start!"
|
echo "[hot-dev] ✗ Build failed!"
|
||||||
fi
|
fi
|
||||||
else
|
echo "[hot-dev] Watching for changes..."
|
||||||
echo "[hot-dev] ✗ Build failed!"
|
|
||||||
fi
|
fi
|
||||||
echo "[hot-dev] Watching for changes..."
|
done
|
||||||
fi
|
else
|
||||||
done
|
echo "[hot-dev] inotifywait not found. Auto-rebuild disabled."
|
||||||
|
sleep 3600
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
) &
|
) &
|
||||||
WATCHER_PID=$!
|
WATCHER_PID=$!
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue