Skip to content

Commit 9549ee1

Browse files
committed
Collect watch details for ClawWatch preregistration
1 parent fc6afb6 commit 9549ee1

File tree

3 files changed

+113
-9
lines changed

3 files changed

+113
-9
lines changed

docs/app.js

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const resultBanner = document.getElementById('preregister-result');
88
const preregisterSection = document.getElementById('preregister');
99
const preregisterModal = document.getElementById('preregister-modal');
1010
const preregisterModalClose = document.getElementById('preregister-modal-close');
11+
const watchModelInputs = Array.from(document.querySelectorAll('input[name="watch-model"]'));
12+
const feedbackInput = document.getElementById('preregister-feedback');
1113

1214
let supabaseClient = null;
1315
let hasShownThankYou = false;
@@ -45,6 +47,24 @@ function clearBanner() {
4547
delete resultBanner.dataset.tone;
4648
}
4749

50+
function getFormState() {
51+
return {
52+
watchModels: watchModelInputs.filter((input) => input.checked).map((input) => input.value),
53+
feedback: feedbackInput?.value.trim() || ''
54+
};
55+
}
56+
57+
function applyFormState(metadata = {}) {
58+
const selected = Array.isArray(metadata.clawwatch_watch_models) ? metadata.clawwatch_watch_models : [];
59+
const selectedSet = new Set(selected);
60+
watchModelInputs.forEach((input) => {
61+
input.checked = selectedSet.has(input.value);
62+
});
63+
if (feedbackInput) {
64+
feedbackInput.value = typeof metadata.clawwatch_feedback === 'string' ? metadata.clawwatch_feedback : '';
65+
}
66+
}
67+
4868
function renderSignedOut() {
4969
clearBanner();
5070
if (statusText) {
@@ -76,36 +96,41 @@ function renderBusy(message) {
7696
function renderRegistered(user) {
7797
const email = user.email || 'your Google account';
7898
if (statusText) {
79-
statusText.textContent = `You are registered for ClawWatch install updates as ${email}.`;
99+
statusText.textContent = `You are registered for ClawWatch install updates as ${email}. You can update your watch details below any time.`;
80100
}
81101
if (preregisterButton) {
82-
preregisterButton.disabled = true;
83-
preregisterButton.innerHTML = '<span class="google-mark">✓</span><span>You are on the list</span>';
102+
preregisterButton.disabled = false;
103+
preregisterButton.innerHTML = '<span class="google-mark">✓</span><span>Update my interest details</span>';
84104
}
85105
if (signOutButton) {
86106
signOutButton.hidden = false;
87107
}
88108
setBanner("Thank you for your interest! We'll be back when the easy-to-install ClawWatch is here.", 'success');
89109
}
90110

91-
async function ensureInterest(user, { showModal = false } = {}) {
111+
async function ensureInterest(user, { showModal = false, forceUpdate = false } = {}) {
92112
const metadata = user.user_metadata || {};
93-
if (metadata.clawwatch_interest_at) {
113+
if (metadata.clawwatch_interest_at && !forceUpdate) {
114+
applyFormState(metadata);
94115
renderRegistered(user);
95116
if (showModal) {
96117
showThankYouModal();
97118
}
98119
return;
99120
}
100121

101-
renderBusy('Saving your ClawWatch preregistration…');
122+
const { watchModels, feedback } = getFormState();
123+
renderBusy(metadata.clawwatch_interest_at ? 'Updating your ClawWatch details…' : 'Saving your ClawWatch preregistration…');
102124

103125
const { data, error } = await supabaseClient.auth.updateUser({
104126
data: {
105127
clawwatch_interest: true,
106-
clawwatch_interest_at: new Date().toISOString(),
128+
clawwatch_interest_at: metadata.clawwatch_interest_at || new Date().toISOString(),
107129
clawwatch_interest_source: window.location.host,
108-
clawwatch_interest_status: 'preregistered'
130+
clawwatch_interest_status: 'preregistered',
131+
clawwatch_watch_models: watchModels,
132+
clawwatch_has_watch: watchModels.length > 0 && !watchModels.includes('no-watch-yet'),
133+
clawwatch_feedback: feedback
109134
}
110135
});
111136

@@ -122,6 +147,7 @@ async function ensureInterest(user, { showModal = false } = {}) {
122147
}
123148

124149
track('clawwatch_preregister_complete');
150+
applyFormState(data.user?.user_metadata || metadata);
125151
renderRegistered(data.user || user);
126152
if (showModal) {
127153
showThankYouModal();
@@ -182,6 +208,15 @@ async function startGoogleSignIn() {
182208
}, 500);
183209
}
184210

211+
async function handlePreregisterAction() {
212+
const { data } = await supabaseClient.auth.getSession();
213+
if (data.session?.user) {
214+
await ensureInterest(data.session.user, { showModal: true, forceUpdate: true });
215+
return;
216+
}
217+
await startGoogleSignIn();
218+
}
219+
185220
async function signOut() {
186221
const { error } = await supabaseClient.auth.signOut();
187222
if (error) {
@@ -202,7 +237,7 @@ async function init() {
202237
}
203238
});
204239

205-
preregisterButton?.addEventListener('click', startGoogleSignIn);
240+
preregisterButton?.addEventListener('click', handlePreregisterAction);
206241
signOutButton?.addEventListener('click', signOut);
207242
preregisterModalClose?.addEventListener('click', closeThankYouModal);
208243
preregisterModal?.addEventListener('click', (event) => {
@@ -233,6 +268,7 @@ async function init() {
233268
}
234269

235270
if (data.session?.user) {
271+
applyFormState(data.session.user.user_metadata || {});
236272
await ensureInterest(data.session.user, { showModal: preregComplete });
237273
} else {
238274
renderSignedOut();
@@ -248,6 +284,7 @@ async function init() {
248284

249285
supabaseClient.auth.onAuthStateChange(async (event, session) => {
250286
if (event === 'SIGNED_IN' && session?.user) {
287+
applyFormState(session.user.user_metadata || {});
251288
await ensureInterest(session.user, { showModal: true });
252289
return;
253290
}

docs/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ <h2>Signal that you want one-tap ClawWatch installs</h2>
142142
<h3>Open source now. Install-button version next.</h3>
143143
<p>ClawWatch is already real and open source, but getting it onto a fresh watch still means compiling the app and using developer mode.</p>
144144
<p>We are building the version every watch owner can install with a button. Tap below to signal your interest and we will let you know when it is ready.</p>
145+
<div class="preregister-form">
146+
<fieldset class="preregister-fieldset">
147+
<legend>Do you already have a watch? Select all that apply.</legend>
148+
<label class="preregister-check"><input type="checkbox" name="watch-model" value="galaxy-watch"> <span>Galaxy Watch</span></label>
149+
<label class="preregister-check"><input type="checkbox" name="watch-model" value="pixel-watch"> <span>Pixel Watch</span></label>
150+
<label class="preregister-check"><input type="checkbox" name="watch-model" value="apple-watch"> <span>Apple Watch</span></label>
151+
<label class="preregister-check"><input type="checkbox" name="watch-model" value="garmin"> <span>Garmin</span></label>
152+
<label class="preregister-check"><input type="checkbox" name="watch-model" value="other-wear-os"> <span>Other Wear OS watch</span></label>
153+
<label class="preregister-check"><input type="checkbox" name="watch-model" value="no-watch-yet"> <span>No watch yet</span></label>
154+
</fieldset>
155+
<label class="preregister-feedback-label" for="preregister-feedback">Anything you want from ClawWatch?</label>
156+
<textarea id="preregister-feedback" class="preregister-feedback" rows="4" placeholder="Tell us what watch you have, what you want to do with ClawWatch, or any feedback for the install-ready version."></textarea>
157+
</div>
145158
<p id="preregister-status" class="preregister-status">
146159
Sign in with Google and we will mark your account for the future install-ready ClawWatch release.
147160
</p>

docs/styles.css

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,60 @@ body.clawwatch-body {
457457
line-height: 1.75;
458458
}
459459

460+
.preregister-form {
461+
display: grid;
462+
gap: 16px;
463+
margin: 20px 0 18px;
464+
}
465+
466+
.preregister-fieldset {
467+
margin: 0;
468+
padding: 16px;
469+
border-radius: 18px;
470+
border: 1px solid rgba(255,255,255,0.1);
471+
background: rgba(255,255,255,0.03);
472+
}
473+
474+
.preregister-fieldset legend,
475+
.preregister-feedback-label {
476+
color: #eef4ff;
477+
font-weight: 700;
478+
font-size: 0.98rem;
479+
}
480+
481+
.preregister-fieldset legend {
482+
padding: 0 8px;
483+
}
484+
485+
.preregister-check {
486+
display: flex;
487+
align-items: center;
488+
gap: 10px;
489+
margin-top: 12px;
490+
color: var(--muted);
491+
}
492+
493+
.preregister-check input {
494+
accent-color: #f28c1b;
495+
}
496+
497+
.preregister-feedback {
498+
width: 100%;
499+
min-height: 110px;
500+
padding: 14px 16px;
501+
border-radius: 16px;
502+
border: 1px solid rgba(255,255,255,0.12);
503+
background: rgba(255,255,255,0.04);
504+
color: var(--text);
505+
font: inherit;
506+
line-height: 1.6;
507+
resize: vertical;
508+
}
509+
510+
.preregister-feedback::placeholder {
511+
color: rgba(162, 172, 192, 0.78);
512+
}
513+
460514
.preregister-points {
461515
display: flex;
462516
flex-wrap: wrap;

0 commit comments

Comments
 (0)