* Localize calendar date pickers to the active UI locale. Pass the Inertia locale into Reka calendars, translate a11y labels, and use dayjs LL/LLL for DatePicker display text. Co-authored-by: Cursor <cursoragent@cursor.com> * Localize remaining dayjs date displays across the UI. Route list/calendar/preview timestamps through localized LL/LLL helpers so formats follow the active UI locale instead of English or Portuguese-locked patterns. Co-authored-by: Cursor <cursoragent@cursor.com> * Use scheduled-or-now timestamps in platform previews. Drive preview labels from the post schedule when set, localize Discord without dayjs calendar(), and expose a single formatPreviewPostedAt helper. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix preview schedule wiring and Discord/Facebook timestamp labels. Restore hasPickedTime from any saved scheduled_at, keep time on non-today Discord labels, and use a localized just-now fallback for unschedled Facebook previews. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix API key expiry day shift and tighten calendar range titles. Format date-only expiry in UTC calendar days, and use compact dayjs titles for calendar day/week headers. Co-authored-by: Cursor <cursoragent@cursor.com> * Replace frontend date source greps with Inertia API key assertions. Drop the Vue/TS file scanner and assert expiry calendar days through ApiKeyController props instead. Co-authored-by: Cursor <cursoragent@cursor.com> * Localize calendar week titles with day-first dayjs formats. Avoid English month-day order in week headers and chart axis labels so locales like pt-BR keep natural day-first dates. Co-authored-by: Cursor <cursoragent@cursor.com> * Split preview timestamp formatting into named platform helpers. Replace the style-switch formatPreviewPostedAt with clear per-platform helpers so call sites read as formatDiscordPreview / formatXPreview / etc. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
92 lines
2.5 KiB
Vue
92 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
|
|
import type { MediaItem } from '@/types/media';
|
|
|
|
import BlueskyPreview from './BlueskyPreview.vue';
|
|
import DiscordPreview from './DiscordPreview.vue';
|
|
import FacebookPreview from './FacebookPreview.vue';
|
|
import InstagramPreview from './InstagramPreview.vue';
|
|
import LinkedInPreview from './LinkedInPreview.vue';
|
|
import MastodonPreview from './MastodonPreview.vue';
|
|
import PinterestPreview from './PinterestPreview.vue';
|
|
import TelegramPreview from './TelegramPreview.vue';
|
|
import ThreadsPreview from './ThreadsPreview.vue';
|
|
import TikTokPreview from './TikTokPreview.vue';
|
|
import XPreview from './XPreview.vue';
|
|
import YouTubePreview from './YouTubePreview.vue';
|
|
|
|
interface SocialAccount {
|
|
id: string;
|
|
platform: string;
|
|
display_name: string;
|
|
username: string;
|
|
avatar_url: string | null;
|
|
}
|
|
|
|
interface Props {
|
|
platform: string;
|
|
socialAccount: SocialAccount | null | undefined;
|
|
content: string;
|
|
media: MediaItem[];
|
|
contentType?: string;
|
|
meta?: Record<string, any>;
|
|
/** Local scheduled datetime (datetime-local); falls back to now in previews. */
|
|
postedAt?: string | null;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
const resolvedSocialAccount = computed((): SocialAccount => props.socialAccount ?? {
|
|
id: '',
|
|
platform: props.platform,
|
|
display_name: '',
|
|
username: '',
|
|
avatar_url: null,
|
|
});
|
|
|
|
const previewComponent = computed(() => {
|
|
switch (props.platform) {
|
|
case 'linkedin':
|
|
case 'linkedin-page':
|
|
return LinkedInPreview;
|
|
case 'x':
|
|
return XPreview;
|
|
case 'facebook':
|
|
return FacebookPreview;
|
|
case 'instagram':
|
|
case 'instagram-facebook':
|
|
return InstagramPreview;
|
|
case 'threads':
|
|
return ThreadsPreview;
|
|
case 'tiktok':
|
|
return TikTokPreview;
|
|
case 'youtube':
|
|
return YouTubePreview;
|
|
case 'pinterest':
|
|
return PinterestPreview;
|
|
case 'bluesky':
|
|
return BlueskyPreview;
|
|
case 'mastodon':
|
|
return MastodonPreview;
|
|
case 'telegram':
|
|
return TelegramPreview;
|
|
case 'discord':
|
|
return DiscordPreview;
|
|
default:
|
|
return LinkedInPreview;
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<component
|
|
:is="previewComponent"
|
|
:social-account="resolvedSocialAccount"
|
|
:content="content"
|
|
:media="media"
|
|
:content-type="contentType"
|
|
:meta="meta"
|
|
:posted-at="postedAt"
|
|
/>
|
|
</template>
|