Fix milestone sharing previews and publisher recovery
This commit is contained in:
@@ -14,7 +14,10 @@ export default function SettingsPage() {
|
||||
const { fetchWithCsrf } = useCsrf();
|
||||
const [activeTab, setActiveTab] = useState<TabType>('profile');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [showPasswordModal, setShowPasswordModal] = useState(false);
|
||||
const [showPasswordModal, setShowPasswordModal] = useState(false);
|
||||
const [socialPromptsEnabled, setSocialPromptsEnabled] = useState(true);
|
||||
const [socialTestResetAvailable, setSocialTestResetAvailable] = useState(false);
|
||||
const [socialSaving, setSocialSaving] = useState(false);
|
||||
|
||||
// Profile states
|
||||
const [name, setName] = useState('');
|
||||
@@ -49,10 +52,17 @@ export default function SettingsPage() {
|
||||
|
||||
// Fetch usage stats from API
|
||||
const statsResponse = await fetch('/api/user/stats');
|
||||
if (statsResponse.ok) {
|
||||
const data = await statsResponse.json();
|
||||
setUsageStats(data);
|
||||
}
|
||||
if (statsResponse.ok) {
|
||||
const data = await statsResponse.json();
|
||||
setUsageStats(data);
|
||||
}
|
||||
|
||||
const socialResponse = await fetch('/api/social-milestones/preferences');
|
||||
if (socialResponse.ok) {
|
||||
const data = await socialResponse.json();
|
||||
setSocialPromptsEnabled(data.promptsEnabled !== false);
|
||||
setSocialTestResetAvailable(data.testResetAvailable === true);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to load user data:', e);
|
||||
}
|
||||
@@ -92,7 +102,25 @@ export default function SettingsPage() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const updateSocialPrompts = async (action: 'enable' | 'disable' | 'reset_test') => {
|
||||
setSocialSaving(true);
|
||||
try {
|
||||
const response = await fetchWithCsrf('/api/social-milestones/preferences', {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ action }),
|
||||
});
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.error || 'Could not update milestone prompts');
|
||||
setSocialPromptsEnabled(data.promptsEnabled !== false);
|
||||
showToast(action === 'reset_test' ? 'Milestone test reset. Open the dashboard to test it again.' : 'Milestone preference updated.', 'success');
|
||||
} catch (error) {
|
||||
showToast(error instanceof Error ? error.message : 'Could not update milestone prompts', 'error');
|
||||
} finally {
|
||||
setSocialSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleManageSubscription = async () => {
|
||||
setLoading(true);
|
||||
@@ -245,9 +273,32 @@ export default function SettingsPage() {
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Security */}
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Milestone sharing</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div className="max-w-xl">
|
||||
<h3 className="text-sm font-medium text-gray-900">Show scan milestone prompts</h3>
|
||||
<p className="mt-1 text-sm text-gray-500">Choose whether QR Master may ask you to share verified scan achievements. Nothing is published without your confirmation.</p>
|
||||
</div>
|
||||
<Button variant="outline" disabled={socialSaving} onClick={() => updateSocialPrompts(socialPromptsEnabled ? 'disable' : 'enable')}>
|
||||
{socialPromptsEnabled ? 'Turn off' : 'Turn on'}
|
||||
</Button>
|
||||
</div>
|
||||
{socialTestResetAvailable && <div className="border-t border-gray-100 pt-4">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<p className="text-sm text-gray-500">Test environment: reopen the latest milestone and clear its publishing state.</p>
|
||||
<Button variant="outline" disabled={socialSaving} onClick={() => updateSocialPrompts('reset_test')}>Reset milestone test</Button>
|
||||
</div>
|
||||
</div>}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Security */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Security</CardTitle>
|
||||
|
||||
Reference in New Issue
Block a user