From 70182d8bb7ace6f791f37a9c1abc8a88ccd8866b Mon Sep 17 00:00:00 2001 From: Cayden Schwechten Date: Sat, 31 Oct 2026 21:50:28 -0500 Subject: [PATCH] remove sign up prompts --- components/ProviderPicker.tsx | 112 +++------------------ components/WeatherApp.tsx | 10 +- components/forecast/DailyView.tsx | 2 +- components/ui/ChoiceChips.tsx | 17 +--- lib/weather/providers/index.ts | 17 ++-- lib/weather/providers/openmeteo.ts | 1 - lib/weather/providers/openweather/index.ts | 1 - lib/weather/providers/tomorrow.ts | 1 - lib/weather/providers/weatherapi.ts | 1 - lib/weather/types.ts | 7 +- 10 files changed, 31 insertions(+), 138 deletions(-) diff --git a/components/ProviderPicker.tsx b/components/ProviderPicker.tsx index 3c3f1a7..d643cb1 100644 --- a/components/ProviderPicker.tsx +++ b/components/ProviderPicker.tsx @@ -1,114 +1,34 @@ "use client"; -import { useState } from "react"; import { pixelLabel } from "@/lib/styles"; import type { ProviderId, ProviderInfo } from "@/lib/weather/types"; -import { Slot } from "./Slot"; import { ChoiceChips } from "./ui/ChoiceChips"; -const PROVIDER_KEY_HINTS: Record = { - openweather: { - envVar: "OPENWEATHER_API_KEY", - summary: "5-day forecast, reverse location naming, and 5 extra map layers (precip, clouds, temp, wind, pressure).", - }, - weatherapi: { - envVar: "WEATHERAPI_API_KEY", - summary: "3-day hourly & daily forecast plus worldwide weather alerts (instant key activation).", - }, - tomorrow: { - envVar: "TOMORROW_API_KEY", - summary: "5-day hourly & 6-day daily timelines (free tier: 25 calls/hr, 500/day).", - }, - openmeteo: { - envVar: null, - summary: "14-day daily & 7-day hourly forecast — free out of the box, no API key required.", - }, -}; - /** - * Provider choices. Each shows how many forecast days it delivers on the - * configured plan. Providers without an API key stay visible with an optional - * setup guide so adding free keys to `.env.local` is self-explanatory. + * Switcher between active weather data sources. + * Only configured providers are shown; hidden automatically if only one source is active. */ export function ProviderPicker({ providers, selected, onChange }: { providers: ProviderInfo[]; selected: ProviderId; onChange: (id: ProviderId) => void; }) { - const [showKeyGuide, setShowKeyGuide] = useState(false); - const missingProviders = providers.filter((p) => !p.ready); + if (providers.length <= 1) return null; return ( -
-
-
- Source - ({ - value: p.id, - label: p.label, - disabled: !p.ready, - note: p.ready ? `${p.forecastDays}d` : "Locked", - noteTone: p.ready ? "muted" : "subtle", - }))} - /> -
- - {missingProviders.length > 0 && ( - - )} -
- - {showKeyGuide && missingProviders.length > 0 && ( - -
-

- Optional free API keys -

-

- Add keys to .env.local and reload. -

-
- -
    - {missingProviders.map((p) => { - const info = PROVIDER_KEY_HINTS[p.id]; - return ( -
  • -
    -
    - {p.label} - {info.envVar && ( - {info.envVar} - )} -
    -

    {info.summary}

    -
    - - Get free key - -
  • - ); - })} -
-
- )} +
+ Source + ({ + value: p.id, + label: p.label, + note: `${p.forecastDays}d`, + }))} + />
); } diff --git a/components/WeatherApp.tsx b/components/WeatherApp.tsx index 9fe93a5..6546d0e 100644 --- a/components/WeatherApp.tsx +++ b/components/WeatherApp.tsx @@ -106,11 +106,9 @@ export default function WeatherApp() { fetchProviders() .then((list) => { setProviders(list); - // Prefer OpenWeather if its key was just added and user hasn't explicitly saved a choice; - // otherwise keep saved provider if ready, or fall back to the first ready source. - const savedIsReady = list.some((p) => p.id === saved.provider && p.ready); - const fallback = list.find((p) => p.ready)?.id ?? saved.provider; - setSettings({ ...saved, provider: savedIsReady ? saved.provider : fallback }); + const savedIsAvailable = list.some((p) => p.id === saved.provider); + const fallback = list[0]?.id ?? saved.provider; + setSettings({ ...saved, provider: savedIsAvailable ? saved.provider : fallback }); }) .catch(() => setSettings(saved)) .finally(() => setLoaded(true)); @@ -146,7 +144,7 @@ export default function WeatherApp() { const activeProvider = providers.find((p) => p.id === settings.provider); const reportProvider = providers.find((p) => p.id === report?.provider); - const hasOpenWeather = providers.some((p) => p.id === "openweather" && p.ready); + const hasOpenWeather = providers.some((p) => p.id === "openweather"); return (
- {providerLabel} gives {maxDaysOnPlan} days on this plan. Choose Open-Meteo for 14. + {providerLabel} provides a {maxDaysOnPlan}-day outlook. Switch to Open-Meteo above for 14 days.

)}
diff --git a/components/ui/ChoiceChips.tsx b/components/ui/ChoiceChips.tsx index 5df911a..b41f0e9 100644 --- a/components/ui/ChoiceChips.tsx +++ b/components/ui/ChoiceChips.tsx @@ -3,8 +3,7 @@ import { useId } from "react"; export interface Choice { value: T; label: string; - note?: string; // small extra text, e.g. "14d" or "No key" - noteTone?: "muted" | "subtle" | "warning"; + note?: string; // small extra text, e.g. "14d" disabled?: boolean; } @@ -54,19 +53,7 @@ export function ChoiceChips({ legend, choices, selected, onCha onChange={() => onChange(choice.value)} /> {choice.label} - {choice.note && ( - - {choice.note} - - )} + {choice.note && {choice.note}} ))} diff --git a/lib/weather/providers/index.ts b/lib/weather/providers/index.ts index c4809d9..27d2fd7 100644 --- a/lib/weather/providers/index.ts +++ b/lib/weather/providers/index.ts @@ -28,18 +28,13 @@ export function isReady(provider: WeatherProvider): boolean { return provider.envKey === null || Boolean(process.env[provider.envKey]?.trim()); } -/** Provider list for the browser — readiness and limits only, never the keys. - * Ready sources lead so the picker starts with working options out of the box. */ +/** Configured providers available to the browser — never exposes keys or unconfigured sources. */ export function listProviders(): ProviderInfo[] { - const all = DISPLAY_ORDER.map((id) => { - const provider = PROVIDERS[id]; - return { - id, + return DISPLAY_ORDER.map((id) => PROVIDERS[id]) + .filter(isReady) + .map((provider) => ({ + id: provider.id, label: provider.label, - ready: isReady(provider), - signupUrl: provider.signupUrl, ...provider.limits(), - }; - }); - return [...all.filter((p) => p.ready), ...all.filter((p) => !p.ready)]; + })); } diff --git a/lib/weather/providers/openmeteo.ts b/lib/weather/providers/openmeteo.ts index 824bf75..ec9f352 100644 --- a/lib/weather/providers/openmeteo.ts +++ b/lib/weather/providers/openmeteo.ts @@ -54,7 +54,6 @@ export const openMeteo: WeatherProvider = { id: "openmeteo", label: "Open-Meteo", envKey: null, - signupUrl: "https://open-meteo.com/", limits: () => ({ forecastDays: 14, hourlyStepHours: 1 }), async getForecast(lat, lon) { diff --git a/lib/weather/providers/openweather/index.ts b/lib/weather/providers/openweather/index.ts index c68b0c8..914bb91 100644 --- a/lib/weather/providers/openweather/index.ts +++ b/lib/weather/providers/openweather/index.ts @@ -16,7 +16,6 @@ export const openWeather: WeatherProvider = { id: "openweather", label: "OpenWeather", envKey: "OPENWEATHER_API_KEY", - signupUrl: "https://home.openweathermap.org/users/sign_up", limits: () => (usesOneCall() ? { forecastDays: 8, hourlyStepHours: 1 } : { forecastDays: 5, hourlyStepHours: 3 }), getForecast(lat, lon) { diff --git a/lib/weather/providers/tomorrow.ts b/lib/weather/providers/tomorrow.ts index ea30841..cfb2f50 100644 --- a/lib/weather/providers/tomorrow.ts +++ b/lib/weather/providers/tomorrow.ts @@ -74,7 +74,6 @@ export const tomorrowIo: WeatherProvider = { id: "tomorrow", label: "Tomorrow.io", envKey: "TOMORROW_API_KEY", - signupUrl: "https://app.tomorrow.io/signup", limits: () => ({ forecastDays: 6, hourlyStepHours: 1 }), async getForecast(lat, lon) { diff --git a/lib/weather/providers/weatherapi.ts b/lib/weather/providers/weatherapi.ts index c0b0593..2ebe894 100644 --- a/lib/weather/providers/weatherapi.ts +++ b/lib/weather/providers/weatherapi.ts @@ -110,7 +110,6 @@ export const weatherApi: WeatherProvider = { id: "weatherapi", label: "WeatherAPI", envKey: "WEATHERAPI_API_KEY", - signupUrl: "https://www.weatherapi.com/signup.aspx", // Set WEATHERAPI_PLAN=paid in .env.local if your plan includes 14 days. limits: () => ({ forecastDays: process.env.WEATHERAPI_PLAN === "paid" ? 14 : 3, hourlyStepHours: 1 }), diff --git a/lib/weather/types.ts b/lib/weather/types.ts index cf43425..c03cac8 100644 --- a/lib/weather/types.ts +++ b/lib/weather/types.ts @@ -121,18 +121,15 @@ export interface WeatherProvider { label: string; /** Name of the env var holding its key, or null if no key is needed. */ envKey: string | null; - signupUrl: string; - /** What this provider can deliver on the plan configured in .env.local. */ + /** Forecast horizon available on the configured tier. */ limits(): { forecastDays: number; hourlyStepHours: 1 | 3 }; getForecast(lat: number, lon: number): Promise; } -/** Safe-to-share provider info for the browser (never includes keys). */ +/** Configured provider metadata exposed to the browser (never includes keys). */ export interface ProviderInfo { id: ProviderId; label: string; - ready: boolean; - signupUrl: string; forecastDays: number; hourlyStepHours: 1 | 3; }