Skip to content

Commit 56af4d7

Browse files
committed
Refactor code for improved readability and consistency
- Added missing newline at the end of _journal.json file. - Simplified import statements in notifications.spec.ts and structured-data/index.ts for better clarity. - Reformatted code in seed-notifications.ts for consistent indentation and readability. - Enhanced readability of import statements in content.ts and tag.ts by aligning them properly. - Updated test expectations in notifications.spec.ts to improve clarity and maintainability.
1 parent d072cb9 commit 56af4d7

14 files changed

Lines changed: 504 additions & 1242 deletions

File tree

app/(app)/[username]/[slug]/_userLinkDetail.tsx

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,6 @@ type Props = {
2121
contentSlug: string;
2222
};
2323

24-
// Get favicon URL from a website
25-
const getFaviconUrl = (
26-
websiteUrl: string | null | undefined,
27-
): string | null => {
28-
if (!websiteUrl) return null;
29-
try {
30-
const url = new URL(websiteUrl);
31-
return `https://www.google.com/s2/favicons?domain=${url.hostname}&sz=32`;
32-
} catch {
33-
return null;
34-
}
35-
};
36-
3724
// Get hostname from URL
3825
const getHostname = (urlString: string): string => {
3926
try {
@@ -189,7 +176,6 @@ const UserLinkDetail = ({ username, contentSlug }: Props) => {
189176
})
190177
: null;
191178

192-
const faviconUrl = getFaviconUrl(externalUrl);
193179
const hostname = externalUrl ? getHostname(externalUrl) : null;
194180
const score = votes.upvotes - votes.downvotes;
195181

app/(app)/admin/moderation/_client.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useState } from "react";
44
import Link from "next/link";
55
import {
66
FlagIcon,
7-
CheckCircleIcon,
87
XCircleIcon,
98
ExclamationTriangleIcon,
109
ArrowLeftIcon,

app/(app)/admin/sources/_client.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ const LogoWithFallback = ({
6060

6161
// Fallback to initial letter
6262
return (
63-
<span className={`flex ${sizeClass} flex-shrink-0 items-center justify-center rounded bg-orange-500 ${textSize} font-medium text-white`}>
63+
<span
64+
className={`flex ${sizeClass} flex-shrink-0 items-center justify-center rounded bg-orange-500 ${textSize} font-medium text-white`}
65+
>
6466
{initial}
6567
</span>
6668
);
@@ -223,7 +225,8 @@ const AdminSourcesPage = () => {
223225

224226
// Handle logo image upload
225227
const handleLogoUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
226-
if (!e.target.files || e.target.files.length === 0 || !editingSource) return;
228+
if (!e.target.files || e.target.files.length === 0 || !editingSource)
229+
return;
227230

228231
const file = e.target.files[0];
229232
const { size, type } = file;
@@ -628,7 +631,9 @@ const AdminSourcesPage = () => {
628631
disabled={updateSource.status === "pending"}
629632
className="rounded-lg bg-orange-500 px-4 py-2 font-medium text-white transition-colors hover:bg-orange-600 disabled:opacity-50"
630633
>
631-
{updateSource.status === "pending" ? "Saving..." : "Save Changes"}
634+
{updateSource.status === "pending"
635+
? "Saving..."
636+
: "Save Changes"}
632637
</button>
633638
</div>
634639
</form>

app/(app)/admin/tags/_client.tsx

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ import {
1919
type SortField = "postCount" | "title" | "createdAt";
2020
type SortOrder = "asc" | "desc";
2121

22+
const SortIcon = ({
23+
field,
24+
sortField,
25+
}: {
26+
field: SortField;
27+
sortField: SortField;
28+
}) => (
29+
<ChevronUpDownIcon
30+
className={`ml-1 inline h-4 w-4 ${
31+
sortField === field ? "text-orange-500" : "text-neutral-400"
32+
}`}
33+
/>
34+
);
35+
2236
const TagsAdmin = () => {
2337
const [searchQuery, setSearchQuery] = useState("");
2438
const [sortField, setSortField] = useState<SortField>("postCount");
@@ -42,8 +56,6 @@ const TagsAdmin = () => {
4256
} | null>(null);
4357
const [showMergePanel, setShowMergePanel] = useState(false);
4458

45-
const utils = api.useUtils();
46-
4759
// Fetch all tags with admin stats
4860
const { data, status, refetch } = api.tag.getAdminStats.useQuery();
4961

@@ -195,14 +207,6 @@ const TagsAdmin = () => {
195207
setShowMergePanel(true);
196208
};
197209

198-
const SortIcon = ({ field }: { field: SortField }) => (
199-
<ChevronUpDownIcon
200-
className={`ml-1 inline h-4 w-4 ${
201-
sortField === field ? "text-orange-500" : "text-neutral-400"
202-
}`}
203-
/>
204-
);
205-
206210
return (
207211
<div className="mx-auto max-w-6xl px-4 py-8">
208212
{/* Header */}
@@ -380,9 +384,7 @@ const TagsAdmin = () => {
380384
<button
381385
onClick={handleMerge}
382386
disabled={
383-
!mergeSource ||
384-
!mergeTarget ||
385-
mergeTags.status === "pending"
387+
!mergeSource || !mergeTarget || mergeTags.status === "pending"
386388
}
387389
className="rounded-lg bg-blue-600 px-4 py-2 font-medium text-white transition-colors hover:bg-blue-700 disabled:opacity-50"
388390
>
@@ -495,7 +497,9 @@ const TagsAdmin = () => {
495497
disabled={updateTag.status === "pending"}
496498
className="rounded-lg bg-orange-500 px-4 py-2 font-medium text-white transition-colors hover:bg-orange-600 disabled:opacity-50"
497499
>
498-
{updateTag.status === "pending" ? "Saving..." : "Save Changes"}
500+
{updateTag.status === "pending"
501+
? "Saving..."
502+
: "Save Changes"}
499503
</button>
500504
</div>
501505
</form>
@@ -526,7 +530,7 @@ const TagsAdmin = () => {
526530
className="cursor-pointer px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-neutral-500 hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200"
527531
>
528532
Tag
529-
<SortIcon field="title" />
533+
<SortIcon field="title" sortField={sortField} />
530534
</th>
531535
<th className="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-neutral-500 dark:text-neutral-400">
532536
Slug
@@ -536,14 +540,14 @@ const TagsAdmin = () => {
536540
className="cursor-pointer px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-neutral-500 hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200"
537541
>
538542
Posts
539-
<SortIcon field="postCount" />
543+
<SortIcon field="postCount" sortField={sortField} />
540544
</th>
541545
<th
542546
onClick={() => handleSort("createdAt")}
543547
className="cursor-pointer px-6 py-3 text-left text-xs font-medium uppercase tracking-wider text-neutral-500 hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200"
544548
>
545549
Created
546-
<SortIcon field="createdAt" />
550+
<SortIcon field="createdAt" sortField={sortField} />
547551
</th>
548552
<th className="px-6 py-3 text-right text-xs font-medium uppercase tracking-wider text-neutral-500 dark:text-neutral-400">
549553
Actions
@@ -656,9 +660,7 @@ const TagsAdmin = () => {
656660
</table>
657661
{filteredTags?.length === 0 && (
658662
<div className="py-12 text-center text-neutral-500 dark:text-neutral-400">
659-
{searchQuery
660-
? "No tags match your search."
661-
: "No tags yet."}
663+
{searchQuery ? "No tags match your search." : "No tags yet."}
662664
</div>
663665
)}
664666
</div>

app/(app)/feed/_client.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { useSearchParams, useRouter } from "next/navigation";
66
import Link from "next/link";
77
import { api } from "@/server/trpc/react";
88
import { useSession } from "next-auth/react";
9-
import { FeedItemLoading, FeedFilters, PopularTagsSidebar } from "@/components/Feed";
9+
import {
10+
FeedItemLoading,
11+
FeedFilters,
12+
PopularTagsSidebar,
13+
} from "@/components/Feed";
1014
import { UnifiedContentCard } from "@/components/UnifiedContentCard";
1115
import { SavedItemCard } from "@/components/SavedItemCard";
1216
import NewsletterCTA from "@/components/NewsletterCTA/NewsletterCTA";
@@ -238,7 +242,10 @@ const FeedPage = () => {
238242

239243
{/* Popular Tags section */}
240244
<div className="mt-6">
241-
<PopularTagsSidebar selectedTag={tag} onTagClick={handleTagChange} />
245+
<PopularTagsSidebar
246+
selectedTag={tag}
247+
onTagClick={handleTagChange}
248+
/>
242249
</div>
243250

244251
{/* Categories section (RSS source categories) */}

components/PostEditor/components/TagInput.tsx

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
useCallback,
66
useEffect,
77
useRef,
8+
useMemo,
89
type KeyboardEvent,
910
type ChangeEvent,
1011
} from "react";
@@ -54,6 +55,7 @@ export function TagInput({
5455
const [inputValue, setInputValue] = useState("");
5556
const [isOpen, setIsOpen] = useState(false);
5657
const [highlightedIndex, setHighlightedIndex] = useState(-1);
58+
const [lastSuggestionsLength, setLastSuggestionsLength] = useState(0);
5759
const inputRef = useRef<HTMLInputElement>(null);
5860
const dropdownRef = useRef<HTMLDivElement>(null);
5961

@@ -69,10 +71,19 @@ export function TagInput({
6971
);
7072

7173
// Filter out already selected tags
72-
const suggestions: TagSuggestion[] =
73-
searchResults?.data?.filter(
74-
(t) => !tags.includes(t.title.toLowerCase()),
75-
) || [];
74+
const suggestions: TagSuggestion[] = useMemo(
75+
() =>
76+
searchResults?.data?.filter(
77+
(t) => !tags.includes(t.title.toLowerCase()),
78+
) || [],
79+
[searchResults?.data, tags],
80+
);
81+
82+
// Reset highlighted index when suggestions change (synchronous state derivation)
83+
if (suggestions.length !== lastSuggestionsLength) {
84+
setHighlightedIndex(-1);
85+
setLastSuggestionsLength(suggestions.length);
86+
}
7687

7788
const addTag = useCallback(
7889
(tag: string) => {
@@ -165,11 +176,6 @@ export function TagInput({
165176
return () => document.removeEventListener("mousedown", handleClickOutside);
166177
}, []);
167178

168-
// Reset highlighted index when suggestions change
169-
useEffect(() => {
170-
setHighlightedIndex(-1);
171-
}, [suggestions.length]);
172-
173179
const isMaxReached = tags.length >= maxTags;
174180

175181
// Format post count for display
@@ -229,19 +235,19 @@ export function TagInput({
229235
onFocus={() => inputValue.length >= 1 && setIsOpen(true)}
230236
placeholder={tags.length === 0 ? placeholder : "Add more..."}
231237
disabled={disabled}
232-
className="min-w-[120px] w-full border-none bg-transparent px-1 py-1 text-sm text-neutral-900 placeholder:text-neutral-400 focus:outline-none focus:ring-0 dark:text-white dark:placeholder:text-neutral-500"
238+
className="w-full min-w-[120px] border-none bg-transparent px-1 py-1 text-sm text-neutral-900 placeholder:text-neutral-400 focus:outline-none focus:ring-0 dark:text-white dark:placeholder:text-neutral-500"
233239
autoComplete="off"
234240
/>
235241

236242
{/* Autocomplete Dropdown */}
237243
{isOpen && inputValue.length >= 1 && (
238244
<div
239245
ref={dropdownRef}
240-
className="absolute left-0 top-full z-50 mt-1 w-72 max-h-64 overflow-y-auto rounded-lg border border-neutral-200 bg-white shadow-lg dark:border-neutral-700 dark:bg-neutral-800"
246+
className="absolute left-0 top-full z-50 mt-1 max-h-64 w-72 overflow-y-auto rounded-lg border border-neutral-200 bg-white shadow-lg dark:border-neutral-700 dark:bg-neutral-800"
241247
>
242248
{isLoading ? (
243249
<div className="flex items-center justify-center p-4 text-neutral-500">
244-
<Loader2 className="h-4 w-4 animate-spin mr-2" />
250+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
245251
<span className="text-sm">Searching...</span>
246252
</div>
247253
) : suggestions.length > 0 ? (
@@ -262,7 +268,7 @@ export function TagInput({
262268
{suggestion.title}
263269
</span>
264270
<span
265-
className={`text-xs px-2 py-0.5 rounded-full ${
271+
className={`rounded-full px-2 py-0.5 text-xs ${
266272
suggestion.postCount > 100
267273
? "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"
268274
: suggestion.postCount > 10

0 commit comments

Comments
 (0)