Something went wrong. Try again.
(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol.
margin.at
extension web atproto comments
Something went wrong. Try again.
4.3 kB · 145 lines
JSX
at ui-refactor
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146import { useState } from "react";import { updateProfile } from "../api/client";
export default function EditProfileModal({ profile, onClose, onUpdate }) { const [bio, setBio] = useState(profile?.bio || ""); const [website, setWebsite] = useState(profile?.website || ""); const [links, setLinks] = useState(profile?.links || []); const [newLink, setNewLink] = useState(""); const [saving, setSaving] = useState(false); const [error, setError] = useState(null);
const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); setError(null);
try { await updateProfile({ bio, website, links }); onUpdate(); onClose(); } catch (err) { setError(err.message); } finally { setSaving(false); } };
const addLink = () => { if (!newLink) return;
if (!links.includes(newLink)) { setLinks([...links, newLink]); setNewLink(""); setError(null); } };
const removeLink = (index) => { setLinks(links.filter((_, i) => i !== index)); };
return ( <div className="modal-overlay" onClick={onClose}> <div className="modal-container" onClick={(e) => e.stopPropagation()}> <div className="modal-header"> <h2>Edit Profile</h2> <button className="modal-close-btn" onClick={onClose}> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" > <line x1="18" y1="6" x2="6" y2="18" /> <line x1="6" y1="6" x2="18" y2="18" /> </svg> </button> </div> <form onSubmit={handleSubmit} className="modal-body"> {error && <div className="error-message">{error}</div>}
<div className="form-group"> <label>Bio</label> <textarea className="input" value={bio} onChange={(e) => setBio(e.target.value)} placeholder="Tell us about yourself..." rows={4} maxLength={5000} /> <div className="char-count">{bio.length}/5000</div> </div>
<div className="form-group"> <label>Website</label> <input type="url" className="input" value={website} onChange={(e) => setWebsite(e.target.value)} placeholder="https://example.com" maxLength={1000} /> </div>
<div className="form-group"> <label>Links</label> <div className="links-input-group"> <input type="url" className="input" value={newLink} onChange={(e) => setNewLink(e.target.value)} placeholder="Add a link (e.g. GitHub, LinkedIn)..." onKeyDown={(e) => e.key === "Enter" && (e.preventDefault(), addLink()) } /> <button type="button" className="btn btn-secondary" onClick={addLink} > Add </button> </div> <ul className="links-list"> {links.map((link, i) => ( <li key={i} className="link-item"> <span>{link}</span> <button type="button" className="btn-icon-sm" onClick={() => removeLink(i)} > × </button> </li> ))} </ul> </div>
<div className="modal-actions"> <button type="button" className="btn btn-secondary" onClick={onClose} disabled={saving} > Cancel </button> <button type="submit" className="btn btn-primary" disabled={saving}> {saving ? "Saving..." : "Save Profile"} </button> </div> </form> </div> </div> );}