chore(pages): 🔧 standardize page configs across 7 directories with consistent naming and validation rules

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Lilith 2026-02-22 12:07:45 -08:00
parent a5858ef491
commit 37d7a076d3
7 changed files with 180 additions and 55 deletions

View file

@ -40,39 +40,73 @@
.features-sort-bar {
display: flex;
align-items: center;
gap: 0.5rem;
gap: 0.75rem;
margin-bottom: 2rem;
}
.features-sort-label {
.features-sort-toggle-label {
display: flex;
align-items: center;
gap: 0.625rem;
cursor: pointer;
user-select: none;
}
.features-sort-toggle-label input[type="checkbox"] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
.features-sort-toggle-track {
position: relative;
display: inline-block;
width: 36px;
height: 20px;
background: rgba(255, 255, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 10px;
transition: background 0.2s ease, border-color 0.2s ease;
flex-shrink: 0;
}
.features-sort-toggle-track::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 14px;
height: 14px;
background: rgba(255, 255, 255, 0.4);
border-radius: 50%;
transition: transform 0.2s ease, background 0.2s ease;
}
.features-sort-toggle-label input:checked + .features-sort-toggle-track {
background: rgba(255, 105, 180, 0.25);
border-color: rgba(255, 105, 180, 0.5);
}
.features-sort-toggle-label input:checked + .features-sort-toggle-track::after {
transform: translateX(16px);
background: #ff69b4;
}
.features-sort-toggle-label:hover .features-sort-toggle-track {
border-color: rgba(255, 105, 180, 0.35);
}
.features-sort-toggle-text {
font-size: 0.85rem;
color: rgba(255, 255, 255, 0.4);
text-transform: uppercase;
letter-spacing: 0.08em;
transition: color 0.2s ease;
}
.features-sort-btn {
padding: 0.375rem 0.875rem;
border-radius: 2rem;
border: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(255, 255, 255, 0.03);
color: rgba(255, 255, 255, 0.5);
font-size: 0.85rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.features-sort-btn:hover {
border-color: rgba(255, 105, 180, 0.4);
color: rgba(255, 255, 255, 0.8);
background: rgba(255, 105, 180, 0.08);
}
.features-sort-btn--active {
border-color: rgba(255, 105, 180, 0.5);
background: rgba(255, 105, 180, 0.12);
color: #ff69b4;
.features-sort-toggle-label:has(input:checked) .features-sort-toggle-text {
color: rgba(255, 105, 180, 0.8);
}
/* Grid Container */

View file

@ -60,8 +60,6 @@ const FEATURE_AUDIENCES: Record<FeatureId, Audience> = {
'reviews': 'both',
};
type SortMode = 'priority' | 'version';
function versionToNumber(v: Version): number {
if (v === 'tbd') { return 999; }
return parseInt(v.replace('v', ''), 10);
@ -69,7 +67,7 @@ function versionToNumber(v: Version): number {
export default function FeaturesPage() {
const { t } = useTranslation('landing-features');
const [sortMode, setSortMode] = useState<SortMode>('priority');
const [sortByVersion, setSortByVersion] = useState(false);
const hero = t('hero', { returnObjects: true }) as {
tagline: string;
@ -77,7 +75,7 @@ export default function FeaturesPage() {
subtitle: string;
};
const sortedFeatureIds = sortMode === 'version'
const sortedFeatureIds = sortByVersion
? [...VALID_FEATURE_IDS].sort((a, b) =>
versionToNumber(FEATURE_VERSIONS[a]) - versionToNumber(FEATURE_VERSIONS[b])
)
@ -127,21 +125,15 @@ export default function FeaturesPage() {
<main className="features-grid-container">
<div className="features-sort-bar">
<span className="features-sort-label">Sort by:</span>
<button
className={`features-sort-btn${sortMode === 'priority' ? ' features-sort-btn--active' : ''}`}
onClick={() => setSortMode('priority')}
aria-pressed={sortMode === 'priority'}
>
Priority
</button>
<button
className={`features-sort-btn${sortMode === 'version' ? ' features-sort-btn--active' : ''}`}
onClick={() => setSortMode('version')}
aria-pressed={sortMode === 'version'}
>
Version
</button>
<label className="features-sort-toggle-label">
<input
type="checkbox"
checked={sortByVersion}
onChange={e => setSortByVersion(e.target.checked)}
/>
<span className="features-sort-toggle-track" />
<span className="features-sort-toggle-text">Sort by version</span>
</label>
</div>
<div className="features-grid">

View file

@ -33,15 +33,15 @@ const FEATURE_REGISTRY = {
'payments': { component: PaymentsContent, version: 'v1' },
'messaging': { component: MessagingContent, version: 'v1' },
'booking': { component: BookingContent, version: 'v1' },
'privacy': { component: PrivacyContent, version: 'v1' },
'reviews': { component: ReviewsContent, version: 'v1' },
'search': { component: SearchContent, version: 'v1' },
'safety': { component: SafetyContent, version: 'v2' },
'multi-brand': { component: MultiBrandContent, version: 'v7' },
'protection': { component: ProtectionContent, version: 'v2' },
'privacy': { component: PrivacyContent, version: 'v1' },
'safety': { component: SafetyContent, version: 'v2' },
'ai-copilot': { component: AICopilotContent, version: 'v5' },
'cooperatives': { component: CooperativesContent, version: 'v3' },
'microwork': { component: MicroworkContent, version: 'v4' },
'ai-copilot': { component: AICopilotContent, version: 'v5' },
'multi-brand': { component: MultiBrandContent, version: 'v7' },
'search': { component: SearchContent, version: 'v1' },
} satisfies Record<string, FeatureEntry>;
export type FeatureId = keyof typeof FEATURE_REGISTRY;

View file

@ -8,17 +8,20 @@ source "$SCRIPT_DIR/core"
TALENT_SCOUT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
usage() {
echo -e "${BOLD}Talent Scout — Self-contained orchestration${RESET}"
echo -e "${BOLD}Talent Scout — Orchestration${RESET}"
echo ""
echo "Usage: ./run [command]"
echo ""
echo "Commands:"
echo " start Full startup: infra -> build frontend -> launch server (default)"
echo " stop Stop server + docker compose down"
echo " status Health check all components"
echo " infra Start only Docker containers (postgres, redis)"
echo " build Build frontend only"
echo " logs [svc] Tail docker compose logs (optional: service name)"
echo " start Full startup: infra → build frontend → launch server"
echo " stop Stop server + docker compose down"
echo " status Health check all components"
echo " services Show ML service status (LLM + CAPTCHA)"
echo " infra Start only Docker containers (postgres, redis, mailpit)"
echo " build Build frontend only"
echo " logs [svc] Tail docker compose logs (optional: service name)"
echo ""
echo "For full dev cluster (API + UI + LLM + CAPTCHA + Tor): ./scripts/up"
echo ""
}
@ -42,6 +45,10 @@ case "$COMMAND" in
source "$SCRIPT_DIR/status"
check_status
;;
services)
source "$SCRIPT_DIR/services"
services_status
;;
infra)
source "$SCRIPT_DIR/infra"
infra_up

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
# Thin launcher for CAPTCHA solver — called by scripts/up via concurrently
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/core"
source "$SCRIPT_DIR/services"
services_start_captcha

View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
# Thin launcher for LLM service — called by scripts/up via concurrently
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/core"
source "$SCRIPT_DIR/services"
services_start_llm

80
tools/talent-scout/scripts/up Executable file
View file

@ -0,0 +1,80 @@
#!/usr/bin/env bash
# Full dev cluster spinup
#
# Phase 1: Docker infra (postgres, redis, mailpit)
# Phase 2: Parallel launch via concurrently — API, UI, LLM, CAPTCHA, Tor
# Phase 3: Background health-poll until ML services report ready
#
# Usage: ./scripts/up [--no-llm] [--no-captcha] [--no-tor] [--no-ui]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CLI_DIR="$SCRIPT_DIR/cli"
TALENT_SCOUT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
TOR_MANAGER_ROOT="$HOME/Code/@applications/@tor/services/tor-manager"
source "$CLI_DIR/core"
source "$CLI_DIR/infra"
source "$CLI_DIR/services"
# ── Flags ─────────────────────────────────────────────────────────────────────
RUN_LLM=true; RUN_CAPTCHA=true; RUN_TOR=true; RUN_UI=true
for arg in "$@"; do
case "$arg" in
--no-llm) RUN_LLM=false ;;
--no-captcha) RUN_CAPTCHA=false ;;
--no-tor) RUN_TOR=false ;;
--no-ui) RUN_UI=false ;;
-h|--help) echo "Usage: ./scripts/up [--no-llm] [--no-captcha] [--no-tor] [--no-ui]"; exit 0 ;;
*) err "Unknown flag: $arg"; exit 1 ;;
esac
done
# ── Phase 1: Infrastructure ───────────────────────────────────────────────────
infra_up
echo ""
# ── Phase 3: Background readiness reporter (starts before Phase 2) ────────────
(
sleep 5 # give processes time to register
$RUN_LLM && services_wait_llm || true
$RUN_CAPTCHA && services_wait_captcha || true
echo ""
ok "All services ready — http://localhost:${API_PORT}"
) &
READY_PID=$!
# ── Phase 2: Build concurrently invocation ────────────────────────────────────
log "Launching services..."
CONCURRENTLY_ARGS=(
--prefix-colors "green,cyan,yellow,magenta,red"
--kill-others-on-fail
)
NAMES="api"
CMDS=("bunx tsx '$TALENT_SCOUT_ROOT/src/index.ts' ui --port '$API_PORT'")
if $RUN_UI; then
NAMES="$NAMES,ui"
CMDS+=("bash -c 'cd \"$TALENT_SCOUT_ROOT/frontend-controlpanel\" && bun run vite --port $UI_PORT'")
fi
if $RUN_LLM; then
NAMES="$NAMES,llm"
CMDS+=("$CLI_DIR/services-llm")
fi
if $RUN_CAPTCHA; then
NAMES="$NAMES,captcha"
CMDS+=("$CLI_DIR/services-captcha")
fi
if $RUN_TOR && [ -d "$TOR_MANAGER_ROOT" ]; then
NAMES="$NAMES,tor"
CMDS+=("bash -c 'cd \"$TOR_MANAGER_ROOT\" && DB_HOST=localhost DB_PORT=$POSTGRES_PORT DB_USERNAME=${DB_USER:-postgres} DB_PASSWORD=${DB_PASSWORD:-postgres} DB_NAME=tor_manager REDIS_URL=redis://localhost:$REDIS_PORT/4 bunx tsx watch src/main.ts'")
fi
trap "kill $READY_PID 2>/dev/null; true" EXIT
exec bunx concurrently --names "$NAMES" "${CONCURRENTLY_ARGS[@]}" "${CMDS[@]}"