Skip to content

Commit c2700b7

Browse files
committed
Simplify ClawWatch prereg client flow
1 parent 8006740 commit c2700b7

File tree

2 files changed

+27
-146
lines changed

2 files changed

+27
-146
lines changed

docs/app.js

Lines changed: 26 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
const SUPABASE_URL = 'https://kvezyhwbkvpyndkaemsw.supabase.co';
2-
const SUPABASE_ANON_KEY = 'sb_publishable_MWtbxI1_Gm_yYTSxHofq2Q_z0nGwItH';
3-
41
const preregisterButton = document.getElementById('google-preregister-button');
52
const signOutButton = document.getElementById('google-signout-button');
63
const statusText = document.getElementById('preregister-status');
74
const resultBanner = document.getElementById('preregister-result');
8-
const preregisterSection = document.getElementById('preregister');
95
const preregisterModal = document.getElementById('preregister-modal');
106
const preregisterModalClose = document.getElementById('preregister-modal-close');
117
const watchModelInputs = Array.from(document.querySelectorAll('input[name="watch-model"]'));
128
const feedbackInput = document.getElementById('preregister-feedback');
9+
1310
const PREREG_DRAFT_KEY = 'clawwatch-preregister-draft';
1411
const PREREG_PENDING_KEY = 'clawwatch-preregister-pending';
1512
const XFOR_PREREGISTER_START_URL = 'https://xfor.bot/api/v1/clawwatch/start';
1613

17-
let supabaseClient = null;
1814
let hasShownThankYou = false;
1915

2016
function showThankYouModal() {
@@ -53,7 +49,7 @@ function clearBanner() {
5349
function getFormState() {
5450
return {
5551
watchModels: watchModelInputs.filter((input) => input.checked).map((input) => input.value),
56-
feedback: feedbackInput?.value.trim() || ''
52+
feedback: feedbackInput?.value.trim() || '',
5753
};
5854
}
5955

@@ -89,35 +85,6 @@ function setPendingPreregistration(isPending) {
8985
} catch {}
9086
}
9187

92-
function hasPendingPreregistration() {
93-
try {
94-
return window.localStorage.getItem(PREREG_PENDING_KEY) === '1';
95-
} catch {
96-
return false;
97-
}
98-
}
99-
100-
function buildSharedAuthRedirectUrl() {
101-
const { watchModels, feedback } = getFormState();
102-
const params = new URLSearchParams({
103-
return_to: `${window.location.origin}${window.location.pathname}?preregister=complete#preregister`,
104-
watch_models: watchModels.join(','),
105-
feedback
106-
});
107-
return `${XFOR_PREREGISTER_START_URL}?${params.toString()}`;
108-
}
109-
110-
function applyFormState(metadata = {}) {
111-
const selected = Array.isArray(metadata.clawwatch_watch_models) ? metadata.clawwatch_watch_models : [];
112-
const selectedSet = new Set(selected);
113-
watchModelInputs.forEach((input) => {
114-
input.checked = selectedSet.has(input.value);
115-
});
116-
if (feedbackInput) {
117-
feedbackInput.value = typeof metadata.clawwatch_feedback === 'string' ? metadata.clawwatch_feedback : '';
118-
}
119-
}
120-
12188
function applyDraftState(draft = {}) {
12289
const selected = Array.isArray(draft.watchModels) ? draft.watchModels : [];
12390
const selectedSet = new Set(selected);
@@ -129,7 +96,7 @@ function applyDraftState(draft = {}) {
12996
}
13097
}
13198

132-
function renderSignedOut() {
99+
function renderReady() {
133100
clearBanner();
134101
if (statusText) {
135102
statusText.textContent = 'Sign in with Google and we will mark your account for the future install-ready ClawWatch release.';
@@ -157,148 +124,62 @@ function renderBusy(message) {
157124
}
158125
}
159126

160-
function renderRegistered(user) {
161-
const email = user.email || 'your Google account';
162-
if (statusText) {
163-
statusText.textContent = `You are registered for ClawWatch install updates as ${email}. You can update your watch details below any time.`;
164-
}
165-
if (preregisterButton) {
166-
preregisterButton.disabled = false;
167-
preregisterButton.innerHTML = '<span class="google-mark">✓</span><span>Update my interest details</span>';
168-
}
169-
if (signOutButton) {
170-
signOutButton.hidden = false;
171-
}
172-
setBanner("Thank you for your interest! We'll be back when the easy-to-install ClawWatch is here.", 'success');
173-
}
174-
175-
async function ensureInterest(user, { showModal = false, forceUpdate = false } = {}) {
176-
const metadata = user.user_metadata || {};
177-
if (metadata.clawwatch_interest_at && !forceUpdate) {
178-
applyFormState(metadata);
179-
renderRegistered(user);
180-
if (showModal) {
181-
showThankYouModal();
182-
}
183-
return;
184-
}
185-
renderRegistered(user);
186-
if (showModal) {
187-
showThankYouModal();
188-
}
127+
function buildSharedAuthRedirectUrl() {
128+
const { watchModels, feedback } = getFormState();
129+
const params = new URLSearchParams({
130+
return_to: `${window.location.origin}${window.location.pathname}?preregister=complete#preregister`,
131+
watch_models: watchModels.join(','),
132+
feedback,
133+
});
134+
return `${XFOR_PREREGISTER_START_URL}?${params.toString()}`;
189135
}
190136

191-
async function startGoogleSignIn() {
192-
clearBanner();
137+
function startGoogleSignIn() {
193138
renderBusy('Redirecting to Google sign-in…');
194139
track('clawwatch_preregister_start');
195140
saveDraftState();
196141
setPendingPreregistration(true);
197142
window.location.assign(buildSharedAuthRedirectUrl());
198143
}
199144

200-
async function handlePreregisterAction() {
201-
const { data } = await supabaseClient.auth.getSession();
202-
if (data.session?.user) {
203-
await ensureInterest(data.session.user, { showModal: true, forceUpdate: true });
204-
return;
205-
}
206-
await startGoogleSignIn();
207-
}
208-
209-
async function signOut() {
210-
const { error } = await supabaseClient.auth.signOut();
211-
if (error) {
212-
setBanner(error.message, 'error');
213-
return;
214-
}
215-
renderSignedOut();
216-
}
217-
218-
async function init() {
219-
const { createClient } = await import('https://esm.sh/@supabase/supabase-js@2');
220-
supabaseClient = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
221-
auth: {
222-
autoRefreshToken: true,
223-
detectSessionInUrl: true,
224-
persistSession: true,
225-
flowType: 'pkce'
226-
}
227-
});
228-
229-
preregisterButton?.addEventListener('click', handlePreregisterAction);
230-
signOutButton?.addEventListener('click', signOut);
145+
function init() {
146+
preregisterButton?.addEventListener('click', startGoogleSignIn);
231147
preregisterModalClose?.addEventListener('click', closeThankYouModal);
232148
preregisterModal?.addEventListener('click', (event) => {
233149
if (event.target?.dataset?.closeModal === 'true') {
234150
closeThankYouModal();
235151
}
236152
});
153+
237154
const savedDraft = loadDraftState();
238155
if (savedDraft) {
239156
applyDraftState(savedDraft);
240157
}
241158

242-
const { data, error } = await supabaseClient.auth.getSession();
243-
if (error) {
244-
setBanner(error.message, 'error');
245-
return;
246-
}
247-
248-
const preregComplete = new URLSearchParams(window.location.search).get('preregister') === 'complete';
249-
const pendingPreregistration = hasPendingPreregistration();
159+
const url = new URL(window.location.href);
160+
const preregStatus = url.searchParams.get('preregister');
250161

251-
if (data.session?.user) {
252-
applyFormState(data.session.user.user_metadata || {});
253-
if (preregComplete || pendingPreregistration) {
254-
if (savedDraft) {
255-
applyDraftState(savedDraft);
256-
}
257-
await ensureInterest(data.session.user, {
258-
showModal: true,
259-
forceUpdate: true
260-
});
261-
} else {
262-
renderRegistered(data.session.user);
263-
}
264-
} else if (preregComplete) {
162+
if (preregStatus === 'complete') {
265163
if (savedDraft) {
266164
applyDraftState(savedDraft);
267165
}
268166
clearDraftState();
269167
setPendingPreregistration(false);
270-
renderSignedOut();
168+
renderReady();
271169
setBanner("Thank you for your interest! We'll be back when the easy-to-install ClawWatch is here.", 'success');
272170
showThankYouModal();
171+
} else if (preregStatus === 'error') {
172+
renderReady();
173+
setPendingPreregistration(false);
174+
setBanner('Google sign-in finished, but ClawWatch preregistration was not stored. Please try again.', 'error');
273175
} else {
274-
renderSignedOut();
176+
renderReady();
275177
}
276178

277-
if (preregComplete) {
179+
if (preregStatus) {
278180
const cleanUrl = `${window.location.origin}${window.location.pathname}${window.location.hash || ''}`;
279181
window.history.replaceState({}, document.title, cleanUrl);
280182
}
281-
282-
supabaseClient.auth.onAuthStateChange(async (event, session) => {
283-
if (event === 'SIGNED_IN' && session?.user) {
284-
applyFormState(session.user.user_metadata || {});
285-
if (hasPendingPreregistration()) {
286-
const draft = loadDraftState();
287-
if (draft) {
288-
applyDraftState(draft);
289-
}
290-
}
291-
await ensureInterest(session.user, { showModal: true, forceUpdate: hasPendingPreregistration() });
292-
return;
293-
}
294-
295-
if (event === 'SIGNED_OUT') {
296-
renderSignedOut();
297-
}
298-
});
299183
}
300184

301-
init().catch((error) => {
302-
renderSignedOut();
303-
setBanner(error.message || 'Failed to initialize preregistration.', 'error');
304-
});
185+
init();

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,6 @@ <h2 id="preregister-modal-title">Thank you for your interest!</h2>
325325
<button id="preregister-modal-close" class="cta-primary modal-close-button" type="button" onclick="document.getElementById('preregister-modal').hidden = true; document.body.style.overflow = '';">Close</button>
326326
</div>
327327
</div>
328-
<script type="module" src="/app.js"></script>
328+
<script type="module" src="/app.js?v=20260310b"></script>
329329
</body>
330330
</html>

0 commit comments

Comments
 (0)