95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { useState } from 'react'
|
|
import { AtUriBrowser, useAtUriBrowser } from './components/AtUriBrowser'
|
|
import './App.css'
|
|
|
|
function BrowserContent() {
|
|
const [handle, setHandle] = useState('')
|
|
const { records, currentRecord, setCurrentRecord, loading, error, loadHandle } = useAtUriBrowser()
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
if (handle) {
|
|
await loadHandle(handle)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="container">
|
|
<h1>AT Protocol Browser</h1>
|
|
|
|
<form onSubmit={handleSubmit} className="input-section">
|
|
<input
|
|
type="text"
|
|
placeholder="handle (e.g., ai.syui.ai)"
|
|
value={handle}
|
|
onChange={(e) => setHandle(e.target.value)}
|
|
className="at-uri-input"
|
|
/>
|
|
<button type="submit" disabled={loading}>
|
|
{loading ? 'Loading...' : 'Browse'}
|
|
</button>
|
|
</form>
|
|
|
|
{error && (
|
|
<div className="error-section">
|
|
<p>Error: {error}</p>
|
|
</div>
|
|
)}
|
|
|
|
{currentRecord ? (
|
|
<div className="record-view">
|
|
<button onClick={() => setCurrentRecord(null)} className="back-button">
|
|
← Back to list
|
|
</button>
|
|
<h2>{currentRecord.value.title}</h2>
|
|
<div className="record-meta">
|
|
<p>URI: {currentRecord.uri}</p>
|
|
<p>Created: {new Date(currentRecord.value.createdAt).toLocaleString()}</p>
|
|
</div>
|
|
<div className="record-content">
|
|
<pre>{currentRecord.value.content}</pre>
|
|
</div>
|
|
</div>
|
|
) : records.length > 0 ? (
|
|
<div className="records-list">
|
|
<h2>Posts ({records.length})</h2>
|
|
<ul>
|
|
{records.map((record) => (
|
|
<li key={record.uri}>
|
|
<button onClick={() => setCurrentRecord(record)} className="record-link">
|
|
<span className="record-title">{record.value.title}</span>
|
|
<span className="record-date">
|
|
{new Date(record.value.createdAt).toLocaleDateString()}
|
|
</span>
|
|
</button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
) : !loading && !error && (
|
|
<div className="info-section">
|
|
<h2>About</h2>
|
|
<p>Browse AT Protocol records directly from the PDS.</p>
|
|
<ul>
|
|
<li>Enter a handle to view posts</li>
|
|
<li>Example: ai.syui.ai</li>
|
|
<li>Supports syu.is PDS environment</li>
|
|
</ul>
|
|
</div>
|
|
)}
|
|
|
|
<a href="/" className="back-link">← Back to Blog</a>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function App() {
|
|
return (
|
|
<AtUriBrowser>
|
|
<BrowserContent />
|
|
</AtUriBrowser>
|
|
)
|
|
}
|
|
|
|
export default App
|