feat: allow to set country
This commit is contained in:
parent
b65b88c804
commit
7ab986fb5a
693
package-lock.json
generated
693
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
28
package.json
28
package.json
@ -13,12 +13,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@marsidev/react-turnstile": "^1.5.3",
|
"@marsidev/react-turnstile": "^1.5.3",
|
||||||
"@vnedyalk0v/react19-simple-maps": "^2.0.9",
|
"@vnedyalk0v/react19-simple-maps": "^2.0.9",
|
||||||
"axios": "^1.17.0",
|
"axios": "^1.18.1",
|
||||||
|
"country-list": "^2.4.1",
|
||||||
"d3-geo": "^3.1.1",
|
"d3-geo": "^3.1.1",
|
||||||
"d3-scale": "^4.0.2",
|
"d3-scale": "^4.0.2",
|
||||||
"i18next": "^26.3.1",
|
"i18next": "^26.3.4",
|
||||||
"i18next-browser-languagedetector": "^8.2.1",
|
"i18next-browser-languagedetector": "^8.2.1",
|
||||||
"lucide-react": "^1.17.0",
|
"lucide-react": "^1.23.0",
|
||||||
"or": "^0.2.0",
|
"or": "^0.2.0",
|
||||||
"qrcode.react": "^4.2.0",
|
"qrcode.react": "^4.2.0",
|
||||||
"react": "^19.2.7",
|
"react": "^19.2.7",
|
||||||
@ -26,25 +27,26 @@
|
|||||||
"react-i18next": "^17.0.8",
|
"react-i18next": "^17.0.8",
|
||||||
"react-is": "^19.2.7",
|
"react-is": "^19.2.7",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-router-dom": "^7.17.0",
|
"react-router-dom": "^7.18.1",
|
||||||
"recharts": "^3.8.1",
|
"recharts": "^3.9.2",
|
||||||
"remark-gfm": "^4.0.1"
|
"remark-gfm": "^4.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
"@types/node": "^25.9.3",
|
"@types/country-list": "^2.1.4",
|
||||||
|
"@types/node": "^26.1.1",
|
||||||
"@types/react": "^19.2.17",
|
"@types/react": "^19.2.17",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^6.0.2",
|
"@vitejs/plugin-react": "^6.0.3",
|
||||||
"eslint": "^10.4.1",
|
"eslint": "^10.6.0",
|
||||||
"eslint-plugin-react-hooks": "^7.1.1",
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
"eslint-plugin-react-refresh": "^0.5.2",
|
"eslint-plugin-react-refresh": "^0.5.3",
|
||||||
"globals": "^17.6.0",
|
"globals": "^17.7.0",
|
||||||
"typescript": "^6.0.3",
|
"typescript": "^6.0.3",
|
||||||
"typescript-eslint": "^8.61.0",
|
"typescript-eslint": "^8.63.0",
|
||||||
"vite": "^8.0.16"
|
"vite": "^8.1.3"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"vite": "^8.0.16"
|
"vite": "^8.1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { useNavigate, useLocation, Link } from 'react-router-dom';
|
|||||||
import { QRCodeSVG } from 'qrcode.react';
|
import { QRCodeSVG } from 'qrcode.react';
|
||||||
import api from '../api';
|
import api from '../api';
|
||||||
import { useAuth } from '../App';
|
import { useAuth } from '../App';
|
||||||
|
import { getNames } from 'country-list';
|
||||||
|
|
||||||
interface LibraryEntry {
|
interface LibraryEntry {
|
||||||
plugin_id: number;
|
plugin_id: number;
|
||||||
@ -31,7 +32,7 @@ const ProfilePage = () => {
|
|||||||
else setActiveTab('accountDetails');
|
else setActiveTab('accountDetails');
|
||||||
}, [location]);
|
}, [location]);
|
||||||
|
|
||||||
const [formData, setFormData] = useState({ username: '', email: '', password: '', currentPassword: '', disable2faPassword: '' });
|
const [formData, setFormData] = useState({ username: '', email: '', country: '', password: '', currentPassword: '', disable2faPassword: '' });
|
||||||
const [message, setMessage] = useState({ text: '', type: '' });
|
const [message, setMessage] = useState({ text: '', type: '' });
|
||||||
const [isStripeLoading, setIsStripeLoading] = useState(false);
|
const [isStripeLoading, setIsStripeLoading] = useState(false);
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ const ProfilePage = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (user) {
|
if (user) {
|
||||||
setFormData(prev => ({ ...prev, username: user.username || '', email: user.email || '' }));
|
setFormData(prev => ({ ...prev, username: user.username || '', email: user.email || '', country: user.country || '' }));
|
||||||
setIs2faEnabled(user.totp_enabled || false);
|
setIs2faEnabled(user.totp_enabled || false);
|
||||||
}
|
}
|
||||||
}, [user]);
|
}, [user]);
|
||||||
@ -213,6 +214,49 @@ const ProfilePage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<button type="submit" className="btn">Update Email</button>
|
<button type="submit" className="btn">Update Email</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form onSubmit={(e) => {
|
||||||
|
if (!formData.country) {
|
||||||
|
e.preventDefault();
|
||||||
|
showMessage('Please select a country', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleUpdate(e, '/user/change-country', { newCountry: formData.country });
|
||||||
|
}} style={{ marginTop: '2rem' }}>
|
||||||
|
<div className="form-group">
|
||||||
|
<label>COUNTRY</label>
|
||||||
|
<p style={{ fontSize: '0.85rem', color: 'var(--text-muted)', margin: '0.5rem 0', fontStyle: 'italic' }}>
|
||||||
|
Auto-detected from your IP address during registration. You can change it here.
|
||||||
|
</p>
|
||||||
|
<select
|
||||||
|
value={formData.country}
|
||||||
|
onChange={e => setFormData({ ...formData, country: e.target.value })}
|
||||||
|
required
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '12px 15px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
background: 'var(--bg)',
|
||||||
|
color: 'var(--text)',
|
||||||
|
fontSize: '1rem',
|
||||||
|
outline: 'none',
|
||||||
|
transition: 'border-color 0.2s',
|
||||||
|
cursor: 'pointer',
|
||||||
|
marginTop: '0.5rem',
|
||||||
|
}}
|
||||||
|
onFocus={(e) => e.target.style.borderColor = 'var(--primary)'}
|
||||||
|
onBlur={(e) => e.target.style.borderColor = 'var(--border)'}>
|
||||||
|
<option value="">Select a country</option>
|
||||||
|
{Object.entries(getNames()).map(([code, name]) => (
|
||||||
|
<option key={code} value={code}>
|
||||||
|
{name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button type="submit" className="btn">Update Country</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import './LegalPages.css';
|
import './LegalPages.css';
|
||||||
|
|
||||||
const GuidelinesPage = () => {
|
const GuidelinesPage = () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user