summaryrefslogtreecommitdiff
path: root/front/src/components/ProfileEditor.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'front/src/components/ProfileEditor.tsx')
-rw-r--r--front/src/components/ProfileEditor.tsx280
1 files changed, 0 insertions, 280 deletions
diff --git a/front/src/components/ProfileEditor.tsx b/front/src/components/ProfileEditor.tsx
deleted file mode 100644
index 9a7493f..0000000
--- a/front/src/components/ProfileEditor.tsx
+++ /dev/null
@@ -1,280 +0,0 @@
-import { useState, useEffect } from "react";
-import type { UserProfile } from "@/types/nostrill";
-import useLocalState from "@/state/state";
-import Icon from "@/components/Icon";
-import toast from "react-hot-toast";
-import Avatar from "./Avatar";
-
-interface ProfileEditorProps {
- ship: string;
- onSave?: () => void;
-}
-
-const ProfileEditor: React.FC<ProfileEditorProps> = ({ ship, onSave }) => {
- const { api, profiles } = useLocalState((s) => ({
- api: s.api,
- profiles: s.profiles,
- }));
- const isOwnProfile = ship === api?.airlock.our;
-
- // Initialize state with existing profile or defaults
- const existingProfile = profiles.get(ship);
- const [name, setName] = useState(existingProfile?.name || "");
- const [picture, setPicture] = useState(existingProfile?.picture || "");
- const [about, setAbout] = useState(existingProfile?.about || "");
- const [customFields, setCustomFields] = useState<
- Array<{ key: string; value: string }>
- >(
- Object.entries(existingProfile?.other || {}).map(([key, value]) => ({
- key,
- value,
- })),
- );
- const [isEditing, setIsEditing] = useState(false);
- const [isSaving, setIsSaving] = useState(false);
-
- useEffect(() => {
- const profile = profiles.get(ship);
- if (profile) {
- setName(profile.name || "");
- setPicture(profile.picture || "");
- setAbout(profile.about || "");
- setCustomFields(
- Object.entries(profile.other || {}).map(([key, value]) => ({
- key,
- value,
- })),
- );
- }
- }, [ship, profiles]);
-
- const handleAddCustomField = () => {
- setCustomFields([...customFields, { key: "", value: "" }]);
- };
-
- const handleUpdateCustomField = (
- index: number,
- field: "key" | "value",
- newValue: string,
- ) => {
- const updated = [...customFields];
- updated[index][field] = newValue;
- setCustomFields(updated);
- };
-
- const handleRemoveCustomField = (index: number) => {
- setCustomFields(customFields.filter((_, i) => i !== index));
- };
-
- const handleSave = async () => {
- setIsSaving(true);
- try {
- // Convert custom fields array to object
- const other: Record<string, string> = {};
- customFields.forEach(({ key, value }) => {
- if (key.trim()) {
- other[key.trim()] = value;
- }
- });
-
- const profile: UserProfile = {
- name,
- picture,
- about,
- other,
- };
-
- // Call API to save profile
- if (api && typeof api.createProfile === "function") {
- await api.createProfile(profile);
- } else {
- throw new Error("Profile update API not available");
- }
-
- toast.success("Profile updated successfully");
- setIsEditing(false);
- onSave?.();
- } catch (error) {
- toast.error("Failed to update profile");
- console.error("Failed to save profile:", error);
- } finally {
- setIsSaving(false);
- }
- };
-
- const handleCancel = () => {
- // Reset to original values
- const profile = profiles.get(ship);
- if (profile) {
- setName(profile.name || "");
- setPicture(profile.picture || "");
- setAbout(profile.about || "");
- setCustomFields(
- Object.entries(profile.other || {}).map(([key, value]) => ({
- key,
- value,
- })),
- );
- }
- setIsEditing(false);
- };
-
- if (!isOwnProfile) {
- // View-only mode for other users' profiles - no editing allowed
- return (
- <div className="profile-editor view-mode">
- <div className="profile-picture">
- <Avatar p={ship} size={120} picOnly={true} />
- </div>
- <div className="profile-info">
- <h2>{name || ship}</h2>
- {about && <p className="profile-about">{about}</p>}
-
- {customFields.length > 0 && (
- <div className="profile-custom-fields">
- <h4>Additional Info</h4>
- {customFields.map(({ key, value }, index) => (
- <div key={index} className="custom-field-view">
- <span className="field-key">{key}:</span>
- <span className="field-value">{value}</span>
- </div>
- ))}
- </div>
- )}
- </div>
- </div>
- );
- }
-
- return (
- <div className="profile-editor">
- <div className="profile-header">
- <h2>Edit Profile</h2>
- {isOwnProfile && !isEditing && (
- <button onClick={() => setIsEditing(true)} className="edit-btn">
- <Icon name="settings" size={16} />
- Edit
- </button>
- )}
- </div>
-
- {isEditing ? (
- <div className="profile-form">
- <div className="form-group">
- <label htmlFor="name">Display Name</label>
- <input
- id="name"
- type="text"
- value={name}
- onChange={(e) => setName(e.target.value)}
- placeholder="Your display name"
- />
- </div>
-
- <div className="form-group">
- <label htmlFor="picture">Profile Picture URL</label>
- <input
- id="picture"
- type="url"
- value={picture}
- onChange={(e) => setPicture(e.target.value)}
- placeholder="https://example.com/avatar.jpg"
- />
- <div className="picture-preview">
- <Avatar p={ship} size={54} picOnly={true} />
- </div>
- </div>
-
- <div className="form-group">
- <label htmlFor="about">About</label>
- <textarea
- id="about"
- value={about}
- onChange={(e) => setAbout(e.target.value)}
- placeholder="Tell us about yourself..."
- rows={4}
- />
- </div>
-
- <div className="form-group custom-fields">
- <label>Custom Fields</label>
- {customFields.map((field, index) => (
- <div key={index} className="custom-field-row">
- <input
- type="text"
- value={field.key}
- onChange={(e) =>
- handleUpdateCustomField(index, "key", e.target.value)
- }
- placeholder="Field name"
- className="field-key-input"
- />
- <input
- type="text"
- value={field.value}
- onChange={(e) =>
- handleUpdateCustomField(index, "value", e.target.value)
- }
- placeholder="Field value"
- className="field-value-input"
- />
- <button
- onClick={() => handleRemoveCustomField(index)}
- className="remove-field-btn"
- title="Remove field"
- >
- ×
- </button>
- </div>
- ))}
- <button onClick={handleAddCustomField} className="add-field-btn">
- + Add Custom Field
- </button>
- </div>
-
- <div className="form-actions">
- <button
- onClick={handleSave}
- disabled={isSaving}
- className="save-btn"
- >
- {isSaving ? "Saving..." : "Save Profile"}
- </button>
- <button
- onClick={handleCancel}
- disabled={isSaving}
- className="cancel-btn"
- >
- Cancel
- </button>
- </div>
- </div>
- ) : (
- <div className="profile-view">
- <div className="profile-picture">
- <Avatar p={ship} size={120} picOnly={true} />
- </div>
-
- <div className="profile-info">
- <h3>{name || ship}</h3>
- {about && <p className="profile-about">{about}</p>}
-
- {customFields.length > 0 && (
- <div className="profile-custom-fields">
- <h4>Additional Info</h4>
- {customFields.map(({ key, value }, index) => (
- <div key={index} className="custom-field-view">
- <span className="field-key">{key}:</span>
- <span className="field-value">{value}</span>
- </div>
- ))}
- </div>
- )}
- </div>
- </div>
- )}
- </div>
- );
-};
-
-export default ProfileEditor;