Skip to content

Commit f9db2d5

Browse files
committed
refactor: adjust header offsets and enhance action button layouts for improved UI consistency
1 parent 5ed0d03 commit f9db2d5

File tree

3 files changed

+128
-103
lines changed

3 files changed

+128
-103
lines changed

packages/web/app/components/features/devlogs/DevlogAnchorNav.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export function DevlogAnchorNav({ devlog, notesCount }: DevlogAnchorNavProps) {
7777
});
7878
},
7979
{
80-
rootMargin: '-80px 0px -50% 0px', // Account for fixed header
80+
rootMargin: '-176px 0px -50% 0px', // Account for fixed header (increased from -80px)
8181
threshold: 0.1,
8282
},
8383
);
@@ -101,7 +101,7 @@ export function DevlogAnchorNav({ devlog, notesCount }: DevlogAnchorNavProps) {
101101
const targetId = href.replace('#', '');
102102
const element = document.getElementById(targetId);
103103
if (element) {
104-
const offsetTop = element.offsetTop - 80; // Account for fixed header
104+
const offsetTop = element.offsetTop - 176; // Account for fixed header (increased from 80)
105105
window.scrollTo({
106106
top: offsetTop,
107107
behavior: 'smooth',

packages/web/app/components/features/devlogs/DevlogDetails.tsx

Lines changed: 115 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ interface DevlogDetailsProps {
3737
saveHandler: () => Promise<void>,
3838
discardHandler: () => void,
3939
) => void;
40+
actions?: React.ReactNode;
4041
}
4142

4243
export function DevlogDetails({
@@ -46,6 +47,7 @@ export function DevlogDetails({
4647
onUpdate,
4748
onDelete,
4849
onUnsavedChangesChange,
50+
actions,
4951
}: DevlogDetailsProps) {
5052
// Local state for tracking changes
5153
const [localChanges, setLocalChanges] = useState<Record<string, any>>({});
@@ -70,7 +72,7 @@ export function DevlogDetails({
7072
useStickyHeaders({
7173
selectorClass: 'section-header',
7274
stickyClass: 'is-sticky',
73-
topOffset: 96, // Account for the main devlog header
75+
topOffset: 176, // Account for the sticky main devlog header (increased from 96)
7476
dependencies: [devlog?.id], // Re-run when devlog changes
7577
});
7678

@@ -255,24 +257,22 @@ export function DevlogDetails({
255257
<div className="max-w-7xl mx-auto p-6">
256258
<div className="flex gap-6">
257259
<div className="flex-1 space-y-6">
258-
{/* Header Skeleton */}
259-
<Card>
260-
<CardHeader>
261-
<div className="space-y-4">
262-
<Skeleton className="h-8 w-3/5" />
263-
<div className="flex space-x-2">
264-
<Skeleton className="h-6 w-20" />
265-
<Skeleton className="h-6 w-20" />
266-
<Skeleton className="h-6 w-20" />
267-
</div>
268-
<div className="flex space-x-4 text-sm">
269-
<Skeleton className="h-4 w-16" />
270-
<Skeleton className="h-4 w-24" />
271-
<Skeleton className="h-4 w-24" />
272-
</div>
260+
{/* Sticky Header Skeleton */}
261+
<div className="sticky top-0 z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b border-border/40 -mx-6 px-6 py-4 mb-6">
262+
<div className="space-y-4">
263+
<Skeleton className="h-8 w-3/5" />
264+
<div className="flex space-x-2">
265+
<Skeleton className="h-6 w-20" />
266+
<Skeleton className="h-6 w-20" />
267+
<Skeleton className="h-6 w-20" />
273268
</div>
274-
</CardHeader>
275-
</Card>
269+
<div className="flex space-x-4 text-sm">
270+
<Skeleton className="h-4 w-16" />
271+
<Skeleton className="h-4 w-24" />
272+
<Skeleton className="h-4 w-24" />
273+
</div>
274+
</div>
275+
</div>
276276

277277
{/* Content Skeletons */}
278278
{[
@@ -302,18 +302,29 @@ export function DevlogDetails({
302302

303303
{/* Side Navigation Skeleton */}
304304
<div className="w-64 flex-shrink-0">
305-
<Card>
306-
<CardHeader>
307-
<Skeleton className="h-5 w-20" />
308-
</CardHeader>
309-
<CardContent>
305+
<div className="sticky top-44 space-y-4">
306+
<Card>
307+
<CardHeader>
308+
<Skeleton className="h-5 w-20" />
309+
</CardHeader>
310+
<CardContent>
311+
<div className="space-y-2">
312+
{Array.from({ length: 5 }).map((_, i) => (
313+
<Skeleton key={i} className="h-4 w-full" />
314+
))}
315+
</div>
316+
</CardContent>
317+
</Card>
318+
319+
{/* Actions skeleton */}
320+
<div className="border-t pt-4">
310321
<div className="space-y-2">
311-
{Array.from({ length: 5 }).map((_, i) => (
312-
<Skeleton key={i} className="h-4 w-full" />
322+
{Array.from({ length: 3 }).map((_, i) => (
323+
<Skeleton key={i} className="h-9 w-full" />
313324
))}
314325
</div>
315-
</CardContent>
316-
</Card>
326+
</div>
327+
</div>
317328
</div>
318329
</div>
319330
</div>
@@ -325,81 +336,83 @@ export function DevlogDetails({
325336
<div className="flex gap-6">
326337
{/* Main Content */}
327338
<div className="flex-1 space-y-6">
328-
{/* Header */}
329-
<Card>
330-
<CardHeader>
331-
<div className="space-y-4">
332-
<EditableField
333-
key={`title-${getCurrentValue('title')}`}
334-
value={getCurrentValue('title')}
335-
onSave={(value: any) => handleFieldChange('title', value)}
336-
placeholder="Enter title"
337-
className={cn(
338-
'text-3xl font-bold',
339-
isFieldChanged('title') && 'ring-2 ring-primary/20 bg-primary/5',
340-
)}
341-
>
342-
<h1 className="text-3xl font-bold" title={getCurrentValue('title')}>
343-
{getCurrentValue('title')}
344-
</h1>
345-
</EditableField>
346-
347-
<div className="flex flex-wrap gap-2">
348-
<EditableField
349-
key={`status-${getCurrentValue('status')}`}
350-
className={cn(
351-
'inline-block',
352-
isFieldChanged('status') && 'ring-2 ring-primary/20 bg-primary/5 rounded',
353-
)}
354-
type="select"
355-
value={getCurrentValue('status')}
356-
options={statusOptions}
357-
onSave={(value: any) => handleFieldChange('status', value)}
358-
>
359-
<DevlogStatusTag status={getCurrentValue('status')} />
360-
</EditableField>
361-
339+
{/* Sticky Header */}
340+
<div className="sticky top-0 z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 border-b border-border/40 -mx-6 px-6 py-4 mb-6">
341+
<Card className="border-0 shadow-none bg-transparent">
342+
<CardHeader className="p-0">
343+
<div className="space-y-4">
362344
<EditableField
363-
key={`priority-${getCurrentValue('priority')}`}
345+
key={`title-${getCurrentValue('title')}`}
346+
value={getCurrentValue('title')}
347+
onSave={(value: any) => handleFieldChange('title', value)}
348+
placeholder="Enter title"
364349
className={cn(
365-
'inline-block',
366-
isFieldChanged('priority') && 'ring-2 ring-primary/20 bg-primary/5 rounded',
350+
'text-3xl font-bold',
351+
isFieldChanged('title') && 'ring-2 ring-primary/20 bg-primary/5',
367352
)}
368-
type="select"
369-
value={getCurrentValue('priority')}
370-
options={priorityOptions}
371-
onSave={(value: any) => handleFieldChange('priority', value)}
372353
>
373-
<DevlogPriorityTag priority={getCurrentValue('priority')} />
354+
<h1 className="text-3xl font-bold" title={getCurrentValue('title')}>
355+
{getCurrentValue('title')}
356+
</h1>
374357
</EditableField>
375358

376-
<EditableField
377-
key={`type-${getCurrentValue('type')}`}
378-
className={cn(
379-
'inline-block',
380-
isFieldChanged('type') && 'ring-2 ring-primary/20 bg-primary/5 rounded',
381-
)}
382-
type="select"
383-
value={getCurrentValue('type')}
384-
options={typeOptions}
385-
onSave={(value: any) => handleFieldChange('type', value)}
386-
>
387-
<DevlogTypeTag type={getCurrentValue('type')} />
388-
</EditableField>
389-
</div>
359+
<div className="flex flex-wrap gap-2">
360+
<EditableField
361+
key={`status-${getCurrentValue('status')}`}
362+
className={cn(
363+
'inline-block',
364+
isFieldChanged('status') && 'ring-2 ring-primary/20 bg-primary/5 rounded',
365+
)}
366+
type="select"
367+
value={getCurrentValue('status')}
368+
options={statusOptions}
369+
onSave={(value: any) => handleFieldChange('status', value)}
370+
>
371+
<DevlogStatusTag status={getCurrentValue('status')} />
372+
</EditableField>
373+
374+
<EditableField
375+
key={`priority-${getCurrentValue('priority')}`}
376+
className={cn(
377+
'inline-block',
378+
isFieldChanged('priority') && 'ring-2 ring-primary/20 bg-primary/5 rounded',
379+
)}
380+
type="select"
381+
value={getCurrentValue('priority')}
382+
options={priorityOptions}
383+
onSave={(value: any) => handleFieldChange('priority', value)}
384+
>
385+
<DevlogPriorityTag priority={getCurrentValue('priority')} />
386+
</EditableField>
387+
388+
<EditableField
389+
key={`type-${getCurrentValue('type')}`}
390+
className={cn(
391+
'inline-block',
392+
isFieldChanged('type') && 'ring-2 ring-primary/20 bg-primary/5 rounded',
393+
)}
394+
type="select"
395+
value={getCurrentValue('type')}
396+
options={typeOptions}
397+
onSave={(value: any) => handleFieldChange('type', value)}
398+
>
399+
<DevlogTypeTag type={getCurrentValue('type')} />
400+
</EditableField>
401+
</div>
390402

391-
<div className="flex space-x-4 text-sm text-muted-foreground">
392-
<span>ID: #{devlog.id}</span>
393-
<span title={formatTimeAgoWithTooltip(devlog.createdAt).fullDate}>
394-
Created: {formatTimeAgoWithTooltip(devlog.createdAt).timeAgo}
395-
</span>
396-
<span title={formatTimeAgoWithTooltip(devlog.updatedAt).fullDate}>
397-
Updated: {formatTimeAgoWithTooltip(devlog.updatedAt).timeAgo}
398-
</span>
403+
<div className="flex space-x-4 text-sm text-muted-foreground">
404+
<span>ID: #{devlog.id}</span>
405+
<span title={formatTimeAgoWithTooltip(devlog.createdAt).fullDate}>
406+
Created: {formatTimeAgoWithTooltip(devlog.createdAt).timeAgo}
407+
</span>
408+
<span title={formatTimeAgoWithTooltip(devlog.updatedAt).fullDate}>
409+
Updated: {formatTimeAgoWithTooltip(devlog.updatedAt).timeAgo}
410+
</span>
411+
</div>
399412
</div>
400-
</div>
401-
</CardHeader>
402-
</Card>
413+
</CardHeader>
414+
</Card>
415+
</div>
403416

404417
{/* Description */}
405418
<Card id="description">
@@ -608,7 +621,14 @@ export function DevlogDetails({
608621

609622
{/* Side Navigation */}
610623
<div className="w-64 flex-shrink-0">
611-
<DevlogAnchorNav devlog={devlog} notesCount={notes?.length || 0} />
624+
<div className="sticky top-44 space-y-4">
625+
<DevlogAnchorNav devlog={devlog} notesCount={notes?.length || 0} />
626+
{actions && (
627+
<div className="border-t pt-4">
628+
<div className="space-y-3">{actions}</div>
629+
</div>
630+
)}
631+
</div>
612632
</div>
613633
</div>
614634
</div>

packages/web/app/projects/[id]/devlogs/[devlogId]/ProjectDevlogDetailsPage.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,35 +147,39 @@ export function ProjectDevlogDetailsPage({ projectId, devlogId }: ProjectDevlogD
147147
}
148148

149149
const actions = (
150-
<div className="flex items-center gap-3">
150+
<div className="flex flex-col gap-2 w-full">
151151
{hasUnsavedChanges && (
152152
<>
153153
<Button
154154
variant="outline"
155155
onClick={() => discardHandlerRef.current?.()}
156156
disabled={isSaving}
157-
className="flex items-center gap-2"
157+
className="flex items-center gap-2 w-full justify-start"
158158
>
159159
<UndoIcon size={16} />
160160
Discard Changes
161161
</Button>
162162
<Button
163163
onClick={() => saveHandlerRef.current?.()}
164164
disabled={isSaving}
165-
className="flex items-center gap-2"
165+
className="flex items-center gap-2 w-full justify-start"
166166
>
167167
<SaveIcon size={16} />
168168
Save Changes
169169
</Button>
170170
</>
171171
)}
172-
<Button variant="outline" onClick={handleBack} className="flex items-center gap-2">
172+
<Button
173+
variant="outline"
174+
onClick={handleBack}
175+
className="flex items-center gap-2 w-full justify-start"
176+
>
173177
<ArrowLeftIcon size={16} />
174178
Back to List
175179
</Button>
176180
<Popover>
177181
<PopoverTrigger asChild>
178-
<Button variant="destructive" className="flex items-center gap-2">
182+
<Button variant="destructive" className="flex items-center gap-2 w-full justify-start">
179183
<TrashIcon size={16} />
180184
Delete
181185
</Button>
@@ -201,13 +205,14 @@ export function ProjectDevlogDetailsPage({ projectId, devlogId }: ProjectDevlogD
201205
);
202206

203207
return (
204-
<PageLayout actions={actions}>
208+
<PageLayout>
205209
<DevlogDetails
206210
devlog={devlog}
207211
hasUnsavedChanges={hasUnsavedChanges}
208212
onUpdate={handleUpdate}
209213
onDelete={handleDelete}
210214
onUnsavedChangesChange={handleUnsavedChangesChange}
215+
actions={actions}
211216
/>
212217
</PageLayout>
213218
);

0 commit comments

Comments
 (0)