useIntentStyles
Location: src/hooks/useIntentStyles.js
Overview
This file exports two hooks for working with intent styles -- the user-defined visual customizations applied to each of the six post intent types. useIntentStyles fetches a specific user's styles (read-only, for rendering their posts), while useMyIntentStyles fetches and manages the current authenticated user's styles with full CRUD capability.
Intent styles are stored in the intent_styles Supabase table, keyed by (user_id, intent).
useIntentStyles
Signature
function useIntentStyles(
userId: string | null
): {
styles: Record<string, IntentStyleRow>,
loading: boolean
}
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | null | Yes | The user ID whose intent styles to fetch. If null, loading resolves immediately with empty styles. |
Return Value
| Property | Type | Description |
|---|---|---|
styles | Record<string, IntentStyleRow> | Object keyed by intent key (e.g. thinking_out_loud), each value is the full row from intent_styles. |
loading | boolean | true while the fetch is in progress. |
Usage
function PostCard({ post }) {
const { styles, loading } = useIntentStyles(post.user_id);
if (loading) return <Skeleton />;
const intentStyle = styles[post.intent];
return (
<div style={{ background: intentStyle?.background_color }}>
{post.content}
</div>
);
}
useMyIntentStyles
Signature
function useMyIntentStyles(): {
styles: Record<string, IntentStyleRow>,
loading: boolean,
updateStyle: (intent: string, updates: Partial<IntentStyleRow>) => Promise<{ data: IntentStyleRow | null, error: Error | null }>,
updatePhoto: (intent: string, photoUrl: string) => Promise<{ data: IntentStyleRow | null, error: Error | null }>,
user: User | null
}
Parameters
None. The hook automatically resolves the current authenticated user via supabase.auth.getUser().
Return Value
| Property | Type | Description |
|---|---|---|
styles | Record<string, IntentStyleRow> | Current user's intent styles keyed by intent key. |
loading | boolean | true while the initial fetch is in progress. |
updateStyle | (intent, updates) => Promise | Upserts style properties for the given intent. Merges with existing row. Returns { data, error }. |
updatePhoto | (intent, photoUrl) => Promise | Convenience wrapper around updateStyle that sets photo_url. Returns { data, error }. |
user | User | null | The authenticated Supabase user object, or null if not logged in. |
Usage
function IntentStyleEditor() {
const { styles, loading, updateStyle } = useMyIntentStyles();
const handleColorChange = async (intent, color) => {
const { error } = await updateStyle(intent, { background_color: color });
if (error) console.error('Failed to save:', error);
};
if (loading) return <Skeleton />;
return (
<div>
{Object.entries(styles).map(([intent, style]) => (
<div key={intent}>
<span>{intent}</span>
<input
type="color"
value={style.background_color || '#ffffff'}
onChange={(e) => handleColorChange(intent, e.target.value)}
/>
</div>
))}
</div>
);
}
Last updated: 2026-02-07