Add image upload and category icons to map cards
- Add image upload functionality with file picker and URL input - Display custom uploaded images or category-specific FontAwesome icons - Add icon styles for all themes (dark, blue, light) - Map unique icons to each category and subcategory (News, Friends, Events, Market) - Update card templates to show 72x72px icon/image on the left - Add image preview and validation (max 5MB, images only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d8b4be20fd
commit
2c4c9a7065
|
|
@ -76,6 +76,11 @@ export default function MapView({
|
||||||
CREATE_CATEGORY_MAP.News[0]
|
CREATE_CATEGORY_MAP.News[0]
|
||||||
);
|
);
|
||||||
const [draftCoords, setDraftCoords] = useState(null);
|
const [draftCoords, setDraftCoords] = useState(null);
|
||||||
|
const [draftImage, setDraftImage] = useState("");
|
||||||
|
const [draftImageFile, setDraftImageFile] = useState(null);
|
||||||
|
const [draftImagePreview, setDraftImagePreview] = useState("");
|
||||||
|
const [useCustomImage, setUseCustomImage] = useState(false);
|
||||||
|
const [uploadingImage, setUploadingImage] = useState(false);
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
const [saveError, setSaveError] = useState("");
|
const [saveError, setSaveError] = useState("");
|
||||||
|
|
||||||
|
|
@ -219,6 +224,10 @@ export default function MapView({
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
setDraftTitle("");
|
setDraftTitle("");
|
||||||
setDraftBody("");
|
setDraftBody("");
|
||||||
|
setDraftImage("");
|
||||||
|
setDraftImageFile(null);
|
||||||
|
setDraftImagePreview("");
|
||||||
|
setUseCustomImage(false);
|
||||||
const main = mainFilter === "All" ? "News" : mainFilter;
|
const main = mainFilter === "All" ? "News" : mainFilter;
|
||||||
setDraftCategory(main);
|
setDraftCategory(main);
|
||||||
const list = CREATE_CATEGORY_MAP[main] || CREATE_CATEGORY_MAP.News;
|
const list = CREATE_CATEGORY_MAP[main] || CREATE_CATEGORY_MAP.News;
|
||||||
|
|
@ -234,6 +243,62 @@ export default function MapView({
|
||||||
setSearchQuery("");
|
setSearchQuery("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleImageFileChange = async (e) => {
|
||||||
|
const file = e.target.files?.[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
// Vérifier le type de fichier
|
||||||
|
if (!file.type.startsWith('image/')) {
|
||||||
|
setSaveError("Please select an image file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier la taille (max 5MB)
|
||||||
|
if (file.size > 5 * 1024 * 1024) {
|
||||||
|
setSaveError("Image must be less than 5MB");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDraftImageFile(file);
|
||||||
|
|
||||||
|
// Créer preview
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = () => {
|
||||||
|
setDraftImagePreview(reader.result);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
|
||||||
|
// Upload immédiatement
|
||||||
|
setUploadingImage(true);
|
||||||
|
setSaveError("");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('image', file);
|
||||||
|
|
||||||
|
const res = await fetch('/api/upload-image', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
credentials: 'include',
|
||||||
|
headers: token ? { 'Authorization': `Bearer ${token}` } : {},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error('Upload failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json();
|
||||||
|
setDraftImage(data.url || data.image_url);
|
||||||
|
setUploadingImage(false);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Image upload error:', err);
|
||||||
|
setSaveError('Failed to upload image');
|
||||||
|
setUploadingImage(false);
|
||||||
|
setDraftImageFile(null);
|
||||||
|
setDraftImagePreview("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmitPost = async () => {
|
const handleSubmitPost = async () => {
|
||||||
if (isSaving) return;
|
if (isSaving) return;
|
||||||
setSaveError("");
|
setSaveError("");
|
||||||
|
|
@ -282,8 +347,7 @@ export default function MapView({
|
||||||
try {
|
try {
|
||||||
setIsSaving(true);
|
setIsSaving(true);
|
||||||
|
|
||||||
const newPost = await createPost(
|
const payload = {
|
||||||
{
|
|
||||||
title: draftTitle.trim(),
|
title: draftTitle.trim(),
|
||||||
snippet: draftBody.trim() || draftTitle.trim(),
|
snippet: draftBody.trim() || draftTitle.trim(),
|
||||||
category:
|
category:
|
||||||
|
|
@ -292,9 +356,14 @@ export default function MapView({
|
||||||
lat,
|
lat,
|
||||||
lon: lng,
|
lon: lng,
|
||||||
author: authorName,
|
author: authorName,
|
||||||
},
|
};
|
||||||
token
|
|
||||||
);
|
if (useCustomImage && draftImage.trim()) {
|
||||||
|
payload.image_small = draftImage.trim();
|
||||||
|
payload.image_large = draftImage.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
const newPost = await createPost(payload, token);
|
||||||
|
|
||||||
if (newPost && newPost.id) handleIncomingPost(newPost);
|
if (newPost && newPost.id) handleIncomingPost(newPost);
|
||||||
|
|
||||||
|
|
@ -510,6 +579,68 @@ export default function MapView({
|
||||||
onChange={(e) => setDraftBody(e.target.value)}
|
onChange={(e) => setDraftBody(e.target.value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<div className="create-image-option">
|
||||||
|
<label style={{ display: "flex", alignItems: "center", gap: "8px", cursor: "pointer" }}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={useCustomImage}
|
||||||
|
onChange={(e) => setUseCustomImage(e.target.checked)}
|
||||||
|
/>
|
||||||
|
<span>Use custom image instead of category icon</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{useCustomImage && (
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: "8px" }}>
|
||||||
|
<div style={{ display: "flex", gap: "8px" }}>
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="image/*"
|
||||||
|
onChange={handleImageFileChange}
|
||||||
|
disabled={uploadingImage}
|
||||||
|
style={{ flex: 1 }}
|
||||||
|
/>
|
||||||
|
{uploadingImage && <span>Uploading...</span>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{draftImagePreview && (
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: "8px" }}>
|
||||||
|
<img
|
||||||
|
src={draftImagePreview}
|
||||||
|
alt="Preview"
|
||||||
|
style={{ width: "60px", height: "60px", objectFit: "cover", borderRadius: "8px" }}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
setDraftImageFile(null);
|
||||||
|
setDraftImagePreview("");
|
||||||
|
setDraftImage("");
|
||||||
|
}}
|
||||||
|
style={{ padding: "4px 8px", fontSize: "12px" }}
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div style={{ fontSize: "12px", color: "#888" }}>
|
||||||
|
Or paste an image URL:
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
className="create-input"
|
||||||
|
placeholder="https://example.com/image.jpg"
|
||||||
|
value={draftImageFile ? "" : draftImage}
|
||||||
|
onChange={(e) => {
|
||||||
|
setDraftImage(e.target.value);
|
||||||
|
setDraftImageFile(null);
|
||||||
|
setDraftImagePreview("");
|
||||||
|
}}
|
||||||
|
disabled={!!draftImageFile}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{saveError && <div className="create-error">{saveError}</div>}
|
{saveError && <div className="create-error">{saveError}</div>}
|
||||||
|
|
||||||
<div className="create-actions">
|
<div className="create-actions">
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@ export const TEMPLATE_SPECS = {
|
||||||
background: { type: "gradient", value: "newsBlue" },
|
background: { type: "gradient", value: "newsBlue" },
|
||||||
radius: 18,
|
radius: 18,
|
||||||
layers: [
|
layers: [
|
||||||
{ id: "badge", type: "chip", x: 12, y: 10, text: "NEWS", style: "chip.news" },
|
{ id: "icon", type: "icon", x: 12, y: 12, w: 72, h: 72, text: "\uf1ea", style: "text.icon", bind: "data.categoryIcon" },
|
||||||
{ id: "title", type: "text", x: 12, y: 34, w: 216, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
{ id: "imageOverlay", type: "image", x: 12, y: 12, w: 72, h: 72, bind: "data.image", radius: 12 },
|
||||||
{ id: "meta", type: "text", x: 12, y: 76, w: 216, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
{ id: "badge", type: "chip", x: 94, y: 10, text: "NEWS", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 94, y: 34, w: 134, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 94, y: 76, w: 134, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
full_spec: {
|
full_spec: {
|
||||||
|
|
@ -38,9 +40,11 @@ export const TEMPLATE_SPECS = {
|
||||||
background: { type: "gradient", value: "breakingRed" },
|
background: { type: "gradient", value: "breakingRed" },
|
||||||
radius: 18,
|
radius: 18,
|
||||||
layers: [
|
layers: [
|
||||||
{ id: "badge", type: "chip", x: 12, y: 10, text: "BREAKING", style: "chip.danger" },
|
{ id: "icon", type: "icon", x: 12, y: 12, w: 72, h: 72, text: "\uf0e7", style: "text.icon", bind: "data.categoryIcon" },
|
||||||
{ id: "title", type: "text", x: 12, y: 34, w: 216, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
{ id: "imageOverlay", type: "image", x: 12, y: 12, w: 72, h: 72, bind: "data.image", radius: 12 },
|
||||||
{ id: "meta", type: "text", x: 12, y: 76, w: 216, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
{ id: "badge", type: "chip", x: 94, y: 10, text: "BREAKING", style: "chip.danger" },
|
||||||
|
{ id: "title", type: "text", x: 94, y: 34, w: 134, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 94, y: 76, w: 134, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
full_spec: {
|
full_spec: {
|
||||||
|
|
@ -61,9 +65,11 @@ export const TEMPLATE_SPECS = {
|
||||||
background: { type: "gradient", value: "financeTeal" },
|
background: { type: "gradient", value: "financeTeal" },
|
||||||
radius: 18,
|
radius: 18,
|
||||||
layers: [
|
layers: [
|
||||||
{ id: "badge", type: "chip", x: 12, y: 10, text: "FINANCE", style: "chip.news" },
|
{ id: "icon", type: "icon", x: 12, y: 12, w: 72, h: 72, text: "\uf201", style: "text.icon", bind: "data.categoryIcon" },
|
||||||
{ id: "title", type: "text", x: 12, y: 34, w: 216, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
{ id: "imageOverlay", type: "image", x: 12, y: 12, w: 72, h: 72, bind: "data.image", radius: 12 },
|
||||||
{ id: "meta", type: "text", x: 12, y: 76, w: 216, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
{ id: "badge", type: "chip", x: 94, y: 10, text: "FINANCE", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 94, y: 34, w: 134, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 94, y: 76, w: 134, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
full_spec: {
|
full_spec: {
|
||||||
|
|
@ -84,9 +90,11 @@ export const TEMPLATE_SPECS = {
|
||||||
background: { type: "gradient", value: "marketGold" },
|
background: { type: "gradient", value: "marketGold" },
|
||||||
radius: 18,
|
radius: 18,
|
||||||
layers: [
|
layers: [
|
||||||
{ id: "badge", type: "chip", x: 12, y: 10, text: "MARKET", style: "chip.news" },
|
{ id: "icon", type: "icon", x: 12, y: 12, w: 72, h: 72, text: "\uf3d1", style: "text.icon", bind: "data.categoryIcon" },
|
||||||
{ id: "title", type: "text", x: 12, y: 34, w: 216, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
{ id: "imageOverlay", type: "image", x: 12, y: 12, w: 72, h: 72, bind: "data.image", radius: 12 },
|
||||||
{ id: "meta", type: "text", x: 12, y: 76, w: 216, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
{ id: "badge", type: "chip", x: 94, y: 10, text: "MARKET", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 94, y: 34, w: 134, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 94, y: 76, w: 134, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
full_spec: {
|
full_spec: {
|
||||||
|
|
@ -107,9 +115,11 @@ export const TEMPLATE_SPECS = {
|
||||||
background: { type: "gradient", value: "friendsGreen" },
|
background: { type: "gradient", value: "friendsGreen" },
|
||||||
radius: 18,
|
radius: 18,
|
||||||
layers: [
|
layers: [
|
||||||
{ id: "badge", type: "chip", x: 12, y: 10, text: "FRIENDS", style: "chip.news" },
|
{ id: "icon", type: "icon", x: 12, y: 12, w: 72, h: 72, text: "\uf500", style: "text.icon", bind: "data.categoryIcon" },
|
||||||
{ id: "title", type: "text", x: 12, y: 34, w: 216, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
{ id: "imageOverlay", type: "image", x: 12, y: 12, w: 72, h: 72, bind: "data.image", radius: 12 },
|
||||||
{ id: "meta", type: "text", x: 12, y: 76, w: 216, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
{ id: "badge", type: "chip", x: 94, y: 10, text: "FRIENDS", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 94, y: 34, w: 134, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 94, y: 76, w: 134, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
full_spec: {
|
full_spec: {
|
||||||
|
|
@ -130,9 +140,11 @@ export const TEMPLATE_SPECS = {
|
||||||
background: { type: "gradient", value: "eventsPurple" },
|
background: { type: "gradient", value: "eventsPurple" },
|
||||||
radius: 18,
|
radius: 18,
|
||||||
layers: [
|
layers: [
|
||||||
{ id: "badge", type: "chip", x: 12, y: 10, text: "EVENTS", style: "chip.news" },
|
{ id: "icon", type: "icon", x: 12, y: 12, w: 72, h: 72, text: "\uf073", style: "text.icon", bind: "data.categoryIcon" },
|
||||||
{ id: "title", type: "text", x: 12, y: 34, w: 216, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
{ id: "imageOverlay", type: "image", x: 12, y: 12, w: 72, h: 72, bind: "data.image", radius: 12 },
|
||||||
{ id: "meta", type: "text", x: 12, y: 76, w: 216, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
{ id: "badge", type: "chip", x: 94, y: 10, text: "EVENTS", style: "chip.news" },
|
||||||
|
{ id: "title", type: "text", x: 94, y: 34, w: 134, h: 42, bind: "data.headline", style: "text.title", maxLines: 2 },
|
||||||
|
{ id: "meta", type: "text", x: 94, y: 76, w: 134, h: 16, bind: "data.source", style: "text.meta", maxLines: 1 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
full_spec: {
|
full_spec: {
|
||||||
|
|
@ -195,6 +207,58 @@ export function getTemplateSpecForPost(post, variant /* "mini"|"full" */) {
|
||||||
return variant === "full" ? t.full_spec : t.mini_spec;
|
return variant === "full" ? t.full_spec : t.mini_spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCategoryIcon(post) {
|
||||||
|
const category = (post?.category || "").toUpperCase();
|
||||||
|
const subCategory = (post?.sub_category || "").toLowerCase();
|
||||||
|
|
||||||
|
// Mapping des icônes par catégorie et sous-catégorie
|
||||||
|
const iconMap = {
|
||||||
|
NEWS: {
|
||||||
|
default: "\uf1ea", // fa-newspaper
|
||||||
|
world: "\uf57d", // fa-globe-americas
|
||||||
|
politics: "\uf0a3", // fa-landmark-flag
|
||||||
|
tech: "\uf2db", // fa-microchip
|
||||||
|
finance: "\uf201", // fa-chart-line
|
||||||
|
local: "\uf3c5", // fa-map-marker-alt
|
||||||
|
},
|
||||||
|
FRIENDS: {
|
||||||
|
default: "\uf500", // fa-user-group
|
||||||
|
nearby: "\uf3c5", // fa-location-crosshairs
|
||||||
|
chats: "\uf086", // fa-comments
|
||||||
|
groups: "\uf0c0", // fa-users
|
||||||
|
stories: "\uf02d", // fa-book-open
|
||||||
|
favs: "\uf004", // fa-heart
|
||||||
|
},
|
||||||
|
EVENT: {
|
||||||
|
default: "\uf073", // fa-calendar
|
||||||
|
today: "\uf783", // fa-calendar-day
|
||||||
|
weekend: "\uf784", // fa-calendar-week
|
||||||
|
music: "\uf001", // fa-music
|
||||||
|
sports: "\uf1e3", // fa-football
|
||||||
|
local: "\uf3c5", // fa-map-marker-alt
|
||||||
|
},
|
||||||
|
EVENTS: {
|
||||||
|
default: "\uf073", // fa-calendar
|
||||||
|
today: "\uf783", // fa-calendar-day
|
||||||
|
weekend: "\uf784", // fa-calendar-week
|
||||||
|
music: "\uf001", // fa-music
|
||||||
|
sports: "\uf1e3", // fa-football
|
||||||
|
local: "\uf3c5", // fa-map-marker-alt
|
||||||
|
},
|
||||||
|
MARKET: {
|
||||||
|
default: "\uf3d1", // fa-store
|
||||||
|
actu: "\uf1ea", // fa-newspaper
|
||||||
|
tech: "\uf2db", // fa-microchip
|
||||||
|
finan: "\uf555", // fa-money-bill-trend-up
|
||||||
|
sport: "\uf434", // fa-basketball
|
||||||
|
deals: "\uf02b", // fa-tags
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const categoryIcons = iconMap[category] || iconMap.NEWS;
|
||||||
|
return categoryIcons[subCategory] || categoryIcons.default;
|
||||||
|
}
|
||||||
|
|
||||||
export function adaptPostToTemplateData(post) {
|
export function adaptPostToTemplateData(post) {
|
||||||
const headline = post?.title || "Untitled";
|
const headline = post?.title || "Untitled";
|
||||||
const author = post?.author ? `by ${post.author}` : "";
|
const author = post?.author ? `by ${post.author}` : "";
|
||||||
|
|
@ -203,5 +267,6 @@ export function adaptPostToTemplateData(post) {
|
||||||
const summary = post?.snippet || post?.body || "";
|
const summary = post?.snippet || post?.body || "";
|
||||||
const url = post?.url || "";
|
const url = post?.url || "";
|
||||||
const image = post?.image_large || post?.image_small || post?.image || post?.media_url || "";
|
const image = post?.image_large || post?.image_small || post?.image || post?.media_url || "";
|
||||||
return { headline, source, summary, url, image };
|
const categoryIcon = getCategoryIcon(post);
|
||||||
|
return { headline, source, summary, url, image, categoryIcon };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export const cardTokens = {
|
||||||
meta: { color: "#A9B3C7", fontSize: 12, fontWeight: 600 },
|
meta: { color: "#A9B3C7", fontSize: 12, fontWeight: 600 },
|
||||||
h1: { color: "#E9EEF8", fontSize: 22, fontWeight: 900, lineHeight: "26px" },
|
h1: { color: "#E9EEF8", fontSize: 22, fontWeight: 900, lineHeight: "26px" },
|
||||||
body: { color: "#D7DEED", fontSize: 14, fontWeight: 600, lineHeight: "18px" },
|
body: { color: "#D7DEED", fontSize: 14, fontWeight: 600, lineHeight: "18px" },
|
||||||
|
icon: { color: "rgba(255,255,255,0.3)", fontSize: 48, fontFamily: "Font Awesome 6 Free", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 900 },
|
||||||
},
|
},
|
||||||
chip: {
|
chip: {
|
||||||
news: { background: "rgba(78,161,255,0.18)", color: "#CFE6FF", fontWeight: 800, fontSize: 12, borderRadius: 999 },
|
news: { background: "rgba(78,161,255,0.18)", color: "#CFE6FF", fontWeight: 800, fontSize: 12, borderRadius: 999 },
|
||||||
|
|
@ -55,6 +56,7 @@ export const cardTokens = {
|
||||||
meta: { color: "#B5C7E6", fontSize: 12, fontWeight: 700 },
|
meta: { color: "#B5C7E6", fontSize: 12, fontWeight: 700 },
|
||||||
h1: { color: "#F0F7FF", fontSize: 22, fontWeight: 900, lineHeight: "26px" },
|
h1: { color: "#F0F7FF", fontSize: 22, fontWeight: 900, lineHeight: "26px" },
|
||||||
body: { color: "#D7E9FF", fontSize: 14, fontWeight: 700, lineHeight: "18px" },
|
body: { color: "#D7E9FF", fontSize: 14, fontWeight: 700, lineHeight: "18px" },
|
||||||
|
icon: { color: "rgba(255,255,255,0.3)", fontSize: 48, fontFamily: "Font Awesome 6 Free", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 900 },
|
||||||
},
|
},
|
||||||
chip: {
|
chip: {
|
||||||
news: { background: "rgba(56,189,248,0.18)", color: "#D7F3FF", fontWeight: 900, fontSize: 12, borderRadius: 999 },
|
news: { background: "rgba(56,189,248,0.18)", color: "#D7F3FF", fontWeight: 900, fontSize: 12, borderRadius: 999 },
|
||||||
|
|
@ -88,6 +90,7 @@ export const cardTokens = {
|
||||||
meta: { color: "#5B677A", fontSize: 12, fontWeight: 700 },
|
meta: { color: "#5B677A", fontSize: 12, fontWeight: 700 },
|
||||||
h1: { color: "#0B1220", fontSize: 22, fontWeight: 900, lineHeight: "26px" },
|
h1: { color: "#0B1220", fontSize: 22, fontWeight: 900, lineHeight: "26px" },
|
||||||
body: { color: "#1A2740", fontSize: 14, fontWeight: 600, lineHeight: "18px" },
|
body: { color: "#1A2740", fontSize: 14, fontWeight: 600, lineHeight: "18px" },
|
||||||
|
icon: { color: "rgba(0,0,0,0.15)", fontSize: 48, fontFamily: "Font Awesome 6 Free", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 900 },
|
||||||
},
|
},
|
||||||
chip: {
|
chip: {
|
||||||
news: { background: "rgba(30,107,255,0.12)", color: "#0B1220", fontWeight: 900, fontSize: 12, borderRadius: 999 },
|
news: { background: "rgba(30,107,255,0.12)", color: "#0B1220", fontWeight: 900, fontSize: 12, borderRadius: 999 },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue