1 2import { useState } from 'react'; 3import { html } from '../html.js?v=3.8.36'; 4import { BookOpen, ExternalLink, ArrowLeft, Calendar, GraduationCap } from 'lucide-react'; 5import MindMap from './MindMap.js?v=3.8.36'; 6import DetailPanel from './DetailPanel.js?v=3.8.36'; 7import { DISSERTATION_NODES } from './dissertationData.js?v=3.8.36'; 8import { resolveSitePath } from '../utils/pathResolver.js?v=3.8.36'; 9 10const DissertationPage = ({ onBack, embedded = false }) => { 11 const [selectedNode, setSelectedNode] = useState(null); 12 const [detailPanelOpen, setDetailPanelOpen] = useState(false); 13 14 // Resolve for the current environment so the link works in local preview and 15 // GitHub Pages, not only production. 16 const dissertationPdfUrl = resolveSitePath('dissertation/reader/'); 17 18 const handleNodeSelect = (node) => { 19 if (node) { 20 setSelectedNode(node); 21 setDetailPanelOpen(true); 22 } else { 23 // Node was deselected (from MindMap) 24 setSelectedNode(null); 25 setDetailPanelOpen(false); 26 } 27 }; 28 29 const closeDetailPanel = () => { 30 setSelectedNode(null); 31 setDetailPanelOpen(false); 32 }; 33 34 return html` 35 <div className=${embedded 36 ? 'desktop-dissertation-surface archive-dissertation-route is-embedded' 37 : 'archive-dissertation-route'}> 38 ${!embedded && html`<header className="archive-dissertation-header"> 39 <div className="archive-dissertation-header__inner"> 40 <div className="archive-dissertation-header__primary"> 41 ${onBack && html` 42 <button 43 type="button" 44 onClick=${onBack} 45 aria-label="Back to archive" 46 className="archive-action archive-action--quiet archive-dissertation-header__back" 47 > 48 <${ArrowLeft} aria-hidden="true" /> 49 <span>Back to archive</span> 50 </button> 51 `} 52 <div className="archive-dissertation-header__identity"> 53 <div className="archive-dissertation-header__mark"> 54 <${BookOpen} aria-hidden="true" /> 55 </div> 56 <div> 57 <p className="archive-dissertation-header__title"> 58 The Impossible Press 59 </p> 60 <p className="archive-dissertation-header__meta">PhD dissertation, 1986</p> 61 </div> 62 </div> 63 </div> 64 65 <div className="archive-dissertation-header__metadata"> 66 <div> 67 <${GraduationCap} aria-hidden="true" /> 68 <span>Jay Rosen</span> 69 </div> 70 <div> 71 <${Calendar} aria-hidden="true" /> 72 <span>New York University, 1986</span> 73 </div> 74 </div> 75 76 <a 77 href=${dissertationPdfUrl} 78 target="_blank" 79 rel="noopener noreferrer" 80 className="archive-action archive-action--primary archive-dissertation-header__read" 81 > 82 <span>Read full text</span> 83 <${ExternalLink} aria-hidden="true" /> 84 </a> 85 </div> 86 </header>`} 87 88 <div className="archive-dissertation-intro"> 89 <div className="archive-dissertation-intro__inner"> 90 <div className="archive-dissertation-intro__layout"> 91 <div className="archive-dissertation-intro__title"> 92 <h1 93 data-route-entry-focus=${embedded ? undefined : true} 94 tabIndex=${embedded ? undefined : '-1'} 95 > 96 The Impossible Press 97 </h1> 98 <h2> 99 American Journalism and the Decline of Public Life 100 </h2> 101 </div> 102 <div 103 className="archive-dissertation-terms" 104 role="region" 105 tabIndex="0" 106 aria-label="Dissertation index terms" 107 > 108 ${['Public Sphere', 'Objectivity', 'Lippmann', 'Dewey'].map(tag => html` 109 <span 110 key=${tag} 111 className="archive-index-term" 112 > 113 ${tag} 114 </span> 115 `)} 116 </div> 117 </div> 118 </div> 119 </div> 120 121 <div className="archive-dissertation-guide"> 122 <div className="archive-dissertation-guide__inner"> 123 <div> 124 <strong>Navigate:</strong>
125 Click any node to expand and see details. 126 </div> 127 <div className="archive-dissertation-legend" aria-label="Map legend"> 128 <span> 129 <i className="archive-dissertation-legend__key is-part" aria-hidden="true" /> Parts 130 </span> 131 <span> 132 <i className="archive-dissertation-legend__key is-chapter" aria-hidden="true" /> Chapters 133 </span> 134 <span> 135 <i className="archive-dissertation-legend__key is-bookend" aria-hidden="true" /> Intro/conclusion 136 </span> 137 </div> 138 </div> 139 </div> 140 141 <div className=${embedded ? 'desktop-dissertation-map archive-dissertation-map' : 'archive-dissertation-map'}> 142 <${MindMap} 143 nodes=${DISSERTATION_NODES} 144 onNodeSelect=${handleNodeSelect} 145 isPanelOpen=${detailPanelOpen} 146 minimumZoom=${embedded ? 44 / 72 : 0.3} 147 className=${embedded ? '' : 'absolute inset-0'} 148 /> 149 </div> 150 151 <${DetailPanel} 152 node=${selectedNode} 153 isOpen=${detailPanelOpen} 154 onClose=${closeDetailPanel} 155 contained=${embedded} 156 /> 157 158 ${!embedded && html`<footer className="archive-dissertation-footer"> 159 <div className="archive-dissertation-footer__inner"> 160 <div> 161 Part of <strong>Jay Rosen's Internet Archive</strong> 162 </div> 163 <div> 164 <a 165 href="https://twitter.com/jayrosen_nyu" 166 target="_blank" 167 rel="noopener noreferrer" 168 > 169 @jayrosen_nyu 170 </a> 171 <span aria-hidden="true">|</span> 172 <a 173 href="https://pressthink.org" 174 target="_blank" 175 rel="noopener noreferrer" 176 > 177 PressThink 178 </a> 179 </div> 180 </div> 181 </footer>`} 182 </div> 183 `; 184}; 185 186export default DissertationPage;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.