mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
Improve login page UI and fix hot-dev script for macOS
This commit is contained in:
@@ -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="max-w-md w-full space-y-8">
|
||||
<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="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
|
||||
@@ -378,10 +378,12 @@ const LoginForm: Component<{
|
||||
/>
|
||||
</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
|
||||
</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
|
||||
</p>
|
||||
</div>
|
||||
@@ -524,11 +526,10 @@ const LoginForm: Component<{
|
||||
|
||||
<Show when={error()}>
|
||||
<div
|
||||
class={`rounded-md p-4 ${
|
||||
error().includes('locked')
|
||||
? 'bg-orange-50 dark:bg-orange-900/20'
|
||||
: 'bg-red-50 dark:bg-red-900/20'
|
||||
}`}
|
||||
class={`rounded-md p-4 ${error().includes('locked')
|
||||
? 'bg-orange-50 dark:bg-orange-900/20'
|
||||
: 'bg-red-50 dark:bg-red-900/20'
|
||||
}`}
|
||||
>
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
@@ -555,11 +556,10 @@ const LoginForm: Component<{
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<p
|
||||
class={`text-sm ${
|
||||
error().includes('locked')
|
||||
? 'text-orange-800 dark:text-orange-200'
|
||||
: 'text-red-800 dark:text-red-200'
|
||||
}`}
|
||||
class={`text-sm ${error().includes('locked')
|
||||
? 'text-orange-800 dark:text-orange-200'
|
||||
: 'text-red-800 dark:text-red-200'
|
||||
}`}
|
||||
>
|
||||
{error()}
|
||||
</p>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
@@ -25,6 +26,7 @@
|
||||
transform: translateX(100%) scale(0.95);
|
||||
filter: blur(4px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0) scale(1);
|
||||
@@ -80,7 +82,8 @@
|
||||
/* Slider thumb styles with value display */
|
||||
.threshold-slider::-webkit-slider-thumb {
|
||||
@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;
|
||||
border: 2px solid currentColor;
|
||||
box-shadow:
|
||||
@@ -99,15 +102,18 @@
|
||||
|
||||
/* Color coding for different metrics */
|
||||
.threshold-slider.slider-cpu {
|
||||
color: #3b82f6; /* blue-500 */
|
||||
color: #3b82f6;
|
||||
/* blue-500 */
|
||||
}
|
||||
|
||||
.threshold-slider.slider-memory {
|
||||
color: #10b981; /* green-500 */
|
||||
color: #10b981;
|
||||
/* green-500 */
|
||||
}
|
||||
|
||||
.threshold-slider.slider-disk {
|
||||
color: #f59e0b; /* amber-500 */
|
||||
color: #f59e0b;
|
||||
/* amber-500 */
|
||||
}
|
||||
|
||||
/* Value display inside thumb */
|
||||
@@ -227,20 +233,24 @@
|
||||
/* Global scrollbar styling */
|
||||
* {
|
||||
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 * {
|
||||
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 */
|
||||
*: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 {
|
||||
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 {
|
||||
@@ -311,20 +321,24 @@ body,
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse-ring {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.92;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.6;
|
||||
transform: scale(1.1);
|
||||
@@ -376,6 +390,7 @@ body,
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
@@ -387,6 +402,7 @@ body,
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
@@ -394,17 +410,19 @@ body,
|
||||
}
|
||||
|
||||
@keyframes pulse-slow {
|
||||
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.25;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fade-in 0.6s ease-out;
|
||||
animation: fade-in 0.6s ease-out forwards;
|
||||
}
|
||||
|
||||
.animate-slide-up {
|
||||
@@ -414,3 +432,50 @@ body,
|
||||
.animate-pulse-slow {
|
||||
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"
|
||||
|
||||
# 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
|
||||
sudo systemctl stop pulse-hot-dev 2>/dev/null || true
|
||||
fi
|
||||
# sudo systemctl stop pulse-hot-dev 2>/dev/null || true
|
||||
# fi
|
||||
|
||||
sudo systemctl stop pulse-backend 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-backend 2>/dev/null || true
|
||||
# sudo systemctl stop pulse 2>/dev/null || true
|
||||
# sudo systemctl stop pulse-frontend 2>/dev/null || true
|
||||
|
||||
pkill -f "backend-watch.sh" 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}"
|
||||
while true; do
|
||||
# Watch for changes to .go files (excluding vendor and node_modules)
|
||||
inotifywait -r -e modify,create,delete,move \
|
||||
--exclude '(vendor/|node_modules/|\.git/|\.swp$|\.tmp$|~$)' \
|
||||
--format '%e %w%f' \
|
||||
"${ROOT_DIR}/cmd" "${ROOT_DIR}/internal" "${ROOT_DIR}/pkg" 2>/dev/null | \
|
||||
while read -r event changed_file; do
|
||||
# Rebuild on any .go file change OR any create/delete event (catches new files)
|
||||
if [[ "$changed_file" == *.go ]] || [[ "$event" =~ CREATE|DELETE|MOVED ]]; then
|
||||
echo ""
|
||||
echo "[hot-dev] 🔄 Change detected: $event $(basename "$changed_file")"
|
||||
echo "[hot-dev] Rebuilding backend..."
|
||||
if command -v inotifywait >/dev/null 2>&1; then
|
||||
inotifywait -r -e modify,create,delete,move \
|
||||
--exclude '(vendor/|node_modules/|\.git/|\.swp$|\.tmp$|~$)' \
|
||||
--format '%e %w%f' \
|
||||
"${ROOT_DIR}/cmd" "${ROOT_DIR}/internal" "${ROOT_DIR}/pkg" 2>/dev/null | \
|
||||
while read -r event changed_file; do
|
||||
# Rebuild on any .go file change OR any create/delete event (catches new files)
|
||||
if [[ "$changed_file" == *.go ]] || [[ "$event" =~ CREATE|DELETE|MOVED ]]; then
|
||||
echo ""
|
||||
echo "[hot-dev] 🔄 Change detected: $event $(basename "$changed_file")"
|
||||
echo "[hot-dev] Rebuilding backend..."
|
||||
|
||||
# Rebuild the binary
|
||||
if go build -o pulse ./cmd/pulse 2>&1 | grep -v "^#"; then
|
||||
echo "[hot-dev] ✓ Build successful, restarting backend..."
|
||||
# Rebuild the binary
|
||||
if go build -o pulse ./cmd/pulse 2>&1 | grep -v "^#"; then
|
||||
echo "[hot-dev] ✓ Build successful, restarting backend..."
|
||||
|
||||
# Find and kill old backend
|
||||
OLD_PID=$(pgrep -f "^\./pulse$" || true)
|
||||
if [[ -n "$OLD_PID" ]]; then
|
||||
kill "$OLD_PID" 2>/dev/null || true
|
||||
sleep 1
|
||||
if kill -0 "$OLD_PID" 2>/dev/null; then
|
||||
kill -9 "$OLD_PID" 2>/dev/null || true
|
||||
# Find and kill old backend
|
||||
OLD_PID=$(pgrep -f "^\./pulse$" || true)
|
||||
if [[ -n "$OLD_PID" ]]; then
|
||||
kill "$OLD_PID" 2>/dev/null || true
|
||||
sleep 1
|
||||
if kill -0 "$OLD_PID" 2>/dev/null; then
|
||||
kill -9 "$OLD_PID" 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start new backend with same environment
|
||||
FRONTEND_PORT=${PULSE_DEV_API_PORT} PORT=${PULSE_DEV_API_PORT} PULSE_DATA_DIR=${PULSE_DATA_DIR} ./pulse &
|
||||
NEW_PID=$!
|
||||
sleep 1
|
||||
# Start new backend with same environment
|
||||
FRONTEND_PORT=${PULSE_DEV_API_PORT} PORT=${PULSE_DEV_API_PORT} PULSE_DATA_DIR=${PULSE_DATA_DIR} ./pulse &
|
||||
NEW_PID=$!
|
||||
sleep 1
|
||||
|
||||
if kill -0 "$NEW_PID" 2>/dev/null; then
|
||||
echo "[hot-dev] ✓ Backend restarted (PID: $NEW_PID)"
|
||||
if kill -0 "$NEW_PID" 2>/dev/null; then
|
||||
echo "[hot-dev] ✓ Backend restarted (PID: $NEW_PID)"
|
||||
else
|
||||
echo "[hot-dev] ✗ Backend failed to start!"
|
||||
fi
|
||||
else
|
||||
echo "[hot-dev] ✗ Backend failed to start!"
|
||||
echo "[hot-dev] ✗ Build failed!"
|
||||
fi
|
||||
else
|
||||
echo "[hot-dev] ✗ Build failed!"
|
||||
echo "[hot-dev] Watching for changes..."
|
||||
fi
|
||||
echo "[hot-dev] Watching for changes..."
|
||||
fi
|
||||
done
|
||||
done
|
||||
else
|
||||
echo "[hot-dev] inotifywait not found. Auto-rebuild disabled."
|
||||
sleep 3600
|
||||
fi
|
||||
done
|
||||
) &
|
||||
WATCHER_PID=$!
|
||||
|
||||
Reference in New Issue
Block a user