11import { Eye } from "lucide-react" ;
2+ import { cn } from "../../../../lib/utils" ;
23import type { Version } from "../../../../lib/types" ;
34
45export interface VersionListPanelProps {
@@ -8,7 +9,7 @@ export interface VersionListPanelProps {
89 publishedVersionId ?: number | null ;
910 onLoadVersion : ( versionId : number ) => void ;
1011 onPublishVersion : ( versionId : number ) => void ;
11- onPreviewVersion : ( versionId : number ) => void ;
12+ previewBaseUrl : string ;
1213 isPublishing ?: boolean ;
1314 isPublishDisabled ?: boolean ;
1415}
@@ -20,14 +21,87 @@ function formatVersionLabel(version: Version) {
2021 return { label, time } ;
2122}
2223
24+ function VersionEntry ( {
25+ version,
26+ isCurrent,
27+ isPublished,
28+ onLoad,
29+ onPublish,
30+ previewBaseUrl,
31+ isPublishing,
32+ isPublishDisabled,
33+ } : {
34+ version : Version ;
35+ isCurrent : boolean ;
36+ isPublished : boolean ;
37+ onLoad : ( ) => void ;
38+ onPublish : ( ) => void ;
39+ previewBaseUrl : string ;
40+ isPublishing ?: boolean ;
41+ isPublishDisabled ?: boolean ;
42+ } ) {
43+ const { label, time } = formatVersionLabel ( version ) ;
44+
45+ return (
46+ < div
47+ onClick = { onLoad }
48+ className = { cn (
49+ "px-3 py-2 rounded text-xs cursor-pointer transition" ,
50+ isCurrent
51+ ? "bg-gray-100 font-semibold"
52+ : "bg-white hover:bg-gray-50" ,
53+ ) }
54+ >
55+ < div className = "flex items-start justify-between gap-2" >
56+ < div className = "flex-1 min-w-0" >
57+ < span > { label } </ span >
58+
59+ < div className = "text-xs text-gray-500 mt-1" >
60+ { time }
61+ </ div >
62+ </ div >
63+
64+ < div className = "flex items-center gap-1 shrink-0" >
65+ { isPublished ? (
66+ < span className = "px-2 py-0.5 bg-green-500 text-white rounded text-xs" >
67+ Published
68+ </ span >
69+ ) : (
70+ < button
71+ onClick = { ( e ) => {
72+ e . stopPropagation ( ) ;
73+ onPublish ( ) ;
74+ } }
75+ disabled = { isPublishing || isPublishDisabled }
76+ className = "px-2 py-0.5 text-xs text-gray-600 border border-gray-300 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed transition"
77+ >
78+ Publish
79+ </ button >
80+ ) }
81+ < a
82+ href = { `${ previewBaseUrl } /${ version . id } /preview` }
83+ target = "_blank"
84+ rel = "noopener noreferrer"
85+ onClick = { ( e ) => e . stopPropagation ( ) }
86+ className = "p-1 text-gray-400 rounded hover:text-gray-600 hover:bg-gray-100 transition"
87+ title = "Preview"
88+ >
89+ < Eye size = { 14 } />
90+ </ a >
91+ </ div >
92+ </ div >
93+ </ div >
94+ ) ;
95+ }
96+
2397export function VersionListPanel ( {
2498 versions,
2599 isLoading,
26100 currentVersionId,
27101 publishedVersionId,
28102 onLoadVersion,
29103 onPublishVersion,
30- onPreviewVersion ,
104+ previewBaseUrl ,
31105 isPublishing,
32106 isPublishDisabled,
33107} : VersionListPanelProps ) {
@@ -50,62 +124,19 @@ export function VersionListPanel({
50124 ) :
51125 (
52126 < div className = "space-y-1 max-h-96" >
53- { versions . map ( ( version ) => {
54- const isPublished = version . id === publishedVersionId ;
55- const isCurrent = version . id === currentVersionId ;
56- const { label, time } = formatVersionLabel ( version ) ;
57-
58- return (
59- < div
60- key = { version . id }
61- onClick = { ( ) => onLoadVersion ( version . id ) }
62- className = { `px-3 py-2 rounded text-xs cursor-pointer transition ${
63- isCurrent
64- ? "bg-gray-100 font-semibold"
65- : "bg-white hover:bg-gray-50"
66- } `}
67- >
68- < div className = "flex items-start justify-between gap-2" >
69- < div className = "flex-1 min-w-0" >
70- < span > { label } </ span >
71-
72- < div className = "text-xs text-gray-500 mt-1" >
73- { time }
74- </ div >
75- </ div >
76-
77- < div className = "flex items-center gap-1 shrink-0" >
78- { isPublished ? (
79- < span className = "px-2 py-0.5 bg-green-500 text-white rounded text-xs" >
80- Published
81- </ span >
82- ) : (
83- < button
84- onClick = { ( e ) => {
85- e . stopPropagation ( ) ;
86- onPublishVersion ( version . id ) ;
87- } }
88- disabled = { isPublishing || isPublishDisabled }
89- className = "px-2 py-0.5 text-xs text-gray-600 border border-gray-300 rounded hover:bg-gray-100 disabled:opacity-50 disabled:cursor-not-allowed transition"
90- >
91- Publish
92- </ button >
93- ) }
94- < button
95- onClick = { ( e ) => {
96- e . stopPropagation ( ) ;
97- onPreviewVersion ( version . id ) ;
98- } }
99- className = "p-1 text-gray-400 rounded hover:text-gray-600 hover:bg-gray-100 transition"
100- title = "Preview"
101- >
102- < Eye size = { 14 } />
103- </ button >
104- </ div >
105- </ div >
106- </ div >
107- ) ;
108- } ) }
127+ { versions . map ( ( version ) => (
128+ < VersionEntry
129+ key = { version . id }
130+ version = { version }
131+ isCurrent = { version . id === currentVersionId }
132+ isPublished = { version . id === publishedVersionId }
133+ onLoad = { ( ) => onLoadVersion ( version . id ) }
134+ onPublish = { ( ) => onPublishVersion ( version . id ) }
135+ previewBaseUrl = { previewBaseUrl }
136+ isPublishing = { isPublishing }
137+ isPublishDisabled = { isPublishDisabled }
138+ />
139+ ) ) }
109140 </ div >
110141 ) }
111142 </ div >
0 commit comments