feat: integrate Tailwind CSS with custom theme and animations
Added Tailwind CSS and tw-animate-css imports to globals.css. Introduced a custom dark variant and an extensive @theme inline block with CSS variables for colors, radii, and animations. Included keyframes for shimmer-slide, spin-around, gradient, shine, and background-position-spin to enable consistent theming and dynamic UI effects across the application.
This commit is contained in:
1 parent
55c169bd6e
commit
5c1ccbc69a
67 files changed
+8984
-160
No files matched your search
@@ -0,0 +1,90 @@
|
||||
import { Currency } from "@/types/currency";
|
||||
|
||||
export function formatPrice(value: number, currency: Currency = "gp"): string {
|
||||
if (value >= 1000000) {
|
||||
const millions = value / 1000000;
|
||||
return `${millions.toFixed(1)}kk ${currency}`;
|
||||
}
|
||||
|
||||
if (value >= 1000) {
|
||||
const thousands = value / 1000;
|
||||
return `${thousands.toFixed(0)}k ${currency}`;
|
||||
}
|
||||
|
||||
return `${value.toLocaleString("pt-BR")} ${currency}`;
|
||||
}
|
||||
|
||||
export function convertGpToTc(gp: number): number {
|
||||
return Math.round(gp / 35000); // 1 TC ≈ 35.000 gp
|
||||
}
|
||||
|
||||
export function formatLargeNumber(value: number): string {
|
||||
if (value >= 1000000) {
|
||||
const millions = value / 1000000;
|
||||
return `${millions.toFixed(1)}kk`;
|
||||
}
|
||||
|
||||
if (value >= 1000) {
|
||||
const thousands = value / 1000;
|
||||
return `${thousands.toFixed(0)}k`;
|
||||
}
|
||||
|
||||
return value.toLocaleString("pt-BR");
|
||||
}
|
||||
|
||||
export function formatPriceWithTc(gp: number): string {
|
||||
const tc = convertGpToTc(gp);
|
||||
if (tc >= 1) {
|
||||
return `${formatPrice(gp)} (${tc} TC)`;
|
||||
}
|
||||
return formatPrice(gp);
|
||||
}
|
||||
|
||||
export function getRarityColor(rarity: string): string {
|
||||
switch (rarity) {
|
||||
case "legendary":
|
||||
return "text-orange-500";
|
||||
case "epic":
|
||||
return "text-purple-500";
|
||||
case "rare":
|
||||
return "text-blue-500";
|
||||
case "uncommon":
|
||||
return "text-green-500";
|
||||
case "common":
|
||||
return "text-gray-500";
|
||||
default:
|
||||
return "text-gray-500";
|
||||
}
|
||||
}
|
||||
|
||||
export function getRarityBgColor(rarity: string): string {
|
||||
switch (rarity) {
|
||||
case "legendary":
|
||||
return "bg-orange-500/10";
|
||||
case "epic":
|
||||
return "bg-purple-500/10";
|
||||
case "rare":
|
||||
return "bg-blue-500/10";
|
||||
case "uncommon":
|
||||
return "bg-green-500/10";
|
||||
case "common":
|
||||
return "bg-gray-500/10";
|
||||
default:
|
||||
return "bg-gray-500/10";
|
||||
}
|
||||
}
|
||||
|
||||
export function getRarityGlow(rarity: string): string {
|
||||
switch (rarity) {
|
||||
case "legendary":
|
||||
return "shadow-[0_0_15px_rgba(255,140,0,0.5)]";
|
||||
case "epic":
|
||||
return "shadow-[0_0_15px_rgba(155,89,182,0.5)]";
|
||||
case "rare":
|
||||
return "shadow-[0_0_15px_rgba(52,152,219,0.5)]";
|
||||
case "uncommon":
|
||||
return "shadow-[0_0_15px_rgba(46,204,113,0.5)]";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
import { TibiaItem, MarketOffer } from "@/types/item";
|
||||
|
||||
export const featuredItems: TibiaItem[] = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Armor of Fire",
|
||||
image: "/items/armor-of-fire.png",
|
||||
category: "armor",
|
||||
rarity: "legendary",
|
||||
stats: { armor: 16, weight: 120 },
|
||||
requirements: { level: 200, vocation: "Knight" },
|
||||
protections: { fire: 10 },
|
||||
price: { buy: 2500000, sell: 2200000, bid: 2350000 },
|
||||
priceHistory: { highest: 2800000, lowest: 2000000, average: 2350000 },
|
||||
dropLocation: "Fire Dragon Lair",
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Demon Helmet",
|
||||
image: "/items/demon-helmet.png",
|
||||
category: "helmet",
|
||||
rarity: "epic",
|
||||
stats: { armor: 10, weight: 29 },
|
||||
requirements: { level: 100, vocation: "Knight" },
|
||||
price: { buy: 50000, sell: 45000, bid: 47500 },
|
||||
priceHistory: { highest: 55000, lowest: 42000, average: 48500 },
|
||||
dropLocation: "Demon Hell",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Vampire Shield",
|
||||
image: "/items/vampire-shield.png",
|
||||
category: "shield",
|
||||
rarity: "epic",
|
||||
stats: { defense: 38, weight: 48 },
|
||||
requirements: { level: 150, vocation: "Knight" },
|
||||
price: { buy: 450000, sell: 420000, bid: 435000 },
|
||||
priceHistory: { highest: 480000, lowest: 400000, average: 435000 },
|
||||
dropLocation: "Vampire Crypt",
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
name: "Zaoan Helmet",
|
||||
image: "/items/zaoan-helmet.png",
|
||||
category: "helmet",
|
||||
rarity: "rare",
|
||||
stats: { armor: 9, weight: 43 },
|
||||
requirements: { level: 80, vocation: "Knight" },
|
||||
price: { buy: 85000, sell: 75000, bid: 80000 },
|
||||
priceHistory: { highest: 95000, lowest: 70000, average: 80000 },
|
||||
dropLocation: "Zao Palace",
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
name: "Magic Sword",
|
||||
image: "/items/magic-sword.png",
|
||||
category: "weapon",
|
||||
rarity: "rare",
|
||||
stats: { attack: 48, defense: 35, weight: 36 },
|
||||
requirements: { level: 75, vocation: "Knight" },
|
||||
price: { buy: 22000, sell: 20000, bid: 21000 },
|
||||
priceHistory: { highest: 28000, lowest: 20000, average: 24000 },
|
||||
dropLocation: "Magic Shop",
|
||||
},
|
||||
{
|
||||
id: "6",
|
||||
name: "Demonbone Amulet",
|
||||
image: "/items/demonbone-amulet.png",
|
||||
category: "amulet",
|
||||
rarity: "epic",
|
||||
stats: { armor: 2, weight: 8.5 },
|
||||
protections: { fire: 10 },
|
||||
price: { buy: 180000, sell: 165000, bid: 172500 },
|
||||
priceHistory: { highest: 200000, lowest: 150000, average: 175000 },
|
||||
dropLocation: "Demon Hell",
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
name: "Ornate Chestplate",
|
||||
image: "/items/ornate-chestplate.png",
|
||||
category: "armor",
|
||||
rarity: "legendary",
|
||||
stats: { armor: 18, weight: 185 },
|
||||
requirements: { level: 300, vocation: "Knight" },
|
||||
protections: { fire: 5, ice: 5 },
|
||||
price: { buy: 8500000, sell: 8200000, bid: 8350000 },
|
||||
priceHistory: { highest: 9000000, lowest: 8000000, average: 8400000 },
|
||||
dropLocation: "Ornate Chest",
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
name: "Ultimate Health Potion",
|
||||
image: "/items/uhp.png",
|
||||
category: "potion",
|
||||
rarity: "common",
|
||||
stats: { weight: 2 },
|
||||
stackable: true,
|
||||
price: { buy: 310, sell: 280, bid: 295 },
|
||||
priceHistory: { highest: 350, lowest: 280, average: 300 },
|
||||
dropLocation: "Magic Shop",
|
||||
},
|
||||
];
|
||||
|
||||
export const buyOffers: MarketOffer[] = [
|
||||
{
|
||||
id: "1",
|
||||
item: featuredItems[7], // Ultimate Health Potion
|
||||
seller: "EternalOblivion",
|
||||
price: 280000,
|
||||
quantity: 1000,
|
||||
type: "buy",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2), // 2 hours ago
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
item: featuredItems[1], // Demon Helmet
|
||||
seller: "PallySupreme",
|
||||
price: 48000,
|
||||
quantity: 1,
|
||||
type: "buy",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 45), // 45 min ago
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
item: featuredItems[5], // Demonbone Amulet
|
||||
seller: "MageDestroyer",
|
||||
price: 175000,
|
||||
quantity: 1,
|
||||
type: "buy",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 60), // 1 hour ago
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
item: featuredItems[4], // Magic Sword
|
||||
seller: "KnightLegacy",
|
||||
price: 25000,
|
||||
quantity: 1,
|
||||
type: "buy",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 3), // 3 hours ago
|
||||
},
|
||||
{
|
||||
id: "5",
|
||||
item: featuredItems[6], // Ornate Chestplate
|
||||
seller: "TibiaCollector",
|
||||
price: 8300000,
|
||||
quantity: 1,
|
||||
type: "buy",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 30), // 30 min ago
|
||||
},
|
||||
];
|
||||
|
||||
export const sellOffers: MarketOffer[] = [
|
||||
{
|
||||
id: "6",
|
||||
item: featuredItems[7], // Ultimate Health Potion
|
||||
seller: "EternalOblivion",
|
||||
price: 280000,
|
||||
quantity: 1000,
|
||||
type: "sell",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2), // 2 hours ago
|
||||
},
|
||||
{
|
||||
id: "7",
|
||||
item: featuredItems[1], // Demon Helmet
|
||||
seller: "PallySupreme",
|
||||
price: 48000,
|
||||
quantity: 1,
|
||||
type: "sell",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 45), // 45 min ago
|
||||
},
|
||||
{
|
||||
id: "8",
|
||||
item: featuredItems[5], // Demonbone Amulet
|
||||
seller: "MageDestroyer",
|
||||
price: 175000,
|
||||
quantity: 1,
|
||||
type: "sell",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 60), // 1 hour ago
|
||||
},
|
||||
{
|
||||
id: "9",
|
||||
item: featuredItems[4], // Magic Sword
|
||||
seller: "KnightLegacy",
|
||||
price: 25000,
|
||||
quantity: 1,
|
||||
type: "sell",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 60 * 3), // 3 hours ago
|
||||
},
|
||||
{
|
||||
id: "10",
|
||||
item: featuredItems[6], // Ornate Chestplate
|
||||
seller: "TibiaCollector",
|
||||
price: 8300000,
|
||||
quantity: 1,
|
||||
type: "sell",
|
||||
timestamp: new Date(Date.now() - 1000 * 60 * 30), // 30 min ago
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
Reference in new issue
Block a user