From 6d81e0281a86fadcc894332580db609906d70bec Mon Sep 17 00:00:00 2001 From: kimjaehyeon0101 <47347352-kimjaehyeon0101@users.noreply.replit.com> Date: Mon, 29 Sep 2025 18:42:29 +0000 Subject: [PATCH] Add sorting options for media outlets by name or traffic Introduce alphabetical and traffic score sorting for media outlets in both the main content and admin dashboard views, updating the schema to include a trafficScore field. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 069d4324-6c40-4355-955e-c714a50de1ea Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/069d4324-6c40-4355-955e-c714a50de1ea/jvFIdY3 --- .replit | 4 -- ...α…³α„…ᅡᆫ샷 2025-09-30 α„‹α…©α„Œα…₯ᆫ 2.12.13_1759171072115.png | Bin 0 -> 22825 bytes client/src/components/MainContent.tsx | 34 +++++++++++++- client/src/pages/AdminDashboard.tsx | 43 ++++++++++++++---- shared/schema.ts | 1 + 5 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 attached_assets/스크란샷 2025-09-30 α„‹α…©α„Œα…₯ᆫ 2.12.13_1759171072115.png diff --git a/.replit b/.replit index ba89ca5..a45f89c 100644 --- a/.replit +++ b/.replit @@ -22,10 +22,6 @@ externalPort = 3001 localPort = 43349 externalPort = 3000 -[[ports]] -localPort = 44197 -externalPort = 3002 - [env] PORT = "5000" diff --git a/attached_assets/스크란샷 2025-09-30 α„‹α…©α„Œα…₯ᆫ 2.12.13_1759171072115.png b/attached_assets/스크란샷 2025-09-30 α„‹α…©α„Œα…₯ᆫ 2.12.13_1759171072115.png new file mode 100644 index 0000000000000000000000000000000000000000..bd7859dee3cc125f2fea260fc1eee02025ece377 GIT binary patch literal 22825 zcmeFZXIPWl(m#w91rY=k73o!wA_z!t(tGcn&_n1DdKHnXbOS`Xbb&zVNN+-e`{Dg`xUQS5+-qi)S!>Oj`ORF3P*s*8zbt_O9r{!RnUEa{P zH33Y;n7%;U#dbQ_Lq6Ss8-8o7vM<4dl#-PwGvZyIFtN`mfq3|%{_57{*0g_V1Jqk)?e31?++SaW5{Lx<(@#Q<`H3;;z{;SlV!t=%<8MGqAY30X? zPDAtZ7K}9E??4eVcG_|eL?8IXv-#(RxlYBL9)%pE633Dka&C--yraH%*ZBnv&Xc?I z58J;6^7pP?2?tnkgbF?OFf+w}Vre#H75MBnf$hB1s_M&Y9OZ=ZBg3>iv;4e`zE4v8 zZV1RLae(g`Zr`}TD1nY|u4Wdqm!_ICi>^)C#k4LbAk1}$R(*e-yOTOm;v5mL>;MKf z^4*&8G!IqI69FjxG^IVP%(Vf!a#l)8I4s!m9h__7wm3JjrEA#dDfYp^x$*HW4leeS z82h~WeEnaww_bd{@vkxtc1psh#wE?-ga~95Hn;N&()OFKUQWUTN z0olzgLFNEUqByRS?w7N>F z)RG_<05vZ=Cp#yt2p%;xwUCRYm4Nyi=|9-9--Kyx+}xZ5I5<2#J=s0E*+DMW954C# z`8hbbIJmgjuoP^rU`IDIFE&S4x_>tEuXf%5TrFH|o!o3ej?}-}H8Tgfy9v|M{_5!8 zfBzgOz{~bOJvqAmF)i!_Ieyh}ykzI(_;=e_R-s>S1ypUl01kR@Y=KzuVEYhx$-^V` z5Bk5<{HMqN;?(^wPHwJO|IPYeRll=pxdL1yK|pMuZX*9#nm?HTyYdf4A&y^D|1VMe zQ_lZ*ixsp8o)E{s7fl3jq2b$G92_wmxi{jPUe~tL?>1-+lXdBQAO*;iq-Lu#zyDbN zrt{ss=as9VULk2q=7SVj^}GZ<*(VybPZXX%d4F4z{?nJMQ{aGm-Hgv{ec8CX$xgip z6ti7xJz)*q5m}k846rV#>U&`b^GY=%3dFfdjdSge7|!+Iiu-|LlR{r^X#Fh#HPIbv zT^HKFa{kdCSQ4j&3-l@Y{ohjDNlLr%Td)5fix`SX?CW<(-e=msqreGfSoyobQ^)b$ zBzkd>_x#J9znLC&plJ{P|2gqrLs%rZcC)X+7LVon|0SAV6xgZX|J#ZEZ|eWwS6$Z? zU{~QV$z|~MC!xG1s;KgvX6W+4qhiH!{+Vjull`$ecY7a~pBns=Whspp zV+Laf%Nc0Y7qwdzQ>JYMTVLp6E9~psD+&Arba)qYlQ-Y9vcn@tnDV9pi7Z+U+tan^ zag%^t!%LHXL!Ygx6081C)d~xpV|o2^)jLgRQ{EdT)_~pwIlWwyfQwPy8A}p_3d=pb zK6l4wV|md>JEGJts6-rUDEz%35628BtYG%z1KTwRrS1HA_Fk($bha`@{2b1Y_p~RU zY)@J0*!x%-Ac62a?E>{&nBqZD*Y{NJwv)4o?AW~G0kd!ltC_N9l-)RrcWFOYA^ENA zRYA~=t$sKPCTHSrE1>hLnSN456mcJ@^>JO%h~_W*R_f6UGIm27Q1eB#k^9m^^rSU3 z(dOe?d-1#ob3`Jj;j%8>4?T%K8rQ(nI-llu-OLO>oyh5lci8>hQeBEKrR#lNfTQ{H zbYqvPyud%?w#TTJQHfOKqv`>Hjm4_&q{}ZZ^_D#!8Q6!=aPra}$4aYyJVB_4U!77K zXUpw-tDt%wpq)`&8psE$W{BE)lZ^bHRWZmaLwNh^Ogz&GD22X!Bg3l&rfy=Ar1KF? z)YX4gD~oYr9}?c49IPN`JZAwi)xufrk%{I;jJUy(?Y%wmOvtKnk4o&)@D?#9k!3f$ ztT&z+eZ*lrNWxjvDnHq~AaXS=;PD!@-L%0D;kK?Wp!oXz=Azcw=|&rgIlvcq*E?G} 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 S*7#~kTzeZA>uRfj`2PTvf("alphabetical"); const { data: allOutlets = [], isLoading } = useQuery({ queryKey: ["/api/media-outlets"], @@ -26,11 +30,20 @@ export default function MainContent() { }, }); - // Group outlets by category + // Group outlets by category and sort const getOutletsByCategory = (category: string) => { - return allOutlets.filter(outlet => + const filtered = allOutlets.filter(outlet => outlet.category.toLowerCase() === category.toLowerCase() ); + + return filtered.sort((a, b) => { + if (sortBy === "alphabetical") { + return a.name.localeCompare(b.name); + } else { + // Sort by traffic score (descending - highest traffic first) + return (b.trafficScore || 0) - (a.trafficScore || 0); + } + }); }; const renderOutletCard = (outlet: MediaOutlet) => ( @@ -72,6 +85,23 @@ export default function MainContent() { return (
+ {/* Sorting Controls */} +
+

언둠맀체

+
+ + +
+
+ {isLoading ? (
{categories.map((category) => ( diff --git a/client/src/pages/AdminDashboard.tsx b/client/src/pages/AdminDashboard.tsx index e69cd78..b8c4025 100644 --- a/client/src/pages/AdminDashboard.tsx +++ b/client/src/pages/AdminDashboard.tsx @@ -6,7 +6,8 @@ import { useAuth } from "@/hooks/useAuth"; import { useEffect, useState } from "react"; import { useToast } from "@/hooks/use-toast"; import { isUnauthorizedError } from "@/lib/authUtils"; -import { Search, Settings } from "lucide-react"; +import { Search, Settings, ArrowUpDown } from "lucide-react"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import type { MediaOutlet } from "@shared/schema"; import MediaOutletManagement from "@/components/MediaOutletManagement"; @@ -16,6 +17,7 @@ export default function AdminDashboard() { const [searchTerm, setSearchTerm] = useState(""); const [selectedOutlet, setSelectedOutlet] = useState(null); const [managingOutlet, setManagingOutlet] = useState(null); + const [sortBy, setSortBy] = useState<"alphabetical" | "traffic">("alphabetical"); // Redirect if not authenticated or not admin/superadmin useEffect(() => { @@ -44,11 +46,20 @@ export default function AdminDashboard() { }, }); - // Filter outlets based on search term - const filteredOutlets = mediaOutlets.filter(outlet => - outlet.name.toLowerCase().includes(searchTerm.toLowerCase()) || - (outlet.description && outlet.description.toLowerCase().includes(searchTerm.toLowerCase())) - ); + // Filter and sort outlets based on search term and sort option + const filteredOutlets = mediaOutlets + .filter(outlet => + outlet.name.toLowerCase().includes(searchTerm.toLowerCase()) || + (outlet.description && outlet.description.toLowerCase().includes(searchTerm.toLowerCase())) + ) + .sort((a, b) => { + if (sortBy === "alphabetical") { + return a.name.localeCompare(b.name); + } else { + // Sort by traffic score (descending - highest traffic first) + return (b.trafficScore || 0) - (a.trafficScore || 0); + } + }); const handleLogout = () => { window.location.href = "/api/logout"; @@ -131,9 +142,23 @@ export default function AdminDashboard() {
-
-

κ΄€λ¦¬μž λŒ€μ‹œλ³΄λ“œ

-

관리할 언둠맀체λ₯Ό κ²€μƒ‰ν•˜κ³  μ„ νƒν•˜μ„Έμš”

+
+
+

κ΄€λ¦¬μž λŒ€μ‹œλ³΄λ“œ

+

관리할 언둠맀체λ₯Ό κ²€μƒ‰ν•˜κ³  μ„ νƒν•˜μ„Έμš”

+
+
+ + +
{outletsLoading ? ( diff --git a/shared/schema.ts b/shared/schema.ts index b07d00d..4128fc3 100644 --- a/shared/schema.ts +++ b/shared/schema.ts @@ -47,6 +47,7 @@ export const mediaOutlets = pgTable("media_outlets", { description: text("description"), imageUrl: varchar("image_url"), tags: text("tags").array(), + trafficScore: integer("traffic_score").default(0), // For sorting by traffic isActive: boolean("is_active").default(true), createdAt: timestamp("created_at").defaultNow(), updatedAt: timestamp("updated_at").defaultNow(),