2026-03-06 20:14:50 +07:00
|
|
|
import { Link } from 'react-router-dom';
|
feat(editor): translate Save / Share / LoginPrompt modals (Editor block 3)
The three modal dialogs that fire during the editor's routine save +
share + auth-required flows are now fully localised across all 9
locales.
LoginPromptModal
- Title, body, and the three buttons (Sign in / Create account /
Cancel). Sign in / Sign up Links use localize() so a Spanish
reader prompted to log in lands at /es/login rather than dropping
back to English.
SaveProjectModal
- Title (toggles between Save / Update), name + description fields
with placeholders, save button (toggles between Save / Update /
Saving…), Cancel button.
- Visibility toggle: Public / Private label + hint copy under the
icon.
- All four error paths now go through t() with a {{status}}
interpolation for the generic HTTP failure message.
ShareModal
- Title, public/private label + hint pair, "Make private" /
"Make public" toggle, Copy button, the warning shown when the
project is private, and the Close button.
Hand-curated translations for all 8 non-English locales. Status
codes (403) and shortcut markers preserved.
2026-05-09 13:12:52 +07:00
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
import { useLocalizedHref } from '../../i18n/useLocalizedNavigate';
|
2026-03-06 20:14:50 +07:00
|
|
|
|
|
|
|
|
interface LoginPromptModalProps {
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
}
|
|
|
|
|
|
feat(editor): translate Save / Share / LoginPrompt modals (Editor block 3)
The three modal dialogs that fire during the editor's routine save +
share + auth-required flows are now fully localised across all 9
locales.
LoginPromptModal
- Title, body, and the three buttons (Sign in / Create account /
Cancel). Sign in / Sign up Links use localize() so a Spanish
reader prompted to log in lands at /es/login rather than dropping
back to English.
SaveProjectModal
- Title (toggles between Save / Update), name + description fields
with placeholders, save button (toggles between Save / Update /
Saving…), Cancel button.
- Visibility toggle: Public / Private label + hint copy under the
icon.
- All four error paths now go through t() with a {{status}}
interpolation for the generic HTTP failure message.
ShareModal
- Title, public/private label + hint pair, "Make private" /
"Make public" toggle, Copy button, the warning shown when the
project is private, and the Close button.
Hand-curated translations for all 8 non-English locales. Status
codes (403) and shortcut markers preserved.
2026-05-09 13:12:52 +07:00
|
|
|
export const LoginPromptModal: React.FC<LoginPromptModalProps> = ({ onClose }) => {
|
|
|
|
|
const { t } = useTranslation();
|
|
|
|
|
const localize = useLocalizedHref();
|
|
|
|
|
return (
|
|
|
|
|
<div style={styles.overlay} onClick={onClose}>
|
|
|
|
|
<div style={styles.modal} onClick={(e) => e.stopPropagation()}>
|
|
|
|
|
<h2 style={styles.title}>{t('editor.loginPrompt.title')}</h2>
|
|
|
|
|
<p style={styles.body}>{t('editor.loginPrompt.body')}</p>
|
|
|
|
|
<div style={styles.actions}>
|
|
|
|
|
<Link to={localize('/login')} style={styles.primaryBtn}>
|
|
|
|
|
{t('header.auth.signIn')}
|
|
|
|
|
</Link>
|
|
|
|
|
<Link to={localize('/register')} style={styles.secondaryBtn}>
|
|
|
|
|
{t('editor.loginPrompt.createAccount')}
|
|
|
|
|
</Link>
|
|
|
|
|
<button onClick={onClose} style={styles.cancelBtn}>
|
|
|
|
|
{t('editor.loginPrompt.cancel')}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
2026-03-06 20:14:50 +07:00
|
|
|
</div>
|
|
|
|
|
</div>
|
feat(editor): translate Save / Share / LoginPrompt modals (Editor block 3)
The three modal dialogs that fire during the editor's routine save +
share + auth-required flows are now fully localised across all 9
locales.
LoginPromptModal
- Title, body, and the three buttons (Sign in / Create account /
Cancel). Sign in / Sign up Links use localize() so a Spanish
reader prompted to log in lands at /es/login rather than dropping
back to English.
SaveProjectModal
- Title (toggles between Save / Update), name + description fields
with placeholders, save button (toggles between Save / Update /
Saving…), Cancel button.
- Visibility toggle: Public / Private label + hint copy under the
icon.
- All four error paths now go through t() with a {{status}}
interpolation for the generic HTTP failure message.
ShareModal
- Title, public/private label + hint pair, "Make private" /
"Make public" toggle, Copy button, the warning shown when the
project is private, and the Close button.
Hand-curated translations for all 8 non-English locales. Status
codes (403) and shortcut markers preserved.
2026-05-09 13:12:52 +07:00
|
|
|
);
|
|
|
|
|
};
|
2026-03-06 20:14:50 +07:00
|
|
|
|
|
|
|
|
const styles: Record<string, React.CSSProperties> = {
|
2026-04-22 02:45:45 +07:00
|
|
|
overlay: {
|
|
|
|
|
position: 'fixed',
|
|
|
|
|
inset: 0,
|
|
|
|
|
background: 'rgba(0,0,0,.6)',
|
|
|
|
|
display: 'flex',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
zIndex: 1000,
|
|
|
|
|
},
|
|
|
|
|
modal: {
|
|
|
|
|
background: '#252526',
|
|
|
|
|
border: '1px solid #3c3c3c',
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
padding: '1.75rem',
|
|
|
|
|
width: 340,
|
|
|
|
|
display: 'flex',
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
gap: 14,
|
|
|
|
|
},
|
2026-03-06 20:14:50 +07:00
|
|
|
title: { color: '#ccc', margin: 0, fontSize: 18, fontWeight: 600 },
|
|
|
|
|
body: { color: '#9d9d9d', margin: 0, fontSize: 14 },
|
|
|
|
|
actions: { display: 'flex', flexDirection: 'column', gap: 8 },
|
2026-04-22 02:45:45 +07:00
|
|
|
primaryBtn: {
|
|
|
|
|
background: '#0e639c',
|
|
|
|
|
color: '#fff',
|
|
|
|
|
padding: '9px',
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
textDecoration: 'none',
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
fontWeight: 500,
|
|
|
|
|
},
|
|
|
|
|
secondaryBtn: {
|
|
|
|
|
background: 'transparent',
|
|
|
|
|
color: '#ccc',
|
|
|
|
|
padding: '9px',
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
textDecoration: 'none',
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
border: '1px solid #555',
|
|
|
|
|
},
|
|
|
|
|
cancelBtn: {
|
|
|
|
|
background: 'transparent',
|
|
|
|
|
border: 'none',
|
|
|
|
|
color: '#666',
|
|
|
|
|
padding: '6px',
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
fontSize: 13,
|
|
|
|
|
},
|
2026-03-06 20:14:50 +07:00
|
|
|
};
|