adding ability to tag listings eg if you have applied to it / adding ability to add notes to a listing

This commit is contained in:
orangecoding
2026-06-02 12:48:01 +02:00
parent 2bcec04d55
commit 317ef79336
25 changed files with 741 additions and 49 deletions

View File

@@ -20,6 +20,7 @@ import {
Banner,
Spin,
Toast,
TextArea,
} from '@douyinfe/semi-ui-19';
import {
IconArrowLeft,
@@ -44,6 +45,7 @@ import { xhrPost, xhrDelete } from '../../services/xhr.js';
import ListingDeletionModal from '../../components/ListingDeletionModal.jsx';
import Headline from '../../components/headline/Headline.jsx';
import StatusControl from '../../components/listings/StatusControl.jsx';
import './ListingDetail.less';
const { Title, Text } = Typography;
@@ -65,6 +67,8 @@ export default function ListingDetail() {
const map = useRef(null);
const [loading, setLoading] = useState(true);
const [deleteModalVisible, setDeleteModalVisible] = useState(false);
const [notesDraft, setNotesDraft] = useState('');
const [notesSaving, setNotesSaving] = useState(false);
useEffect(() => {
async function fetchListing() {
@@ -82,6 +86,10 @@ export default function ListingDetail() {
fetchListing();
}, [listingId]);
useEffect(() => {
setNotesDraft(listing?.notes ?? '');
}, [listing?.id, listing?.notes]);
const hasGeo =
listing?.latitude != null && listing?.longitude != null && listing?.latitude !== -1 && listing?.longitude !== -1;
@@ -271,6 +279,32 @@ export default function ListingDetail() {
}
};
const handleStatusChange = async (next) => {
try {
await actions.listingsData.setListingStatus(listing.id, next);
await actions.listingsData.getListing(listingId);
Toast.success(next ? `Marked as ${next}` : 'Status cleared');
} catch (e) {
console.error('Failed to update status:', e);
Toast.error('Failed to update status');
}
};
const handleSaveNotes = async () => {
if (!listing) return;
setNotesSaving(true);
try {
await actions.listingsData.setListingNotes(listing.id, notesDraft);
await actions.listingsData.getListing(listingId);
Toast.success('Notes saved');
} catch (e) {
console.error('Failed to save notes:', e);
Toast.error('Failed to save notes');
} finally {
setNotesSaving(false);
}
};
if (loading) {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
@@ -347,6 +381,7 @@ export default function ListingDetail() {
>
{listing.isWatched === 1 ? 'Watched' : 'Watch'}
</Button>
<StatusControl status={listing.status ?? null} onChange={handleStatusChange} />
<a href={listing.link} target="_blank" rel="noopener noreferrer" className="listing-detail__open-btn">
<IconLink style={{ marginRight: 6 }} />
Open listing
@@ -380,6 +415,32 @@ export default function ListingDetail() {
preview={!!listing.image_url}
/>
</div>
<div className="listing-detail__notes">
<Title heading={4} className="listing-detail__notes-title">
Notes
</Title>
<TextArea
value={notesDraft}
onChange={(val) => setNotesDraft(val)}
placeholder="Your private notes about this listing…"
rows={5}
autosize={{ minRows: 4, maxRows: 12 }}
className="listing-detail__notes-textarea"
showClear
/>
<Space className="listing-detail__notes-actions">
<Button
theme="solid"
type="primary"
loading={notesSaving}
disabled={notesSaving || (notesDraft ?? '') === (listing.notes ?? '')}
onClick={handleSaveNotes}
>
Store notes
</Button>
</Space>
</div>
</Col>
<Col span={24} lg={12}>
<div className="listing-detail__info-section">