fixed code
This commit is contained in:
70
src/components/feed/FeedContent.jsx
Normal file
70
src/components/feed/FeedContent.jsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import PostOnFeed from "../../pages/PostOnFeed";
|
||||
|
||||
export default function FeedContent({
|
||||
loading,
|
||||
cityLoading,
|
||||
citySearchActive,
|
||||
error,
|
||||
filteredAds,
|
||||
activeNav,
|
||||
liked,
|
||||
onLike,
|
||||
onEdit,
|
||||
onDelete,
|
||||
onMarkFound,
|
||||
onImageClick,
|
||||
onAuthRequired,
|
||||
t,
|
||||
}) {
|
||||
if (loading || (citySearchActive && cityLoading)) {
|
||||
return (
|
||||
<div className="f-center">
|
||||
<div className="f-spinner-wrap">
|
||||
<div className="f-spinner" />
|
||||
{t('feed.loading')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="f-center">
|
||||
<div className="f-center-icon">⚠️</div>
|
||||
<div className="f-center-title">{t('feed.loadError')}</div>
|
||||
<div className="f-center-sub">{error}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!filteredAds.length) {
|
||||
const emptyMsg = activeNav === "myads"
|
||||
? { title: t('feed.emptyMyAdsTitle'), sub: t('feed.emptyMyAdsSub') }
|
||||
: citySearchActive
|
||||
? { title: t('feed.emptyCityTitle'), sub: t('feed.emptyCitySub') }
|
||||
: { title: t('feed.emptyAllTitle'), sub: t('feed.emptyAllSub') };
|
||||
|
||||
return (
|
||||
<div className="f-center">
|
||||
<div className="f-center-icon">🔍</div>
|
||||
<div className="f-center-title">{emptyMsg.title}</div>
|
||||
<div className="f-center-sub" dangerouslySetInnerHTML={{ __html: emptyMsg.sub }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return filteredAds.map(ad => (
|
||||
<PostOnFeed
|
||||
key={ad.id}
|
||||
ad={ad}
|
||||
liked={liked.has(ad.id)}
|
||||
onLike={onLike}
|
||||
onEdit={activeNav === "myads" ? onEdit : undefined}
|
||||
onDelete={activeNav === "myads" ? onDelete : undefined}
|
||||
onMarkFound={activeNav === "myads" ? onMarkFound : undefined}
|
||||
isOwner={activeNav === "myads"}
|
||||
onImageClick={onImageClick}
|
||||
onAuthRequired={onAuthRequired}
|
||||
/>
|
||||
));
|
||||
}
|
||||
26
src/components/feed/FeedSearchBar.jsx
Normal file
26
src/components/feed/FeedSearchBar.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
export default function FeedSearchBar({ value, onChange, t }) {
|
||||
return (
|
||||
<div className="f-search-bar">
|
||||
<svg className="f-search-icon" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21-4.35-4.35" />
|
||||
</svg>
|
||||
<input
|
||||
className="f-search-input"
|
||||
type="text"
|
||||
placeholder={t('feed.searchPlaceholder')}
|
||||
value={value}
|
||||
onChange={e => onChange(e.target.value)}
|
||||
/>
|
||||
{value && (
|
||||
<button className="f-search-clear" onClick={() => onChange("")}>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" width="18" height="18">
|
||||
<path d="M18 6 6 18M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
28
src/components/feed/FeedTopBar.jsx
Normal file
28
src/components/feed/FeedTopBar.jsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import AppTopBar from "../layout/AppTopBar";
|
||||
|
||||
export default function FeedTopBar({
|
||||
onMenuClick,
|
||||
onCreatePost,
|
||||
isAuthenticated,
|
||||
profileData,
|
||||
onProfileClick,
|
||||
onLoginClick,
|
||||
t,
|
||||
}) {
|
||||
return (
|
||||
<AppTopBar
|
||||
onMenuClick={onMenuClick}
|
||||
isAuthenticated={isAuthenticated}
|
||||
profileData={profileData}
|
||||
onProfileClick={onProfileClick}
|
||||
onLoginClick={onLoginClick}
|
||||
loginLabel={t('feed.login')}
|
||||
centerContent={
|
||||
<button className="f-post-btn" onClick={onCreatePost}>
|
||||
<span style={{ fontSize: "1.15rem", fontWeight: 900, lineHeight: 1 }}>+</span>
|
||||
{t('feed.createPost')}
|
||||
</button>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
21
src/components/feed/TypeFilterBar.jsx
Normal file
21
src/components/feed/TypeFilterBar.jsx
Normal file
@@ -0,0 +1,21 @@
|
||||
export default function TypeFilterBar({ value, onChange, t }) {
|
||||
const options = [
|
||||
{ key: "loss", label: t('feed.filterLoss') },
|
||||
{ key: null, label: t('feed.filterAll') },
|
||||
{ key: "found", label: t('feed.filterFound') },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="f-filter-bar">
|
||||
{options.map(opt => (
|
||||
<button
|
||||
key={opt.key ?? "all"}
|
||||
className={`f-filter-btn${value === opt.key ? " active" : ""}`}
|
||||
onClick={() => onChange(opt.key)}
|
||||
>
|
||||
{opt.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user