Merge pull request #130 from goteo/feat/componets-library
[feat] Components Library
This commit is contained in:
+5
-11
@@ -30,8 +30,8 @@ describe("Login Page", () => {
|
||||
cy.get("body").then(($body) => {
|
||||
if ($body.find("form#login").length > 0) {
|
||||
cy.get("form#login", { timeout: 10000 }).within(() => {
|
||||
cy.get("input#identifier", { timeout: 5000 }).should("exist");
|
||||
cy.get("input#password", { timeout: 5000 }).should("exist");
|
||||
cy.get('input[name="identifier"]', { timeout: 5000 }).should("exist");
|
||||
cy.get('input[name="password"]', { timeout: 5000 }).should("exist");
|
||||
});
|
||||
|
||||
cy.get('button[form="login"]', { timeout: 5000 }).should("be.visible");
|
||||
@@ -54,15 +54,9 @@ describe("Login Page", () => {
|
||||
});
|
||||
|
||||
it("should display floating labels correctly", () => {
|
||||
cy.get('label[for="identifier"]').should("exist");
|
||||
|
||||
cy.get("input#identifier").should("be.visible");
|
||||
|
||||
cy.get("input#identifier").type("root@goteo.org");
|
||||
|
||||
cy.get("input#identifier").should("have.value", "root@goteo.org");
|
||||
|
||||
cy.get('label[for="identifier"]').should("be.visible");
|
||||
cy.get('input[name="identifier"]').should("be.visible");
|
||||
cy.get('input[name="identifier"]').type("root@goteo.org");
|
||||
cy.get('input[name="identifier"]').should("have.value", "root@goteo.org");
|
||||
});
|
||||
|
||||
it("should validate form fields appropriately", () => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import importPlugin from "eslint-plugin-import";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
import cypressPlugin from "eslint-plugin-cypress";
|
||||
import unusedImportsPlugin from "eslint-plugin-unused-imports";
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
@@ -19,6 +20,8 @@ export default [
|
||||
".astro/**",
|
||||
".astro/**/*",
|
||||
"openapi/client/**",
|
||||
".github/**",
|
||||
"env.d.ts",
|
||||
],
|
||||
},
|
||||
{ files: ["**/*.{js,mjs,cjs,ts}"] },
|
||||
@@ -28,6 +31,7 @@ export default [
|
||||
{
|
||||
plugins: {
|
||||
import: importPlugin,
|
||||
"unused-imports": unusedImportsPlugin,
|
||||
},
|
||||
rules: {
|
||||
"import/order": [
|
||||
@@ -48,6 +52,7 @@ export default [
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
},
|
||||
},
|
||||
// Cypress configuration
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"marked": "^15.0.12",
|
||||
"media-icons": "^1.1.5",
|
||||
"svelte": "^5.33.13",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwindcss": "^4.1.8",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
@@ -51,6 +52,7 @@
|
||||
"eslint": "^9.28.0",
|
||||
"eslint-plugin-cypress": "^5.0.1",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-unused-imports": "^4.2.0",
|
||||
"flowbite": "^3.1.2",
|
||||
"flowbite-svelte": "1.5.2",
|
||||
"flowbite-svelte-icons": "^2.2.0",
|
||||
|
||||
Generated
+26
-5
@@ -56,6 +56,9 @@ importers:
|
||||
svelte:
|
||||
specifier: ^5.33.13
|
||||
version: 5.33.13
|
||||
tailwind-merge:
|
||||
specifier: ^3.3.1
|
||||
version: 3.3.1
|
||||
tailwindcss:
|
||||
specifier: ^4.1.8
|
||||
version: 4.1.8
|
||||
@@ -90,6 +93,9 @@ importers:
|
||||
eslint-plugin-import:
|
||||
specifier: ^2.31.0
|
||||
version: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))
|
||||
eslint-plugin-unused-imports:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0(@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))
|
||||
flowbite:
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2(rollup@4.36.0)
|
||||
@@ -1761,6 +1767,15 @@ packages:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
|
||||
eslint-plugin-unused-imports@4.2.0:
|
||||
resolution: {integrity: sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w==}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0
|
||||
eslint: ^9.0.0 || ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
optional: true
|
||||
|
||||
eslint-scope@8.3.0:
|
||||
resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@@ -3462,8 +3477,8 @@ packages:
|
||||
tailwind-merge@3.0.2:
|
||||
resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
|
||||
|
||||
tailwind-merge@3.3.0:
|
||||
resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==}
|
||||
tailwind-merge@3.3.1:
|
||||
resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==}
|
||||
|
||||
tailwind-variants@1.0.0:
|
||||
resolution: {integrity: sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA==}
|
||||
@@ -5744,6 +5759,12 @@ snapshots:
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-unused-imports@4.2.0(@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
eslint: 9.28.0(jiti@2.4.2)
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/eslint-plugin': 8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)
|
||||
|
||||
eslint-scope@8.3.0:
|
||||
dependencies:
|
||||
esrecurse: 4.3.0
|
||||
@@ -5962,7 +5983,7 @@ snapshots:
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
svelte: 5.33.13
|
||||
tailwind-merge: 3.3.0
|
||||
tailwind-merge: 3.3.1
|
||||
|
||||
flowbite-svelte@1.5.2(rollup@4.36.0)(svelte@5.33.13)(tailwindcss@4.1.8):
|
||||
dependencies:
|
||||
@@ -5972,7 +5993,7 @@ snapshots:
|
||||
clsx: 2.1.1
|
||||
flowbite: 3.1.2(rollup@4.36.0)
|
||||
svelte: 5.33.13
|
||||
tailwind-merge: 3.3.0
|
||||
tailwind-merge: 3.3.1
|
||||
tailwind-variants: 1.0.0(tailwindcss@4.1.8)
|
||||
tailwindcss: 4.1.8
|
||||
transitivePeerDependencies:
|
||||
@@ -7851,7 +7872,7 @@ snapshots:
|
||||
|
||||
tailwind-merge@3.0.2: {}
|
||||
|
||||
tailwind-merge@3.3.0: {}
|
||||
tailwind-merge@3.3.1: {}
|
||||
|
||||
tailwind-variants@1.0.0(tailwindcss@4.1.8):
|
||||
dependencies:
|
||||
|
||||
+2
-44
@@ -1,35 +1,12 @@
|
||||
import { z } from "astro/zod";
|
||||
import { ActionError, defineAction } from "astro:actions";
|
||||
|
||||
import { apiGatewayCheckoutsPost, apiGatewaysGetCollection } from "../openapi/client/index.ts";
|
||||
import { apiGatewayCheckoutsPost } from "../openapi/client/index.ts";
|
||||
import { getDefaultCurrency } from "../utils/consts.ts";
|
||||
|
||||
import type { GatewayCharge, ApiGatewaysNameGetResponse } from "../openapi/client/index.ts";
|
||||
import type { GatewayCharge } from "../openapi/client/index.ts";
|
||||
|
||||
const defaultCurrency = getDefaultCurrency();
|
||||
async function getPaymentGateways(): Promise<ApiGatewaysNameGetResponse[]> {
|
||||
if (import.meta.env.NODE_ENV === "test" || process.env.NODE_ENV === "test") {
|
||||
return [{ name: "test-gateway" }] as ApiGatewaysNameGetResponse[];
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiGatewaysGetCollection();
|
||||
const paymentGateways: ApiGatewaysNameGetResponse[] | undefined = response.data;
|
||||
|
||||
if (!paymentGateways) {
|
||||
throw new Error("Payment gateways not found");
|
||||
}
|
||||
|
||||
return paymentGateways;
|
||||
} catch (error) {
|
||||
console.error("Error fetching payment gateways:", error);
|
||||
// En caso de error, devolver un gateway por defecto o re-lanzar según necesites
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
let cachedPaymentGateways: ApiGatewaysNameGetResponse[] | null = null;
|
||||
let cachedPaymentGatewayNames: string[] | null = null;
|
||||
|
||||
export const payment = defineAction({
|
||||
accept: "form",
|
||||
@@ -61,23 +38,6 @@ export const payment = defineAction({
|
||||
const { t } = context.locals;
|
||||
|
||||
try {
|
||||
if (!cachedPaymentGateways) {
|
||||
cachedPaymentGateways = await getPaymentGateways();
|
||||
cachedPaymentGatewayNames = cachedPaymentGateways
|
||||
.map((gateway) => gateway.name)
|
||||
.filter((name): name is string => name !== undefined);
|
||||
}
|
||||
|
||||
if (
|
||||
cachedPaymentGatewayNames === null ||
|
||||
!cachedPaymentGatewayNames.includes(input.paymentMethod)
|
||||
) {
|
||||
throw new ActionError({
|
||||
code: "BAD_REQUEST",
|
||||
message: t("payment.error.invalidPaymentMethod"),
|
||||
});
|
||||
}
|
||||
|
||||
const cart = input.cartData;
|
||||
const charges: GatewayCharge[] = cart.items.map((item) => ({
|
||||
type: "single",
|
||||
@@ -115,8 +75,6 @@ export const payment = defineAction({
|
||||
},
|
||||
});
|
||||
|
||||
console.log({ response });
|
||||
|
||||
return { success: true, checkout: response.data };
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
@@ -5,21 +5,21 @@
|
||||
<section>
|
||||
<div class="flex flex-row gap-6">
|
||||
<button
|
||||
class="btn btn-primary cursor-pointer rounded-2xl border border-[#462949] px-4 py-2 font-bold text-[#575757]"
|
||||
class="btn btn-primary text-content border-secondary cursor-pointer rounded-2xl border px-4 py-2 font-bold"
|
||||
>
|
||||
{$t("contributions.grid.actions.refundToWallet")}</button
|
||||
>
|
||||
<button
|
||||
class="btn btn-secondary cursor-pointer rounded-2xl border border-[#462949] px-4 py-2 font-bold text-[#575757]"
|
||||
class="btn btn-secondary text-content border-secondary cursor-pointer rounded-2xl border px-4 py-2 font-bold"
|
||||
>
|
||||
{$t("contributions.grid.actions.refundToUser")}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-danger cursor-pointer rounded-2xl border border-[#462949] px-4 py-2 font-bold text-[#575757]"
|
||||
class="btn btn-danger text-content border-secondary cursor-pointer rounded-2xl border px-4 py-2 font-bold"
|
||||
>{$t("contributions.grid.actions.changeUser")}</button
|
||||
>
|
||||
<button
|
||||
class="btn btn-danger cursor-pointer rounded-2xl border border-[#462949] px-4 py-2 font-bold text-[#575757]"
|
||||
class="btn btn-danger text-content border-secondary cursor-pointer rounded-2xl border px-4 py-2 font-bold"
|
||||
>{$t("contributions.grid.actions.manageReward")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -44,11 +44,11 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-row items-center gap-4">
|
||||
<p class="text-tertiary font-bold">
|
||||
<p class="text-secondary font-bold">
|
||||
{$t("contributions.grid.content-footer.downloadDetails")}
|
||||
</p>
|
||||
<span
|
||||
class="text-tertiary flex flex-row items-center gap-2 rounded-2xl bg-[#E6E5F7] px-4 py-2 font-bold"
|
||||
class="text-secondary bg-purple-tint flex flex-row items-center gap-2 rounded-2xl px-4 py-2 font-bold"
|
||||
>
|
||||
<AnnotationIcon />
|
||||
{$t("contributions.grid.content-footer.annotations", {
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
<section class="flex flex-col gap-10">
|
||||
<div
|
||||
class="grid grid-cols-4 gap-x-8 gap-y-8 rounded-md bg-[#fbfafe] p-6 text-[16px] text-[#575757]"
|
||||
class="text-content grid grid-cols-4 gap-x-8 gap-y-8 rounded-md bg-[#fbfafe] p-6 text-[16px]"
|
||||
>
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="font-semibold">{$t("contributions.grid.details.operationTime")}</p>
|
||||
@@ -68,7 +68,7 @@
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="font-semibold">{$t("contributions.grid.details.trackingCodes.title")}</p>
|
||||
<button
|
||||
class="text-tertiary flex cursor-pointer items-start truncate whitespace-nowrap underline"
|
||||
class="text-secondary flex cursor-pointer items-start truncate whitespace-nowrap underline"
|
||||
title={trackingCodes.map((tc: Tracking) => tc.value).join(", ")}
|
||||
onclick={() => (trackingModal = true)}
|
||||
>
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
<Modal
|
||||
bind:open={trackingModal}
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent"
|
||||
class="!left-1/2 max-w-[800px] p-4 backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
title={$t("contributions.grid.details.trackingCodes.title")}
|
||||
headerClass="py-2"
|
||||
@@ -86,25 +86,25 @@
|
||||
<Table class="w-full table-fixed border-separate border-spacing-y-2">
|
||||
<TableHead>
|
||||
<TableHeadCell
|
||||
class="bg-secondary rounded-tl-lg rounded-bl-lg py-4 text-base whitespace-nowrap text-white"
|
||||
class="bg-tertiary rounded-tl-lg rounded-bl-lg py-4 text-base whitespace-nowrap text-white"
|
||||
>
|
||||
{$t("contributions.grid.details.trackingCodes.headers.title")}
|
||||
</TableHeadCell>
|
||||
<TableHeadCell
|
||||
class="bg-secondary rounded-tr-lg rounded-br-lg py-4 text-base whitespace-nowrap text-white"
|
||||
class="bg-tertiary rounded-tr-lg rounded-br-lg py-4 text-base whitespace-nowrap text-white"
|
||||
>
|
||||
{$t("contributions.grid.details.trackingCodes.headers.trackingCode")}
|
||||
</TableHeadCell>
|
||||
</TableHead>
|
||||
<TableBody class="text-base">
|
||||
{#each trackingCodes as item}
|
||||
<TableBodyRow class=" bg-[#FBFBFB]">
|
||||
<TableBodyRow class=" bg-light-surface">
|
||||
<TableBodyCell
|
||||
class="rounded-l-md border-t border-b border-l border-[#E6E5F7]"
|
||||
class="border-purple-tint rounded-l-md border-t border-b border-l"
|
||||
>{item.title}</TableBodyCell
|
||||
>
|
||||
<TableBodyCell
|
||||
class="rounded-r-md border-t border-r border-b border-[#E6E5F7] align-top"
|
||||
class="border-purple-tint rounded-r-md border-t border-r border-b align-top"
|
||||
>
|
||||
<div class="flex w-full items-center gap-4">
|
||||
<div
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
<Tooltip
|
||||
text={$t("contributions.tootip.copied")}
|
||||
tooltipClass="bg-[#462949] -translate-x-[90%]"
|
||||
tooltipClass="bg-secondary -translate-x-[90%]"
|
||||
className="h-[20px] w-[20px] cursor-copy shrink-0"
|
||||
>
|
||||
<button
|
||||
@@ -148,7 +148,7 @@
|
||||
<p class="font-semibold">{$t("contributions.grid.details.platformLinks.title")}</p>
|
||||
|
||||
<button
|
||||
class="text-tertiary flex cursor-pointer items-start truncate whitespace-nowrap underline"
|
||||
class="text-secondary flex cursor-pointer items-start truncate whitespace-nowrap underline"
|
||||
title={platformLinks
|
||||
.map((pl: Link) => pl.href ?? "")
|
||||
.filter(Boolean)
|
||||
@@ -165,7 +165,7 @@
|
||||
|
||||
<Modal
|
||||
bind:open={linksModal}
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent"
|
||||
class="!left-1/2 max-w-[800px] p-4 backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
title={$t("contributions.grid.details.platformLinks.title")}
|
||||
headerClass="py-2"
|
||||
@@ -173,36 +173,36 @@
|
||||
<Table class="w-full table-fixed border-separate border-spacing-y-2">
|
||||
<TableHead>
|
||||
<TableHeadCell
|
||||
class="bg-secondary rounded-tl-lg rounded-bl-lg py-4 text-base whitespace-nowrap text-white"
|
||||
class="bg-tertiary rounded-tl-lg rounded-bl-lg py-4 text-base whitespace-nowrap text-white"
|
||||
>
|
||||
{$t("contributions.grid.details.platformLinks.headers.type")}
|
||||
</TableHeadCell>
|
||||
<TableHeadCell
|
||||
class="bg-secondary border-t-lg border-b-lg py-4 text-base whitespace-nowrap text-white"
|
||||
class="bg-tertiary border-t-lg border-b-lg py-4 text-base whitespace-nowrap text-white"
|
||||
>
|
||||
{$t("contributions.grid.details.platformLinks.headers.rel")}
|
||||
</TableHeadCell>
|
||||
<TableHeadCell
|
||||
class="bg-secondary rounded-tr-lg rounded-br-lg py-4 text-base whitespace-nowrap text-white"
|
||||
class="bg-tertiary rounded-tr-lg rounded-br-lg py-4 text-base whitespace-nowrap text-white"
|
||||
>
|
||||
{$t("contributions.grid.details.platformLinks.headers.href")}
|
||||
</TableHeadCell>
|
||||
</TableHead>
|
||||
<TableBody class="text-base">
|
||||
{#each platformLinks as item}
|
||||
<TableBodyRow class=" bg-[#FBFBFB]">
|
||||
<TableBodyRow class=" bg-light-surface">
|
||||
<TableBodyCell
|
||||
class="rounded-l-md border-t border-b border-l border-[#E6E5F7]"
|
||||
class="border-purple-tint rounded-l-md border-t border-b border-l"
|
||||
>
|
||||
{item.type}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell
|
||||
class="rounded-l-md border-t border-b border-[#E6E5F7]"
|
||||
class="border-purple-tint rounded-l-md border-t border-b"
|
||||
>
|
||||
{item.rel}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell
|
||||
class="rounded-r-md border-t border-r border-b border-[#E6E5F7] align-top"
|
||||
class="border-purple-tint rounded-r-md border-t border-r border-b align-top"
|
||||
>
|
||||
<div class="flex w-full items-center gap-4">
|
||||
<div
|
||||
@@ -211,14 +211,14 @@
|
||||
>
|
||||
<a
|
||||
href={item.href}
|
||||
class=" text-tertiary"
|
||||
class=" text-secondary"
|
||||
target="_blank"
|
||||
>{item.href}
|
||||
</a>
|
||||
</div>
|
||||
<Tooltip
|
||||
text={$t("contributions.tootip.copied")}
|
||||
tooltipClass="bg-[#462949]"
|
||||
tooltipClass="bg-secondary"
|
||||
className="h-[20px] w-[20px] cursor-copy shrink-0"
|
||||
>
|
||||
<button
|
||||
|
||||
@@ -211,7 +211,7 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="relative flex flex-col gap-10 rounded-[40px] border border-[#E6E5F7] px-8 pt-6 pb-8 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class="border-purple-tint relative flex flex-col gap-10 rounded-[40px] border px-8 pt-6 pb-8 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
>
|
||||
<div class=" flex items-center justify-between gap-4">
|
||||
<Search onSelectTarget={handleSelectTarget} />
|
||||
@@ -220,7 +220,7 @@
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (showFilters = !showFilters)}
|
||||
class="border-tertiary text-tertiary relative inline-flex cursor-pointer items-center gap-2 rounded-3xl border px-6 py-4 font-bold text-nowrap"
|
||||
class="border-secondary text-secondary relative inline-flex cursor-pointer items-center gap-2 rounded-3xl border px-6 py-4 font-bold text-nowrap"
|
||||
>
|
||||
<span class="relative">
|
||||
<FiltersIcon />
|
||||
@@ -243,7 +243,7 @@
|
||||
<form onsubmit={handleSubmit} class="flex flex-col gap-6">
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<select
|
||||
class="border-tertiary w-full rounded-lg border p-4"
|
||||
class="border-secondary w-full rounded-lg border p-4"
|
||||
bind:value={selectedPaymentMethod}
|
||||
>
|
||||
<option value="" disabled selected
|
||||
@@ -255,7 +255,7 @@
|
||||
</select>
|
||||
|
||||
<select
|
||||
class="border-tertiary w-full rounded-lg border p-4"
|
||||
class="border-secondary w-full rounded-lg border p-4"
|
||||
bind:value={selectedChargeStatus}
|
||||
>
|
||||
<option value="" disabled
|
||||
@@ -267,7 +267,7 @@
|
||||
</select>
|
||||
|
||||
<select
|
||||
class="border-tertiary w-full rounded-lg border p-4"
|
||||
class="border-secondary w-full rounded-lg border p-4"
|
||||
bind:value={selectedRangeAmount}
|
||||
>
|
||||
<option value="" disabled
|
||||
@@ -287,7 +287,7 @@
|
||||
type="date"
|
||||
bind:value={dateFrom}
|
||||
onclick={(e) => (e.currentTarget as HTMLInputElement).showPicker?.()}
|
||||
class="border-tertiary w-full rounded-lg border p-4 pt-4"
|
||||
class="border-secondary w-full rounded-lg border p-4 pt-4"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -298,7 +298,7 @@
|
||||
<input
|
||||
id="dateTo"
|
||||
type="date"
|
||||
class="border-tertiary w-full rounded-lg border p-4 pt-4"
|
||||
class="border-secondary w-full rounded-lg border p-4 pt-4"
|
||||
bind:value={dateTo}
|
||||
onclick={(e) => (e.currentTarget as HTMLInputElement).showPicker?.()}
|
||||
/>
|
||||
@@ -308,7 +308,7 @@
|
||||
<div class="col-span-3 flex justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
class="bg-primary text-tertiary cursor-pointer rounded-3xl px-6 py-4 text-base font-bold"
|
||||
class="bg-primary text-secondary cursor-pointer rounded-3xl px-6 py-4 text-base font-bold"
|
||||
>
|
||||
{$t("contributions.filters.btns.apply")}
|
||||
</button>
|
||||
@@ -322,7 +322,7 @@
|
||||
type="button"
|
||||
onclick={handleExportCSV}
|
||||
disabled={isExporting}
|
||||
class="relative inline-flex cursor-pointer items-center gap-2 rounded-2xl bg-[#E6E5F7] px-4 py-2 font-medium text-nowrap text-gray-700 transition-colors disabled:cursor-not-allowed disabled:opacity-50"
|
||||
class="bg-purple-tint relative inline-flex cursor-pointer items-center gap-2 rounded-2xl px-4 py-2 font-medium text-nowrap text-gray-700 transition-colors disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{#if isExporting}
|
||||
<svg class="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
||||
|
||||
@@ -39,26 +39,26 @@
|
||||
<nav class="flex items-center gap-1">
|
||||
<button
|
||||
onclick={() => goToPage(1)}
|
||||
class="w-[40px] rounded border border-[#5757573D] py-1 text-center disabled:opacity-40
|
||||
class="border-content w-[40px] rounded border py-1 text-center disabled:opacity-40
|
||||
"
|
||||
disabled={currentPage === 1}>«</button
|
||||
>
|
||||
<button
|
||||
onclick={() => goToPage(currentPage - 1)}
|
||||
class="w-[40px] rounded border border-[#5757573D] py-1 text-center disabled:opacity-40"
|
||||
class="border-content w-[40px] rounded border py-1 text-center disabled:opacity-40"
|
||||
disabled={currentPage === 1}>‹</button
|
||||
>
|
||||
|
||||
{#each getVisiblePages() as page}
|
||||
{#if page === "..."}
|
||||
<span class="text-tertiary w-[40px] border-[#5757573D] text-center">…</span>
|
||||
<span class="text-secondary border-content w-[40px] text-center">…</span>
|
||||
{:else}
|
||||
<button
|
||||
onclick={() => typeof page === "number" && goToPage(page)}
|
||||
class="w-[40px] rounded border border-[#5757573D] py-1 text-center text-sm font-medium"
|
||||
class:bg-tertiary={currentPage === page}
|
||||
class="border-content w-[40px] rounded border py-1 text-center text-sm font-medium"
|
||||
class:bg-secondary={currentPage === page}
|
||||
class:text-primary={currentPage === page}
|
||||
class:text-tertiary={currentPage !== page}
|
||||
class:text-secondary={currentPage !== page}
|
||||
class:hover:bg-gray-200={currentPage !== page}
|
||||
>
|
||||
{page}
|
||||
@@ -68,26 +68,26 @@
|
||||
|
||||
<button
|
||||
onclick={() => goToPage(currentPage + 1)}
|
||||
class="w-[40px] rounded border border-[#5757573D] py-1 text-center disabled:opacity-40"
|
||||
class="border-content w-[40px] rounded border py-1 text-center disabled:opacity-40"
|
||||
disabled={currentPage === totalPages()}>›</button
|
||||
>
|
||||
<button
|
||||
onclick={() => goToPage(totalPages())}
|
||||
class="w-[40px] rounded border border-[#5757573D] py-1 text-center disabled:opacity-40"
|
||||
class="border-content w-[40px] rounded border py-1 text-center disabled:opacity-40"
|
||||
disabled={currentPage === totalPages()}>»</button
|
||||
>
|
||||
</nav>
|
||||
|
||||
{#if total > 0}
|
||||
<span class="text-sm font-bold text-[#575757]">
|
||||
<span class="text-content text-sm font-bold">
|
||||
{@html $t("contributions.pagination.showing", { items, total }, { allowHTML: true })}
|
||||
</span>
|
||||
{:else if total === 0 && !isLoading}
|
||||
<span class="text-sm font-bold text-[#575757]">
|
||||
<span class="text-content text-sm font-bold">
|
||||
{@html $t("contributions.pagination.noResults")}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-sm font-bold text-[#575757]">
|
||||
<span class="text-content text-sm font-bold">
|
||||
{@html $t("contributions.pagination.unloaded")}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
oninput={(e) =>
|
||||
handleInput(e.target instanceof HTMLInputElement ? e.target.value : "")}
|
||||
placeholder={$t("contributions.filters.search.placeholder")}
|
||||
class="border-tertiary w-full rounded-3xl border p-4"
|
||||
class="border-secondary w-full rounded-3xl border p-4"
|
||||
minlength="4"
|
||||
/>
|
||||
{#if query}
|
||||
|
||||
@@ -44,17 +44,17 @@
|
||||
<div class="relative h-[160px]">
|
||||
{#if !isLoaded}
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
<span class="text-[#575757]">Cargando...</span>
|
||||
<span class="text-content">Cargando...</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div bind:this={mainCarousel} class="main-carousel h-full opacity-{isLoaded ? 100 : 0}">
|
||||
{#each slides as { title, amount }}
|
||||
<div
|
||||
class="carousel-cell mr-6 flex h-full w-[22.5%] flex-col items-start justify-center gap-4 rounded-xl border border-[#e6e5f7] bg-[#faf9ff] p-8 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class="carousel-cell border-purple-tint bg-soft-purple mr-6 flex h-full w-[22.5%] flex-col items-start justify-center gap-4 rounded-xl border p-8 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
>
|
||||
<span class="text-base font-semibold text-[#575757]">{title}</span>
|
||||
<span class="text-secondary text-[40px]">{amount}</span>
|
||||
<span class="text-content text-base font-semibold">{title}</span>
|
||||
<span class="text-tertiary text-[40px]">{amount}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -507,12 +507,12 @@
|
||||
|
||||
<div class="flex justify-between">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<p class="font-bold text-[#575757]">
|
||||
<p class="text-content font-bold">
|
||||
{$t("contributions.filters.order.title")}
|
||||
</p>
|
||||
<select
|
||||
bind:value={selectedSort}
|
||||
class="border-tertiary text-tertiary min-w-[200px] rounded-sm py-1"
|
||||
class="border-secondary text-secondary min-w-[200px] rounded-sm py-1"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{#each sortOptions as option}
|
||||
@@ -522,13 +522,13 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<p class="font-bold text-[#575757]">
|
||||
<p class="text-content font-bold">
|
||||
{$t("contributions.filters.itemsPerPage.title")}
|
||||
</p>
|
||||
<select
|
||||
name="itemsPerPage"
|
||||
id="itemsPerPage"
|
||||
class="border-tertiary text-tertiary rounded-sm py-1"
|
||||
class="border-secondary text-secondary rounded-sm py-1"
|
||||
bind:value={itemsPerPage}
|
||||
disabled={isLoading}
|
||||
>
|
||||
@@ -540,10 +540,10 @@
|
||||
</div>
|
||||
|
||||
<Table class="w-full border-separate border-spacing-y-2">
|
||||
<TableHead class="bg-secondary">
|
||||
<TableHead class="bg-tertiary">
|
||||
{#each tableHeaders as header}
|
||||
<TableHeadCell
|
||||
class="py-4 text-base whitespace-nowrap text-[#FBFBFB] first:rounded-l-md last:rounded-r-md
|
||||
class="text-light-surface py-4 text-base whitespace-nowrap first:rounded-l-md last:rounded-r-md
|
||||
{header.sortable ? 'hover:bg-opacity-80 cursor-pointer select-none' : ''}"
|
||||
onclick={() => handleHeaderClick(header)}
|
||||
>
|
||||
@@ -579,44 +579,46 @@
|
||||
<TableBodyRow
|
||||
onclick={() => toggleRow(i)}
|
||||
class="{openRow === i
|
||||
? 'bg-[#FAF9FF]'
|
||||
: 'bg-white'} border border-[#e6e5f7] transition-colors hover:bg-[#FAF9FF]"
|
||||
? 'bg-soft-purple]'
|
||||
: 'bg-white'} border-purple-tint hover:bg-soft-purple] border transition-colors"
|
||||
>
|
||||
<TableBodyCell
|
||||
class="truncate rounded-l-md border-t border-b border-l border-[#E6E5F7] "
|
||||
class="border-purple-tint truncate rounded-l-md border-t border-b border-l "
|
||||
>{charge.targetDisplayName}</TableBodyCell
|
||||
>
|
||||
{#if charge.money.amount && charge.money.currency}
|
||||
<TableBodyCell class="border-t border-b border-[#E6E5F7]">
|
||||
<TableBodyCell class="border-purple-tint border-t border-b">
|
||||
{formatCurrency(charge.money.amount, charge.money.currency)}
|
||||
</TableBodyCell>
|
||||
{:else}
|
||||
<TableBodyCell class="border-t border-b border-[#E6E5F7]">—</TableBodyCell>
|
||||
<TableBodyCell class="border-purple-tint border-t border-b">—</TableBodyCell
|
||||
>
|
||||
{/if}
|
||||
<TableBodyCell class="truncate border-t border-b border-[#E6E5F7]"
|
||||
<TableBodyCell class="border-purple-tint truncate border-t border-b"
|
||||
>{charge.originDisplayName}</TableBodyCell
|
||||
>
|
||||
<TableBodyCell class="border-t border-b border-[#E6E5F7]">
|
||||
<TableBodyCell class="border-purple-tint border-t border-b">
|
||||
{$t(`contributions.table.rows.payments.${charge.paymentMethod}`)}
|
||||
</TableBodyCell>
|
||||
<TableBodyCell class="border-t border-b border-[#E6E5F7]">
|
||||
<TableBodyCell class="border-purple-tint border-t border-b">
|
||||
{getDate(charge.dateCreated).date}
|
||||
<p
|
||||
class="text-tertiary max-w-[180px] cursor-pointer truncate text-[12px] whitespace-nowrap underline"
|
||||
class="text-secondary max-w-[180px] cursor-pointer truncate text-[12px] whitespace-nowrap underline"
|
||||
title={charge.trackingCodes[0]?.value || "—"}
|
||||
>
|
||||
{charge.trackingCodes[0]?.value || "—"}
|
||||
</p>
|
||||
</TableBodyCell>
|
||||
<TableBodyCell class="border-t border-b border-[#E6E5F7]">
|
||||
<TableBodyCell class="border-purple-tint border-t border-b">
|
||||
<button
|
||||
class="border-secondary text-secondary flex items-center gap-1 rounded border px-3 py-1 text-base font-medium"
|
||||
class="border-tertiary text-tertiary flex items-center gap-1 rounded border px-3 py-1 text-base font-medium"
|
||||
>
|
||||
{$t(`contributions.table.rows.status.${charge.status}`)}
|
||||
</button>
|
||||
</TableBodyCell>
|
||||
|
||||
<TableBodyCell class="rounded-r-md border-t border-r border-b border-[#E6E5F7]"
|
||||
<TableBodyCell
|
||||
class="border-purple-tint rounded-r-md border-t border-r border-b"
|
||||
>{charge.refundToWallet}</TableBodyCell
|
||||
>
|
||||
</TableBodyRow>
|
||||
@@ -624,7 +626,7 @@
|
||||
<TableBodyRow>
|
||||
<TableBodyCell
|
||||
colspan={tableHeaders.length}
|
||||
class="rounded-lg border border-[#E6E5F7] bg-[#FAF9FF] shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class="border-purple-tint bg-soft-purple] rounded-lg border shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
>
|
||||
<DetailsRow
|
||||
platformLinks={charge.platformLinks}
|
||||
|
||||
@@ -4,7 +4,7 @@ const { t } = Astro.locals;
|
||||
|
||||
<button
|
||||
onclick="history.back()"
|
||||
class="group flex w-fit cursor-pointer items-center gap-2 text-[#575757] transition-colors duration-200 hover:text-[#3D3D3D]"
|
||||
class="group text-content flex w-fit cursor-pointer items-center gap-2 transition-colors duration-200 hover:text-black"
|
||||
>
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
<div class="relative w-full">
|
||||
<button
|
||||
onclick={() => scroll("left")}
|
||||
class="absolute top-1/2 -left-4 z-10 hidden h-10 w-10 -translate-y-1/2 rounded-full bg-[#e6e5f7] p-2 shadow-md disabled:opacity-50 lg:block"
|
||||
class="bg-purple-tint absolute top-1/2 -left-4 z-10 hidden h-10 w-10 -translate-y-1/2 rounded-full p-2 shadow-md disabled:opacity-50 lg:block"
|
||||
disabled={isAtStart}
|
||||
aria-label="Scroll left"
|
||||
>
|
||||
@@ -231,7 +231,7 @@
|
||||
|
||||
<button
|
||||
onclick={() => scroll("right")}
|
||||
class="absolute top-1/2 -right-4 z-10 hidden h-10 w-10 -translate-y-1/2 rounded-full bg-[#e6e5f7] p-2 shadow-md disabled:opacity-50 lg:block"
|
||||
class="bg-purple-tint absolute top-1/2 -right-4 z-10 hidden h-10 w-10 -translate-y-1/2 rounded-full p-2 shadow-md disabled:opacity-50 lg:block"
|
||||
disabled={isAtEnd}
|
||||
aria-label="Scroll right"
|
||||
>
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<div class="flex flex-col gap-10">
|
||||
{#each Object.entries($groupedByOwner) as [target, items]}
|
||||
<div class="flex flex-col gap-6">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-black text-2xl font-bold">
|
||||
{$t("project.owner")}
|
||||
{$displayNames[target] ?? ""}
|
||||
</h2>
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<p class="text-tertiary text-[32px] font-bold">
|
||||
<p class="text-secondary text-[32px] font-bold">
|
||||
{formatCurrency(item.amount, item.currency)}
|
||||
</p>
|
||||
<p class="text-tertiary font-bold">{item.title}</p>
|
||||
<p class="text-[#575757]">
|
||||
<p class="text-secondary font-bold">{item.title}</p>
|
||||
<p class="text-content">
|
||||
{#if typeof item.claimed === "number"}
|
||||
{#if item.claimed > 0}
|
||||
<span>{item.claimed} {$t("checkout.reward.claimed")} </span>
|
||||
@@ -53,7 +53,7 @@
|
||||
<MinusIcon />
|
||||
</button>
|
||||
<div class="relative flex w-4 items-center justify-center">
|
||||
<span class="text-tertiary absolute text-2xl font-bold"
|
||||
<span class="text-secondary absolute text-2xl font-bold"
|
||||
>{item.quantity}</span
|
||||
>
|
||||
</div>
|
||||
@@ -81,7 +81,7 @@
|
||||
id={`reward-checkbox-${item.key}`}
|
||||
class="accent-primary h-6 w-6 rounded"
|
||||
/>
|
||||
<label for="donation-checkbox" class=" text-[#575757]">
|
||||
<label for="donation-checkbox" class=" text-content">
|
||||
{$t("checkout.changeAddressLabel")}
|
||||
</label>
|
||||
</div> -->
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<form id="feedback" method="POST" class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-black text-2xl font-bold">
|
||||
{$t("payment.page-aproved.form-goal.title")}
|
||||
</h2>
|
||||
</div>
|
||||
@@ -35,7 +35,7 @@
|
||||
type="radio"
|
||||
name="type"
|
||||
value="organization"
|
||||
class="relative h-6 w-6 appearance-none rounded-full border border-[#855a96] after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:bg-purple-900 after:content-[''] checked:border-teal-400 checked:bg-teal-400 checked:after:block"
|
||||
class="border-secondary relative h-6 w-6 appearance-none rounded-full border after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:bg-purple-900 after:content-[''] checked:border-teal-400 checked:bg-teal-400 checked:after:block"
|
||||
/>
|
||||
</div>
|
||||
<span class="text-gray-700"
|
||||
@@ -46,11 +46,11 @@
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-black text-2xl font-bold">
|
||||
{$t("payment.page-aproved.form-review.title")}
|
||||
</h2>
|
||||
</div>
|
||||
<p class="text-[#575757]">{$t("payment.page-aproved.form-review.description")}</p>
|
||||
<p class="text-content">{$t("payment.page-aproved.form-review.description")}</p>
|
||||
</div>
|
||||
|
||||
<fieldset class="flex flex-col gap-6">
|
||||
@@ -74,7 +74,7 @@
|
||||
name="messageType"
|
||||
value="public"
|
||||
bind:group={messageType}
|
||||
class="relative h-6 w-6 appearance-none rounded-full border border-[#855a96] after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:bg-purple-900 after:content-[''] checked:border-teal-400 checked:bg-teal-400 checked:after:block"
|
||||
class="border-secondary relative h-6 w-6 appearance-none rounded-full border after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:bg-purple-900 after:content-[''] checked:border-teal-400 checked:bg-teal-400 checked:after:block"
|
||||
/>
|
||||
</div>
|
||||
<span class="text-gray-700"> Dejar un mensaje de forma pública </span>
|
||||
@@ -87,7 +87,7 @@
|
||||
</label>
|
||||
<textarea
|
||||
id="review-message"
|
||||
class="w-full appearance-none rounded-md border border-[#855a96] bg-white p-3 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="border-secondary focus:ring-secondary w-full appearance-none rounded-md border bg-white p-3 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
name="review"
|
||||
placeholder="Escribe tu mensaje de apoyo al impulsor..."
|
||||
rows="4"
|
||||
|
||||
@@ -34,7 +34,7 @@ const { accounting } = Astro.props;
|
||||
{
|
||||
(paymentGateways ?? []).map((gateway) => (
|
||||
<label
|
||||
class="flex cursor-pointer items-center justify-between gap-4 rounded-2xl border border-[#F3F3EF] px-6 py-4 shadow-sm transition-all hover:shadow-md"
|
||||
class="border-light-muted flex cursor-pointer items-center justify-between gap-4 rounded-2xl border px-6 py-4 shadow-sm transition-all hover:shadow-md"
|
||||
data-gateway={gateway.name}
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -47,7 +47,7 @@ const { accounting } = Astro.props;
|
||||
gateway.name !== "wallet" &&
|
||||
paymentGateways?.[0]?.name === gateway.name
|
||||
}
|
||||
class="after:bg-primary relative h-6 w-6 appearance-none rounded-full border border-[#462949] after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:content-[''] checked:border-[#462949] checked:bg-[#462949] checked:after:block"
|
||||
class="after:bg-primary border-secondary checked:border-secondary checked:bg-secondary relative h-6 w-6 appearance-none rounded-full border after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:content-[''] checked:after:block"
|
||||
/>
|
||||
<div class="flex flex-col leading-tight">
|
||||
<span class="font-semibold capitalize">{gateway.name}</span>
|
||||
@@ -188,12 +188,12 @@ const { accounting } = Astro.props;
|
||||
input.addEventListener("change", () => {
|
||||
labels.forEach((label) => {
|
||||
label.classList.remove("bg-teal-300", "text-[#2f1e2e]", "border-teal-400");
|
||||
label.classList.add("border-[#F3F3EF]");
|
||||
label.classList.add("border-light-muted");
|
||||
});
|
||||
|
||||
const selectedLabel = input.closest("label");
|
||||
if (selectedLabel) {
|
||||
selectedLabel.classList.remove("border-[#F3F3EF]");
|
||||
selectedLabel.classList.remove("border-light-muted");
|
||||
selectedLabel.classList.add("bg-teal-300", "text-[#2f1e2e]", "border-teal-400");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
{#each [1, 2, 3, 4] as i}
|
||||
<div
|
||||
class="relative z-10 flex h-4 w-4 items-center justify-center rounded-full border-2 transition-all duration-300"
|
||||
class:bg-tertiary={i <= step}
|
||||
class:bg-secondary={i <= step}
|
||||
class:bg-purple-tint={i > step}
|
||||
class:border-primary={i <= step}
|
||||
class:border-black={i > step}
|
||||
>
|
||||
{#if i <= step}
|
||||
<div class="bg-tertiary h-1.5 w-1.5 rounded-full"></div>
|
||||
<div class="bg-secondary h-1.5 w-1.5 rounded-full"></div>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class="flex flex-col gap-6 px-6 pt-6 pb-0">
|
||||
<div>
|
||||
<h2
|
||||
class={`flex items-center gap-2 text-[32px] font-semibold ${hasError ? "text-[#E94668]" : "text-[#462949]"}`}
|
||||
class={`flex items-center gap-2 text-[32px] font-semibold ${hasError ? "text-tertiary" : "text-secondary"}`}
|
||||
>
|
||||
{#if hasError}
|
||||
<span class="h-6 w-6">
|
||||
@@ -36,10 +36,10 @@
|
||||
{$t("checkout.summary.total.title")}
|
||||
</h2>
|
||||
<p
|
||||
class={`text-[56px] leading-tight font-bold ${hasError ? "text-[#E94668]" : "text-[#462949]"}`}
|
||||
class={`text-[56px] leading-tight font-bold ${hasError ? "text-tertiary" : "text-secondary"}`}
|
||||
>
|
||||
{formatCurrency(amount ?? $total, currency)}
|
||||
</p>
|
||||
</div>
|
||||
<hr class="bg-[#462949]" />
|
||||
<hr class="bg-secondary" />
|
||||
</div>
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
<div class="flex w-auto flex-col gap-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-black text-2xl font-bold">
|
||||
{$t("checkout.tipjar.community")}
|
||||
</h2>
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
toggleDonation(isChecked);
|
||||
}}
|
||||
/>
|
||||
<label for="donation-checkbox" class="text-tertiary">
|
||||
<label for="donation-checkbox" class="text-secondary">
|
||||
{$t("checkout.tipjar.checkboxLabel")}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@ const { accounting, defaultCurrency } = Astro.props;
|
||||
<!-- TODO: Merge with Btn "Continuar" -->
|
||||
<button
|
||||
id="submit-button"
|
||||
class="bg-primary cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
class="bg-primary text-secondary cursor-pointer rounded-3xl px-6 py-4 font-bold"
|
||||
type="submit"
|
||||
>
|
||||
{t("payment.global.btn.continue")}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<span class="block text-sm text-gray-600"
|
||||
>{$t("payment.wallet-confirmation.currentBalance")}</span
|
||||
>
|
||||
<p class="text-[32px] font-bold text-[#462949]">
|
||||
<p class="text-secondary text-[32px] font-bold">
|
||||
{formatCurrency(accounting.balance.amount, accounting.balance.currency)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -36,7 +36,7 @@
|
||||
<span class="block text-sm text-gray-600"
|
||||
>{$t("payment.wallet-confirmation.remainingBalance")}
|
||||
</span>
|
||||
<p id="cart-difference" class="text-[32px] font-bold text-[#462949]">
|
||||
<p id="cart-difference" class="text-secondary text-[32px] font-bold">
|
||||
{formatCurrency(accounting.balance.amount - $total, accounting.balance.currency)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="text-tertiary flex items-center gap-2 text-end text-2xl font-bold lg:justify-end">
|
||||
<div class="text-secondary flex items-center gap-2 text-end text-2xl font-bold lg:justify-end">
|
||||
{#if timeLeft.total > 0}
|
||||
<ClockIcon />
|
||||
<p>{$t("countdown.remaining")} {timeLeft.days}d {timeLeft.hours}h {timeLeft.minutes}m</p>
|
||||
|
||||
+28
-28
@@ -8,14 +8,14 @@ import FooterGmailIcon from "../svgs/footer/FooterGmailIcon.astro";
|
||||
const { t } = Astro.locals;
|
||||
---
|
||||
|
||||
<footer class="text-purple-tint bg-[#FAF9FF]">
|
||||
<footer class="text-purple-tint bg-soft-purple]">
|
||||
<!-- Funding Partners Section -->
|
||||
<div class="text-secondary border-purple-tint rounded-t-3xl border-2 border-b-0 py-10">
|
||||
<div class="text-tertiary border-purple-tint rounded-t-3xl border-2 border-b-0 py-10">
|
||||
<div class="wrapper">
|
||||
<div class="flex flex-col gap-8 lg:flex-row lg:items-center lg:justify-between">
|
||||
<!-- Funding Partners -->
|
||||
<div class="flex flex-col gap-6 md:flex-row md:items-center">
|
||||
<h3 class="text-tertiary text-base font-bold">{t("footer.funding.title")}</h3>
|
||||
<h3 class="text-secondary text-base font-bold">{t("footer.funding.title")}</h3>
|
||||
<div class="flex items-center gap-6">
|
||||
<!-- Funding Partner Logos -->
|
||||
<div class="flex items-center gap-4">
|
||||
@@ -40,7 +40,7 @@ const { t } = Astro.locals;
|
||||
|
||||
<!-- Part Of Section -->
|
||||
<div class="flex flex-col gap-4 md:flex-row md:items-center">
|
||||
<h3 class="text-tertiary text-base font-medium">
|
||||
<h3 class="text-secondary text-base font-medium">
|
||||
{t("footer.funding.partOf")}
|
||||
</h3>
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -79,21 +79,21 @@ const { t } = Astro.locals;
|
||||
</div>
|
||||
|
||||
<!-- Main Footer Content -->
|
||||
<div class="bg-tertiary rounded-t-3xl py-10">
|
||||
<div class="bg-secondary rounded-t-3xl py-10">
|
||||
<div class="wrapper">
|
||||
<div class="flex flex-row justify-between gap-8">
|
||||
<!-- Navigation Links -->
|
||||
<div class="flex flex-row gap-10">
|
||||
<!-- Collaborate -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="text-base leading-6 font-bold text-[#faf9ff]">
|
||||
<h4 class="text-soft-purple text-base leading-6 font-bold">
|
||||
{t("footer.navigation.collaborate.title")}
|
||||
</h4>
|
||||
<ul class="space-y-1 text-sm leading-6">
|
||||
<li>
|
||||
<a
|
||||
href="/create-project"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.collaborate.createProject")}
|
||||
</a>
|
||||
@@ -101,7 +101,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/matchfunding"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.collaborate.matchfunding")}
|
||||
</a>
|
||||
@@ -109,7 +109,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/workshops"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.collaborate.workshops")}
|
||||
</a>
|
||||
@@ -119,14 +119,14 @@ const { t } = Astro.locals;
|
||||
|
||||
<!-- Help -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="text-base leading-6 font-bold text-[#faf9ff]">
|
||||
<h4 class="text-soft-purple text-base leading-6 font-bold">
|
||||
{t("footer.navigation.help.title")}
|
||||
</h4>
|
||||
<ul class="space-y-1 text-sm leading-6">
|
||||
<li>
|
||||
<a
|
||||
href="/faqs"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.help.faqs")}
|
||||
</a>
|
||||
@@ -134,7 +134,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/contact"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.help.contact")}
|
||||
</a>
|
||||
@@ -142,7 +142,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/tax-calculator"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.help.taxCalculator")}
|
||||
</a>
|
||||
@@ -152,14 +152,14 @@ const { t } = Astro.locals;
|
||||
|
||||
<!-- About Goteo -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="text-base leading-6 font-bold text-[#faf9ff]">
|
||||
<h4 class="text-soft-purple text-base leading-6 font-bold">
|
||||
{t("footer.navigation.aboutGoteo.title")}
|
||||
</h4>
|
||||
<ul class="space-y-1 text-sm leading-6">
|
||||
<li>
|
||||
<a
|
||||
href="/about"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.aboutGoteo.whoWeAre")}
|
||||
</a>
|
||||
@@ -167,7 +167,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/benefits"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.aboutGoteo.goteoBenefits")}
|
||||
</a>
|
||||
@@ -175,7 +175,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/impact"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.aboutGoteo.foundationImpact")}
|
||||
</a>
|
||||
@@ -183,7 +183,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/platoniq"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.aboutGoteo.platoniqFoundation")}
|
||||
</a>
|
||||
@@ -193,14 +193,14 @@ const { t } = Astro.locals;
|
||||
|
||||
<!-- For Users -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="text-base leading-6 font-bold text-[#faf9ff]">
|
||||
<h4 class="text-soft-purple text-base leading-6 font-bold">
|
||||
{t("footer.navigation.forUsers.title")}
|
||||
</h4>
|
||||
<ul class="space-y-1 text-sm leading-6">
|
||||
<li>
|
||||
<a
|
||||
href="/wallet"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.forUsers.rechargeWallet")}
|
||||
</a>
|
||||
@@ -208,7 +208,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/certificate"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.forUsers.downloadCertificate")}
|
||||
</a>
|
||||
@@ -216,7 +216,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/funds"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.forUsers.accessComplementaryFunds")}
|
||||
</a>
|
||||
@@ -224,7 +224,7 @@ const { t } = Astro.locals;
|
||||
<li>
|
||||
<a
|
||||
href="/program"
|
||||
class="text-purple-tint transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple transition-colors"
|
||||
>
|
||||
{t("footer.navigation.forUsers.designFundingProgram")}
|
||||
</a>
|
||||
@@ -244,32 +244,32 @@ const { t } = Astro.locals;
|
||||
</div>
|
||||
|
||||
<!-- Bottom Footer -->
|
||||
<div class="bg-tertiary pb-10">
|
||||
<div class="bg-secondary pb-10">
|
||||
<div class="wrapper">
|
||||
<div class="flex flex-col gap-6 lg:flex-row lg:items-center lg:justify-between">
|
||||
<!-- Legal Links -->
|
||||
<div class="flex flex-wrap gap-8">
|
||||
<a
|
||||
href="/terms"
|
||||
class="text-purple-tint text-xs leading-4 font-medium transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple text-xs leading-4 font-medium transition-colors"
|
||||
>
|
||||
{t("footer.legal.termsOfUse")}
|
||||
</a>
|
||||
<a
|
||||
href="/privacy"
|
||||
class="text-purple-tint text-xs leading-4 font-medium transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple text-xs leading-4 font-medium transition-colors"
|
||||
>
|
||||
{t("footer.legal.privacyPolicy")}
|
||||
</a>
|
||||
<a
|
||||
href="/licenses"
|
||||
class="text-purple-tint text-xs leading-4 font-medium transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple text-xs leading-4 font-medium transition-colors"
|
||||
>
|
||||
{t("footer.legal.licenses")}
|
||||
</a>
|
||||
<a
|
||||
href="/stats"
|
||||
class="text-purple-tint text-xs leading-4 font-medium transition-colors hover:text-[#faf9ff]"
|
||||
class="text-purple-tint hover:text-soft-purple text-xs leading-4 font-medium transition-colors"
|
||||
>
|
||||
{t("footer.legal.stats")}
|
||||
</a>
|
||||
|
||||
@@ -55,9 +55,7 @@ if (accessToken) {
|
||||
<UiLanguages />
|
||||
</li>
|
||||
<li class="flex items-center md:hidden">
|
||||
<button class="p-1" aria-label="Menu">
|
||||
<MenuIcon />
|
||||
</button>
|
||||
<MenuIcon />
|
||||
</li>
|
||||
<li class="hidden items-center md:flex">
|
||||
<MenuIcon />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts">
|
||||
import SearchIcon from "../svgs/SearchIcon.svelte";
|
||||
import Button from "./library/Button.svelte";
|
||||
|
||||
function openSearch() {
|
||||
window.location.href = "/search";
|
||||
@@ -11,17 +12,9 @@
|
||||
</script>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
onclick={openSearch}
|
||||
class="flex justify-center items-center gap-2 px-4 py-2 rounded-2xl bg-purple-tint cursor-pointer hover:bg-[#D0CFED] transition-colors"
|
||||
>
|
||||
<Button size="sm" kind="secondary" onclick={openSearch}>
|
||||
<SearchIcon width="16" height="16" />
|
||||
Buscar
|
||||
</button>
|
||||
<button
|
||||
onclick={goToCreateProject}
|
||||
class="flex justify-center items-center gap-2 px-4 py-2 rounded-2xl bg-primary cursor-pointer hover:bg-[#38bfa7] transition-colors"
|
||||
>
|
||||
Crea tu proyecto
|
||||
</button>
|
||||
</Button>
|
||||
<Button size="sm" kind="primary" onclick={goToCreateProject}>Crea tu proyecto</Button>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@ const { t } = Astro.locals;
|
||||
<div class="grid items-center gap-12 lg:grid-cols-2">
|
||||
<!-- Hero Content -->
|
||||
<div class="space-y-8">
|
||||
<h1 class="text-tertiary text-4xl leading-tight font-bold lg:text-5xl xl:text-6xl">
|
||||
<h1 class="text-secondary text-4xl leading-tight font-bold lg:text-5xl xl:text-6xl">
|
||||
{t("hero.title")}
|
||||
</h1>
|
||||
|
||||
@@ -20,12 +20,12 @@ const { t } = Astro.locals;
|
||||
<!-- CTA Buttons -->
|
||||
<div class="flex flex-col gap-4 sm:flex-row">
|
||||
<!-- <button
|
||||
class="text-tertiary bg-light-accent rounded-full border-0 px-8 py-4 font-semibold whitespace-nowrap transition-all duration-200 hover:opacity-90"
|
||||
class="text-secondary bg-light-accent rounded-full border-0 px-8 py-4 font-semibold whitespace-nowrap transition-all duration-200 hover:opacity-90"
|
||||
>
|
||||
{t("hero.buttons.discover")}
|
||||
</button>
|
||||
<button
|
||||
class="bg-primary text-tertiary rounded-full border-0 px-8 py-4 font-semibold whitespace-nowrap transition-all duration-200 hover:opacity-90"
|
||||
class="bg-primary text-secondary rounded-full border-0 px-8 py-4 font-semibold whitespace-nowrap transition-all duration-200 hover:opacity-90"
|
||||
>
|
||||
{t("hero.buttons.impulse")}
|
||||
</button> -->
|
||||
|
||||
@@ -1,48 +1,29 @@
|
||||
---
|
||||
import TextInput from "./library/TextInput.svelte";
|
||||
|
||||
const { t } = Astro.locals;
|
||||
---
|
||||
|
||||
<div>
|
||||
<div class="mt-8 sm:w-full sm:max-w-md">
|
||||
<form id="login" method="POST" class="flex flex-col gap-4">
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
type="text"
|
||||
id="identifier"
|
||||
name="identifier"
|
||||
placeholder=""
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
required
|
||||
/>
|
||||
<label
|
||||
for="identifier"
|
||||
class="absolute top-1 left-4 text-[10px] font-medium text-gray-500 transition-all peer-placeholder-shown:top-4 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-400 peer-focus:top-1 peer-focus:text-[10px] peer-focus:text-gray-500"
|
||||
>
|
||||
{t("login.form.email")}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
required
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder=""
|
||||
required
|
||||
/>
|
||||
<label
|
||||
for="password"
|
||||
class="absolute top-1 left-4 text-[10px] font-medium text-gray-500 transition-all peer-placeholder-shown:top-4 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-400 peer-focus:top-1 peer-focus:text-[10px] peer-focus:text-gray-500"
|
||||
>
|
||||
{t("login.form.password")}
|
||||
</label>
|
||||
</div>
|
||||
<form id="login" method="POST" class="flex flex-col gap-6">
|
||||
<TextInput
|
||||
name="identifier"
|
||||
placeholder={t("login.form.email")}
|
||||
required={true}
|
||||
labelText={t("login.form.email")}
|
||||
/>
|
||||
<TextInput
|
||||
type="password"
|
||||
name="password"
|
||||
placeholder={t("login.form.password")}
|
||||
required={true}
|
||||
labelText={t("login.form.password")}
|
||||
/>
|
||||
</form>
|
||||
|
||||
<div id="login-error-content" class="mt-4 text-center text-red-500"></div>
|
||||
<!-- <a href="#" class="text-tertiary font-bold underline">
|
||||
<!-- <a href="#" class="text-secondary font-bold underline">
|
||||
{t("login.page.forgotPassword")}
|
||||
</a> -->
|
||||
</div>
|
||||
@@ -88,11 +69,13 @@ const { t } = Astro.locals;
|
||||
errorContent.innerText = error.message;
|
||||
}
|
||||
|
||||
if (hasCart) {
|
||||
window.location.href = `/payment`;
|
||||
}
|
||||
if (!error) {
|
||||
if (hasCart) {
|
||||
window.location.href = `/payment`;
|
||||
}
|
||||
|
||||
window.location.href = `/`;
|
||||
window.location.href = `/`;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,7 +4,7 @@ const { t } = Astro.locals;
|
||||
|
||||
<button
|
||||
id="btn-logout"
|
||||
class="bg-primary w-fit cursor-pointer rounded-xl px-4 py-2 font-bold text-[#462949]"
|
||||
class="bg-primary text-secondary w-fit cursor-pointer rounded-xl px-4 py-2 font-bold"
|
||||
>
|
||||
{t("logout.label")}
|
||||
</button>
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { categories } from "../../utils/categories";
|
||||
import SearchIcon from "../../svgs/SearchIcon.svelte";
|
||||
import { t } from "../../i18n/store";
|
||||
|
||||
let showCategoryMenu = $state(false);
|
||||
|
||||
function toggleCategoryMenu() {
|
||||
console.log("Button clicked! Current state:", showCategoryMenu);
|
||||
showCategoryMenu = !showCategoryMenu;
|
||||
console.log("New state:", showCategoryMenu);
|
||||
}
|
||||
|
||||
function closeCategoryMenu() {
|
||||
showCategoryMenu = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<nav>
|
||||
<!-- Mobile Layout -->
|
||||
<div class="flex w-full max-w-screen items-center gap-4 px-4 py-4 md:hidden">
|
||||
<!-- Search Bar -->
|
||||
<div class="relative flex-1">
|
||||
<input
|
||||
type="search"
|
||||
placeholder={$t("navigation.search.placeholder")}
|
||||
class="placeholder:text-tertiary w-full rounded-full border-none bg-[#E6E5F7] p-3 pl-12 text-sm placeholder:font-bold focus:bg-white focus:ring-2 focus:ring-purple-500 focus:outline-none"
|
||||
/>
|
||||
<div class="absolute top-1/2 left-4 h-4 w-4 -translate-y-1/2 transform text-gray-500">
|
||||
<SearchIcon />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Categories Button (Mobile Only) -->
|
||||
<div class="relative">
|
||||
<button
|
||||
class="text-tertiary rounded-full border border-black bg-white px-6 py-3 text-sm font-bold whitespace-nowrap transition-colors hover:bg-gray-50"
|
||||
onclick={toggleCategoryMenu}
|
||||
>
|
||||
{$t("navigation.categories")}
|
||||
</button>
|
||||
|
||||
<!-- Categories Dropdown Menu -->
|
||||
{#if showCategoryMenu}
|
||||
<div
|
||||
class="absolute top-full right-0 z-50 mt-2 max-h-64 w-48 overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-lg"
|
||||
>
|
||||
<div class="p-2">
|
||||
{#each categories as category}
|
||||
<button
|
||||
class="text-tertiary w-full rounded-md px-3 py-2 text-left text-sm font-medium hover:bg-gray-100"
|
||||
onclick={closeCategoryMenu}
|
||||
>
|
||||
{$t(category.translationKey)}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Desktop Layout -->
|
||||
<div class="hidden justify-between gap-6 overflow-x-auto px-10 py-6 md:flex">
|
||||
<div class="relative">
|
||||
<input
|
||||
type="search"
|
||||
placeholder={$t("navigation.search.placeholder")}
|
||||
class="placeholder:text-tertiary w-full rounded-full border-none bg-[#E6E5F7] p-3 pl-12 placeholder:font-bold focus:bg-white focus:ring-2 focus:ring-purple-500 focus:outline-none"
|
||||
/>
|
||||
<div class="absolute top-1/2 left-4 h-5 w-5 -translate-y-1/2 transform text-gray-500">
|
||||
<SearchIcon />
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative min-w-52"></div>
|
||||
|
||||
<!-- Horizontal Categories (Desktop Only) -->
|
||||
{#each categories as category}
|
||||
<button class="text-tertiary font-bold">{$t(category.translationKey)}</button>
|
||||
{/each}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Overlay to close menu when clicking outside -->
|
||||
{#if showCategoryMenu}
|
||||
<div
|
||||
class="fixed inset-0 z-40"
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
onclick={closeCategoryMenu}
|
||||
onkeydown={(e) => e.key === "Escape" && closeCategoryMenu()}
|
||||
></div>
|
||||
{/if}
|
||||
@@ -22,7 +22,7 @@ const { t } = Astro.locals;
|
||||
type="radio"
|
||||
name="type"
|
||||
value="organization"
|
||||
class="relative h-6 w-6 appearance-none rounded-full border border-[#855a96] after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:bg-purple-900 after:content-[''] checked:border-teal-400 checked:bg-teal-400 checked:after:block"
|
||||
class="border-secondary relative h-6 w-6 appearance-none rounded-full border after:absolute after:top-1/2 after:left-1/2 after:hidden after:h-2 after:w-2 after:-translate-x-1/2 after:-translate-y-1/2 after:transform after:rounded-full after:bg-purple-900 after:content-[''] checked:border-teal-400 checked:bg-teal-400 checked:after:block"
|
||||
/>
|
||||
<span class="text-gray-700">{t("register.form.userType.organization")}</span>
|
||||
</label>
|
||||
@@ -31,7 +31,7 @@ const { t } = Astro.locals;
|
||||
<div class="flex flex-row gap-4">
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="peer border-secondary focus:ring-secondary w-full rounded-md border px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
required
|
||||
type="text"
|
||||
id="firstname"
|
||||
@@ -49,7 +49,7 @@ const { t } = Astro.locals;
|
||||
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="peer border-secondary focus:ring-secondary w-full rounded-md border px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
required
|
||||
type="text"
|
||||
id="lastname"
|
||||
@@ -72,7 +72,7 @@ const { t } = Astro.locals;
|
||||
id="identifier"
|
||||
name="identifier"
|
||||
placeholder=""
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="peer border-secondary focus:ring-secondary w-full rounded-md border px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
required
|
||||
/>
|
||||
<label
|
||||
@@ -85,7 +85,7 @@ const { t } = Astro.locals;
|
||||
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="peer border-secondary focus:ring-secondary w-full rounded-md border px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
required
|
||||
type="password"
|
||||
id="password"
|
||||
@@ -101,7 +101,7 @@ const { t } = Astro.locals;
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full text-xs font-medium text-[#575757]">
|
||||
<div class="text-content relative w-full text-xs font-medium">
|
||||
<span> {t("register.form.validation.password.minLength")}</span>
|
||||
</div>
|
||||
|
||||
@@ -111,7 +111,7 @@ const { t } = Astro.locals;
|
||||
<input
|
||||
type="checkbox"
|
||||
id="toggle-dni"
|
||||
class="accent-primary mt-1 h-5 w-5 shrink-0 border border-gray-400 text-[#855a96] focus:ring-[#855a96]"
|
||||
class="accent-primary text-secondary focus:ring-secondary mt-1 h-5 w-5 shrink-0 border border-gray-400"
|
||||
/>
|
||||
<span class="text-sm text-gray-700"
|
||||
>{t("register.individual.taxId.msgDeduction")}</span
|
||||
@@ -141,7 +141,7 @@ const { t } = Astro.locals;
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
id="fields-organization-razonSocial"
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="peer border-secondary focus:ring-secondary w-full rounded-md border px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
type="text"
|
||||
id="razonSocial"
|
||||
name="razonSocial"
|
||||
@@ -159,7 +159,7 @@ const { t } = Astro.locals;
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
id="fields-organization-cif"
|
||||
class="peer w-full rounded-md border border-[#855a96] px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:ring-[#855a96] focus:outline-none"
|
||||
class="peer border-secondary focus:ring-secondary w-full rounded-md border px-4 pt-6 pb-2 text-base text-gray-700 placeholder-gray-400 focus:ring-1 focus:outline-none"
|
||||
type="text"
|
||||
id="cif"
|
||||
name="cif"
|
||||
@@ -180,7 +180,7 @@ const { t } = Astro.locals;
|
||||
<input
|
||||
type="checkbox"
|
||||
id="terms"
|
||||
class="accent-primary mt-1 h-5 w-5 shrink-0 border border-gray-400 text-[#855a96] focus:ring-[#855a96]"
|
||||
class="accent-primary text-secondary focus:ring-secondary mt-1 h-5 w-5 shrink-0 border border-gray-400"
|
||||
/>
|
||||
<span class="text-sm text-gray-700">
|
||||
{t("register.form.termsCheckbox")}
|
||||
@@ -190,21 +190,13 @@ const { t } = Astro.locals;
|
||||
<input
|
||||
type="checkbox"
|
||||
id="cookies"
|
||||
class="accent-primary mt-1 h-5 w-5 shrink-0 border border-gray-400 text-[#855a96] focus:ring-[#855a96]"
|
||||
class="accent-primary text-secondary focus:ring-secondary mt-1 h-5 w-5 shrink-0 border border-gray-400"
|
||||
/>
|
||||
<span class="text-sm text-gray-700">
|
||||
{t("register.form.policiesCheckbox")}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- TODO: Merge with Btn "Continuar" -->
|
||||
<button
|
||||
class="bg-primary cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
type="submit"
|
||||
>
|
||||
{t("register.form.btnSubmit")}</button
|
||||
>
|
||||
</form>
|
||||
<div id="register-error-content" class="mt-4 text-center text-red-500"></div>
|
||||
</div>
|
||||
@@ -299,7 +291,7 @@ const { t } = Astro.locals;
|
||||
dniInput.classList.remove("border-[#e6e6e6]", "focus:ring-transparent");
|
||||
|
||||
if (isChecked) {
|
||||
dniInput.classList.add("border-[#855a96]", "focus:ring-[#855a96]");
|
||||
dniInput.classList.add("border-secondary", "focus:ring-secondary");
|
||||
dniInput.classList.remove("cursor-not-allowed");
|
||||
labelInput.classList.remove("cursor-not-allowed");
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import UserIcon from "../svgs/UserIcon.svelte";
|
||||
import { formatCurrency } from "../utils/currencies";
|
||||
import { renderMarkdown } from "../utils/renderMarkdown";
|
||||
import Button from "./library/Button.svelte";
|
||||
import RewardModal from "./RewardModal.svelte";
|
||||
|
||||
let {
|
||||
@@ -32,12 +33,12 @@
|
||||
</script>
|
||||
|
||||
<li
|
||||
class="flex basis-1/3 flex-col items-center justify-between gap-4 gap-8 rounded-4xl border border-[#F3F3EF] bg-[#FFF] p-6 shadow-[0px_1px_3px_0px_#0000001A] md:gap-8"
|
||||
class="border-light-muted flex basis-1/3 flex-col items-center justify-between gap-4 gap-8 rounded-4xl border bg-[#FFF] p-6 shadow-[0px_1px_3px_0px_#0000001A] md:gap-8"
|
||||
class:opacity-50={!isAvailable}
|
||||
class:cursor-not-allowed={!isAvailable}
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<h3 class="text-tertiary line-clamp-2 w-full text-left text-2xl font-semibold">
|
||||
<h3 class="text-secondary line-clamp-2 w-full text-left text-2xl font-semibold">
|
||||
<div>
|
||||
{@html $t(
|
||||
"rewards.by-amount",
|
||||
@@ -60,7 +61,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-auto flex w-full justify-between">
|
||||
<div class="text-tertiary flex items-center justify-between gap-2 text-sm font-bold">
|
||||
<div class="text-secondary flex items-center justify-between gap-2 text-sm font-bold">
|
||||
<UserIcon />
|
||||
<span>
|
||||
{@html $t(
|
||||
@@ -71,7 +72,7 @@
|
||||
</span>
|
||||
</div>
|
||||
{#if reward.isFinite}
|
||||
<div class="text-tertiary flex items-center justify-between gap-2 text-sm font-bold">
|
||||
<div class="text-secondary flex items-center justify-between gap-2 text-sm font-bold">
|
||||
<UnitIcon />
|
||||
<span>
|
||||
{@html $t(
|
||||
@@ -84,16 +85,14 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (openModal = true)}
|
||||
<Button
|
||||
kind="secondary"
|
||||
class="w-full"
|
||||
disabled={!isAvailable}
|
||||
class:cursor-pointer={isAvailable}
|
||||
class:cursor-not-allowed={!isAvailable}
|
||||
class="text-tertiary inline-block w-full rounded-3xl bg-[#E6E5F7] px-6 py-4 font-bold transition"
|
||||
onclick={() => (openModal = true)}
|
||||
>
|
||||
{$t("reward.donate")}
|
||||
{formatCurrency(reward.money.amount, reward.money.currency)}
|
||||
</button>
|
||||
</Button>
|
||||
</li>
|
||||
<RewardModal {reward} {project} bind:open={openModal} />
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { cart } from "../stores/cart";
|
||||
import { renderMarkdown } from "../utils/renderMarkdown";
|
||||
import { onMount } from "svelte";
|
||||
import Button from "./library/Button.svelte";
|
||||
|
||||
let {
|
||||
open = $bindable(false),
|
||||
@@ -65,12 +66,12 @@
|
||||
|
||||
<Modal
|
||||
bind:open
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent"
|
||||
class="fixed top-1/2 left-1/2 w-full max-w-[900px] -translate-x-1/2 -translate-y-1/2 rounded-3xl bg-white p-6 shadow-lg backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
headerClass="py-2"
|
||||
>
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="text-tertiary flex w-full flex-col gap-6 text-left text-[40px] font-semibold">
|
||||
<div class="text-secondary flex w-full flex-col gap-6 text-left text-[40px] font-semibold">
|
||||
<h3>
|
||||
{@html $t(
|
||||
"rewards.by-amount-or-more",
|
||||
@@ -124,7 +125,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full gap-2">
|
||||
<div class="text-tertiary flex items-center justify-between gap-2 text-sm font-bold">
|
||||
<div class="text-secondary flex items-center justify-between gap-2 text-sm font-bold">
|
||||
<UserIcon />
|
||||
<span>
|
||||
{@html $t(
|
||||
@@ -136,7 +137,7 @@
|
||||
</div>
|
||||
{#if reward.isFinite}
|
||||
<div
|
||||
class="text-tertiary flex items-center justify-between gap-2 text-sm font-bold"
|
||||
class="text-secondary flex items-center justify-between gap-2 text-sm font-bold"
|
||||
>
|
||||
<UnitIcon />
|
||||
<span>
|
||||
@@ -150,20 +151,12 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-row gap-4">
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => updateAmount("close")}
|
||||
class="text-tertiary border-tertiary inline-block w-full cursor-pointer rounded-3xl border bg-[#FFF] px-6 py-4 font-bold transition"
|
||||
>
|
||||
<Button kind="ghost" onclick={() => updateAmount("close")} class="w-full">
|
||||
{$t("rewards.reward-donate-close")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => updateAmount("checkout")}
|
||||
class="text-tertiary bg-primary bg inline-block w-full cursor-pointer rounded-3xl px-6 py-4 font-bold transition"
|
||||
>
|
||||
</Button>
|
||||
<Button onclick={() => updateAmount("checkout")} class="w-full">
|
||||
{$t("rewards.donation-free.btn")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
- useDataAttributes: Whether to toggle [data-tab-content] elements (default: true)
|
||||
|
||||
Design System:
|
||||
- Active: border-primary, text-tertiary
|
||||
- Inactive: border-purple-tint, text-secondary
|
||||
- Active: border-primary, text-secondary
|
||||
- Inactive: border-purple-tint, text-tertiary
|
||||
- Hover: opacity-80
|
||||
- Transition: 200ms ease
|
||||
-->
|
||||
@@ -85,8 +85,8 @@
|
||||
<button
|
||||
class="box-border flex items-center justify-center gap-2 overflow-visible rounded-tl-lg rounded-tr-lg border-b-2 px-6 py-2 transition-all duration-200 {currentTab ===
|
||||
tab.id
|
||||
? 'border-primary text-tertiary'
|
||||
: 'border-purple-tint text-secondary'}"
|
||||
? 'border-primary text-secondary'
|
||||
: 'border-purple-tint text-tertiary'}"
|
||||
onclick={() => handleTabClick(tab.id)}
|
||||
data-tab={tab.id}
|
||||
>
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
</script>
|
||||
|
||||
<div class="flex w-auto gap-2">
|
||||
<div class="border-secondary flex items-center gap-2 rounded-sm border px-2 py-1">
|
||||
<div class="flex items-center gap-2 rounded-sm border border-black px-2 py-1">
|
||||
<BookmarkIcon />
|
||||
{$t(`categories.${project.category}`)}
|
||||
</div>
|
||||
<div class="border-secondary flex items-center gap-2 rounded-sm border px-2 py-1">
|
||||
<div class="flex items-center gap-2 rounded-sm border border-black px-2 py-1">
|
||||
<MapIcon />{displayName(project.territory)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import type { Project, ProjectReward } from "../openapi/client";
|
||||
import { formatCurrency } from "../utils/currencies";
|
||||
import { renderMarkdown } from "../utils/renderMarkdown";
|
||||
import Button from "./library/Button.svelte";
|
||||
import RewardModal from "./RewardModal.svelte";
|
||||
|
||||
let {
|
||||
@@ -30,12 +31,12 @@
|
||||
</script>
|
||||
|
||||
<li
|
||||
class="flex basis-1/3 flex-col items-center justify-between gap-8 rounded-4xl border border-[#F3F3EF] bg-[#FFF] p-6 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class="border-light-muted flex basis-1/3 flex-col items-center justify-between gap-8 rounded-4xl border bg-[#FFF] p-6 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class:opacity-50={!isAvailable}
|
||||
class:cursor-not-allowed={!isAvailable}
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<h3 class="text-tertiary line-clamp-2 w-full text-left text-2xl font-semibold">
|
||||
<h3 class="text-secondary line-clamp-2 w-full text-left text-2xl font-semibold">
|
||||
{reward.title}
|
||||
</h3>
|
||||
|
||||
@@ -48,16 +49,14 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (openModal = true)}
|
||||
<Button
|
||||
kind="secondary"
|
||||
class="w-full"
|
||||
disabled={!isAvailable}
|
||||
class:cursor-pointer={isAvailable}
|
||||
class:cursor-not-allowed={!isAvailable}
|
||||
class="text-tertiary inline-block w-full rounded-3xl bg-[#E6E5F7] px-6 py-4 font-bold transition"
|
||||
onclick={() => (openModal = true)}
|
||||
>
|
||||
{$t("reward.donate")}
|
||||
{formatCurrency(reward.money.amount, reward.money.currency)}
|
||||
</button>
|
||||
</Button>
|
||||
</li>
|
||||
<RewardModal {reward} {project} bind:open={openModal} />
|
||||
|
||||
@@ -5,7 +5,7 @@ const languagesJSON = JSON.stringify(Object.keys(languagesList));
|
||||
---
|
||||
|
||||
<select
|
||||
class="rounded-lg border-none bg-[#fbfbfb] font-bold shadow-sm"
|
||||
class="bg-light-surface rounded-lg border-none font-bold shadow-sm"
|
||||
name="language"
|
||||
id="language-select"
|
||||
data-languages={languagesJSON}
|
||||
|
||||
@@ -20,10 +20,10 @@ const blogPost = {
|
||||
<div class="flex flex-col gap-6 p-10 lg:min-h-0 lg:flex-1">
|
||||
<!-- Main Content -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2 class="text-tertiary text-4xl leading-12 font-bold">
|
||||
<h2 class="text-secondary text-4xl leading-12 font-bold">
|
||||
{blogPost.title}
|
||||
</h2>
|
||||
<p class="text-tertiary text-base leading-6">
|
||||
<p class="text-secondary text-base leading-6">
|
||||
{blogPost.excerpt}
|
||||
</p>
|
||||
</div>
|
||||
@@ -32,9 +32,9 @@ const blogPost = {
|
||||
<div class="flex">
|
||||
<a
|
||||
href={blogPost.href}
|
||||
class="group border-tertiary hover:bg-tertiary flex items-center justify-center gap-2 rounded-3xl border px-6 py-4 transition-all duration-200"
|
||||
class="group border-secondary hover:bg-secondary flex items-center justify-center gap-2 rounded-3xl border px-6 py-4 transition-all duration-200"
|
||||
>
|
||||
<span class="text-tertiary text-base font-bold group-hover:text-white">
|
||||
<span class="text-secondary text-base font-bold group-hover:text-white">
|
||||
{blogPost.buttonText}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
@@ -47,7 +47,7 @@ const imageHeight = "h-[389px]"; // Same height for both sizes
|
||||
class="bg-light-muted flex items-center gap-2 rounded border border-white px-2 py-1"
|
||||
>
|
||||
<ClockIcon />
|
||||
<span class="text-tertiary text-sm font-bold whitespace-nowrap">
|
||||
<span class="text-secondary text-sm font-bold whitespace-nowrap">
|
||||
{t("home.campaigns.daysRemaining", { days: campaign.daysRemaining })}
|
||||
</span>
|
||||
</div> -->
|
||||
@@ -57,7 +57,7 @@ const imageHeight = "h-[389px]"; // Same height for both sizes
|
||||
campaign.hasMatchfunding && (
|
||||
<div class="bg-light-muted flex items-center gap-2 rounded border border-white px-2 py-1">
|
||||
<MatchFundingIcon />
|
||||
<span class="text-tertiary text-sm font-bold whitespace-nowrap">
|
||||
<span class="text-secondary text-sm font-bold whitespace-nowrap">
|
||||
{t("home.campaigns.matchfunding")}
|
||||
</span>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@ const imageHeight = "h-[389px]"; // Same height for both sizes
|
||||
{
|
||||
campaign.tags?.map((tag) => (
|
||||
<div class="bg-light-muted flex items-center gap-2 rounded border border-white px-2 py-1">
|
||||
<span class="text-tertiary text-sm font-bold whitespace-nowrap">
|
||||
<span class="text-secondary text-sm font-bold whitespace-nowrap">
|
||||
{tag}
|
||||
</span>
|
||||
</div>
|
||||
@@ -79,7 +79,7 @@ const imageHeight = "h-[389px]"; // Same height for both sizes
|
||||
|
||||
<!-- Project Content -->
|
||||
<div class={`flex flex-col gap-6 ${size === "large" ? "flex-1" : ""}`}>
|
||||
<h3 class="text-tertiary max-h-16 overflow-hidden text-2xl leading-8 font-bold">
|
||||
<h3 class="text-secondary max-h-16 overflow-hidden text-2xl leading-8 font-bold">
|
||||
{campaign.title}
|
||||
</h3>
|
||||
|
||||
@@ -98,10 +98,10 @@ const imageHeight = "h-[389px]"; // Same height for both sizes
|
||||
<!-- Amount Information -->
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex flex-col gap-1">
|
||||
<span class="text-secondary text-base">
|
||||
<span class="text-content text-base">
|
||||
{t("home.campaigns.obtained")}
|
||||
</span>
|
||||
<span class="text-secondary text-2xl font-bold">
|
||||
<span class="text-content text-2xl font-bold">
|
||||
{
|
||||
formatCurrency(
|
||||
campaign.obtained.amount,
|
||||
@@ -111,10 +111,10 @@ const imageHeight = "h-[389px]"; // Same height for both sizes
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1 text-right">
|
||||
<span class="text-secondary text-base">
|
||||
<span class="text-content text-base">
|
||||
{t("home.campaigns.minimum")}
|
||||
</span>
|
||||
<span class="text-secondary text-2xl font-bold">
|
||||
<span class="text-content text-2xl font-bold">
|
||||
{formatCurrency(campaign.minimum.amount, campaign.minimum.currency)}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -84,7 +84,7 @@ const displayCampaigns = selectCampaignsForGrid(campaigns);
|
||||
>
|
||||
<!-- Arrow Icon -->
|
||||
<ArrowRightIcon />
|
||||
<span class="text-tertiary text-base font-bold">
|
||||
<span class="text-secondary text-base font-bold">
|
||||
{t("home.campaigns.viewAll")}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
@@ -38,12 +38,12 @@ const promoters: Promoter[] = [
|
||||
<div class="flex flex-col gap-6">
|
||||
<!-- Header with title and view all button -->
|
||||
<div class="flex items-center justify-between px-0 md:px-0">
|
||||
<h2 class="text-secondary text-2xl leading-8 font-bold md:text-4xl md:leading-[48px]">
|
||||
<h2 class="text-2xl leading-8 font-bold text-black">
|
||||
{t("home.featuredPromoters.title")}
|
||||
</h2>
|
||||
<a
|
||||
href="/promoters"
|
||||
class="bg-purple-tint text-tertiary hover:bg-tertiary flex items-center gap-2 rounded-3xl px-6 py-4 text-base leading-6 font-bold transition-all duration-200 hover:text-white"
|
||||
class="bg-purple-tint text-secondary hover:bg-secondary flex items-center gap-2 rounded-3xl px-6 py-4 text-base leading-6 font-bold transition-all duration-200 hover:text-white"
|
||||
>
|
||||
<ArrowRightIcon />
|
||||
{t("home.featuredPromoters.viewAll")}
|
||||
|
||||
@@ -56,7 +56,7 @@ const calls: CallCard[] = [
|
||||
];
|
||||
---
|
||||
|
||||
<section class="bg-tertiary w-full text-white">
|
||||
<section class="bg-secondary w-full text-white">
|
||||
<div class="wrapper relative !my-[-32px]">
|
||||
<!-- Two top info panels -->
|
||||
<div class="flex flex-col gap-6">
|
||||
@@ -82,7 +82,7 @@ const calls: CallCard[] = [
|
||||
</a>
|
||||
<a
|
||||
href="/convocatorias"
|
||||
class="bg-light-accent text-tertiary rounded-3xl px-6 py-4 text-sm font-bold transition hover:opacity-90"
|
||||
class="bg-light-accent text-secondary rounded-3xl px-6 py-4 text-sm font-bold transition hover:opacity-90"
|
||||
>
|
||||
{t("home.matchfunding.actions.viewCalls")}
|
||||
</a>
|
||||
@@ -137,13 +137,13 @@ const calls: CallCard[] = [
|
||||
</div>
|
||||
<a
|
||||
href="/convocatorias"
|
||||
class="bg-light-accent text-tertiary w-fit rounded-3xl px-6 py-4 text-sm font-bold transition hover:opacity-90"
|
||||
class="bg-light-accent text-secondary w-fit rounded-3xl px-6 py-4 text-sm font-bold transition hover:opacity-90"
|
||||
>
|
||||
{card.cta}
|
||||
</a>
|
||||
</div>
|
||||
{card.tag && (
|
||||
<div class="absolute top-6 right-6 z-20 rounded bg-[#E94668] px-2 py-1 text-xs font-medium text-white">
|
||||
<div class="bg-tertiary absolute top-6 right-6 z-20 rounded px-2 py-1 text-xs font-medium text-white">
|
||||
{card.tag}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -12,7 +12,7 @@ const { t } = Astro.locals;
|
||||
|
||||
<div class="bg-light-surface relative overflow-hidden rounded-3xl shadow-lg">
|
||||
<!-- Decorative background with gradient and shapes -->
|
||||
<div class="bg-tertiary relative h-[389px] overflow-hidden rounded-t-3xl">
|
||||
<div class="bg-secondary relative h-[389px] overflow-hidden rounded-t-3xl">
|
||||
<!-- Gradient background -->
|
||||
<div class="from-primary/30 to-tertiary absolute inset-0 bg-gradient-to-br"></div>
|
||||
|
||||
@@ -81,7 +81,7 @@ const { t } = Astro.locals;
|
||||
<!-- Content area -->
|
||||
<div class="flex flex-col gap-6 p-6">
|
||||
<!-- Name -->
|
||||
<h3 class="text-tertiary text-2xl leading-8 font-bold">
|
||||
<h3 class="text-secondary text-2xl leading-8 font-bold">
|
||||
{promoter.name}
|
||||
</h3>
|
||||
|
||||
@@ -89,20 +89,20 @@ const { t } = Astro.locals;
|
||||
<div class="flex items-center justify-between">
|
||||
<!-- Projects promoted -->
|
||||
<div class="flex flex-col gap-1 text-left">
|
||||
<span class="text-secondary text-base leading-6">
|
||||
<span class="text-content text-base leading-6">
|
||||
{t("home.featuredPromoters.projectsPromoted")}
|
||||
</span>
|
||||
<span class="text-secondary text-2xl leading-8 font-bold">
|
||||
<span class="text-content text-2xl leading-8 font-bold">
|
||||
{promoter.projectsPromoted}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Capital raised -->
|
||||
<div class="flex flex-col gap-1 text-right">
|
||||
<span class="text-secondary text-base leading-6">
|
||||
<span class="text-content text-base leading-6">
|
||||
{t("home.featuredPromoters.capitalRaised")}
|
||||
</span>
|
||||
<span class="text-secondary text-2xl leading-8 font-bold">
|
||||
<span class="text-content text-2xl leading-8 font-bold">
|
||||
{promoter.capitalRaised}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ const { t } = Astro.locals;
|
||||
<section data-renovation-banner class="wrapper renovation-banner">
|
||||
<!-- Content -->
|
||||
<div
|
||||
class="bg-tertiary relative mx-auto flex items-center justify-between gap-6 overflow-hidden rounded-3xl p-8 text-white"
|
||||
class="bg-secondary relative mx-auto flex items-center justify-between gap-6 overflow-hidden rounded-3xl p-8 text-white"
|
||||
>
|
||||
<!-- Main Content -->
|
||||
<div class="flex-1 space-y-3 pr-0 md:pr-6">
|
||||
@@ -21,7 +21,7 @@ const { t } = Astro.locals;
|
||||
<div class="flex items-center gap-3 md:gap-4">
|
||||
<a
|
||||
href="#"
|
||||
class="text-tertiary bg-light-accent rounded-full px-8 py-4 font-semibold whitespace-nowrap shadow-md transition-colors duration-200 hover:bg-white"
|
||||
class="text-secondary bg-light-accent rounded-full px-8 py-4 font-semibold whitespace-nowrap shadow-md transition-colors duration-200 hover:bg-white"
|
||||
aria-label={t("renovationBanner.ctaButton")}
|
||||
>
|
||||
{t("renovationBanner.ctaButton")}
|
||||
|
||||
@@ -27,12 +27,12 @@ const { title, description, image, href = "#", linkText = "Leer más" } = Astro.
|
||||
<!-- Text content -->
|
||||
<div class="flex flex-1 flex-col gap-2">
|
||||
<h3
|
||||
class="text-tertiary line-clamp-2 text-xl leading-7 font-bold md:text-2xl md:leading-8"
|
||||
class="text-secondary line-clamp-2 text-xl leading-7 font-bold md:text-2xl md:leading-8"
|
||||
>
|
||||
{title}
|
||||
</h3>
|
||||
<p
|
||||
class="line-clamp-3 text-sm leading-5 text-[#575757] md:line-clamp-4 md:text-base md:leading-6"
|
||||
class="text-content line-clamp-3 text-sm leading-5 md:line-clamp-4 md:text-base md:leading-6"
|
||||
>
|
||||
{description}
|
||||
</p>
|
||||
@@ -42,7 +42,7 @@ const { title, description, image, href = "#", linkText = "Leer más" } = Astro.
|
||||
<div class="shrink-0">
|
||||
<a
|
||||
href={href}
|
||||
class="text-tertiary text-sm leading-5 font-bold underline underline-offset-2 transition-opacity hover:opacity-80 md:text-base md:leading-6"
|
||||
class="text-secondary text-sm leading-5 font-bold underline underline-offset-2 transition-opacity hover:opacity-80 md:text-base md:leading-6"
|
||||
>
|
||||
{linkText}
|
||||
</a>
|
||||
|
||||
@@ -54,7 +54,7 @@ const resources = [
|
||||
</h2>
|
||||
<a
|
||||
href="/recursos"
|
||||
class="bg-purple-tint text-tertiary hover:bg-tertiary flex items-center gap-2 rounded-3xl px-4 py-3 text-sm leading-5 font-bold transition-all duration-200 hover:text-white md:px-6 md:py-4 md:text-base md:leading-6"
|
||||
class="bg-purple-tint text-secondary hover:bg-secondary flex items-center gap-2 rounded-3xl px-4 py-3 text-sm leading-5 font-bold transition-all duration-200 hover:text-white md:px-6 md:py-4 md:text-base md:leading-6"
|
||||
>
|
||||
<ArrowRightIcon />
|
||||
<span class="hidden sm:inline">{t("home.resources.viewAll")}</span>
|
||||
|
||||
@@ -10,11 +10,11 @@ const { t } = Astro.locals;
|
||||
<!-- Header -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.theoryToAction.title")}
|
||||
</h2>
|
||||
<p class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<p class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.theoryToAction.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -23,31 +23,31 @@ const { t } = Astro.locals;
|
||||
<div class="flex flex-col items-center justify-between gap-4 md:flex-row md:gap-0">
|
||||
<div class="flex flex-col items-center text-center md:items-start md:text-left">
|
||||
<div
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.theoryToAction.projectsReceived.value")}
|
||||
</div>
|
||||
<div class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<div class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.theoryToAction.projectsReceived.label")}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center text-center md:items-start md:text-left">
|
||||
<div
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.theoryToAction.projectsPublished.value")}
|
||||
</div>
|
||||
<div class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<div class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.theoryToAction.projectsPublished.label")}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center text-center md:items-start md:text-left">
|
||||
<div
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.theoryToAction.successRate.value")}
|
||||
</div>
|
||||
<div class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<div class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.theoryToAction.successRate.label")}
|
||||
</div>
|
||||
</div>
|
||||
@@ -57,7 +57,7 @@ const { t } = Astro.locals;
|
||||
<!-- Button -->
|
||||
<a
|
||||
href="https://stats.goteo.org"
|
||||
class="border-tertiary text-tertiary hover:bg-tertiary flex w-fit items-center justify-center gap-2 self-center rounded-3xl border px-6 py-4 text-sm leading-6 font-bold transition-all duration-200 hover:text-white md:self-start md:text-base"
|
||||
class="border-secondary text-secondary hover:bg-secondary flex w-fit items-center justify-center gap-2 self-center rounded-3xl border px-6 py-4 text-sm leading-6 font-bold transition-all duration-200 hover:text-white md:self-start md:text-base"
|
||||
>
|
||||
{t("home.stats.theoryToAction.button")}
|
||||
</a>
|
||||
@@ -69,11 +69,11 @@ const { t } = Astro.locals;
|
||||
<!-- Header -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.whyGoteo.title")}
|
||||
</h2>
|
||||
<p class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<p class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.whyGoteo.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -82,31 +82,31 @@ const { t } = Astro.locals;
|
||||
<div class="flex flex-col items-center justify-between gap-4 md:flex-row md:gap-0">
|
||||
<div class="flex flex-col items-center text-center md:items-start md:text-left">
|
||||
<div
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.whyGoteo.community.value")}
|
||||
</div>
|
||||
<div class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<div class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.whyGoteo.community.label")}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center text-center md:items-start md:text-left">
|
||||
<div
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.whyGoteo.averageDonors.value")}
|
||||
</div>
|
||||
<div class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<div class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.whyGoteo.averageDonors.label")}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center text-center md:items-start md:text-left">
|
||||
<div
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-4xl md:leading-[48px]"
|
||||
>
|
||||
{t("home.stats.whyGoteo.totalRaised.value")}
|
||||
</div>
|
||||
<div class="text-tertiary text-sm leading-5 md:text-base md:leading-6">
|
||||
<div class="text-secondary text-sm leading-5 md:text-base md:leading-6">
|
||||
{t("home.stats.whyGoteo.totalRaised.label")}
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,7 +116,7 @@ const { t } = Astro.locals;
|
||||
<!-- Button -->
|
||||
<a
|
||||
href="/about"
|
||||
class="border-tertiary text-tertiary hover:bg-tertiary flex w-fit items-center justify-center gap-2 self-center rounded-3xl border px-6 py-4 text-sm leading-6 font-bold transition-all duration-200 hover:text-white md:self-start md:text-base"
|
||||
class="border-secondary text-secondary hover:bg-secondary flex w-fit items-center justify-center gap-2 self-center rounded-3xl border px-6 py-4 text-sm leading-6 font-bold transition-all duration-200 hover:text-white md:self-start md:text-base"
|
||||
>
|
||||
{t("home.stats.whyGoteo.button")}
|
||||
</a>
|
||||
|
||||
@@ -6,26 +6,26 @@ const { t } = Astro.locals;
|
||||
<div class="flex flex-col gap-0 overflow-hidden rounded-3xl bg-white shadow-sm lg:flex-row">
|
||||
<!-- Content Section -->
|
||||
<div
|
||||
class="bg-light-surface flex flex-col justify-between gap-6 rounded-l-3xl border border-r-0 border-[#faf9ff] p-6 md:gap-8 md:py-6 md:pr-10 md:pl-6 lg:min-h-[484px] lg:w-[692px]"
|
||||
class="bg-light-surface border-soft-purple flex flex-col justify-between gap-6 rounded-l-3xl border border-r-0 p-6 md:gap-8 md:py-6 md:pr-10 md:pl-6 lg:min-h-[484px] lg:w-[692px]"
|
||||
>
|
||||
<!-- Text Content -->
|
||||
<div class="flex min-h-[348px] max-w-[529px] flex-col gap-4">
|
||||
<!-- Main Headline -->
|
||||
<h2
|
||||
class="text-tertiary text-2xl leading-tight font-bold md:text-[40px] md:leading-[48px]"
|
||||
class="text-secondary text-2xl leading-tight font-bold md:text-[40px] md:leading-[48px]"
|
||||
>
|
||||
{t("home.stories.title")}
|
||||
</h2>
|
||||
|
||||
<!-- Subtitle -->
|
||||
<h3
|
||||
class="text-tertiary text-lg leading-8 font-bold md:text-[24px] md:leading-[32px]"
|
||||
class="text-secondary text-lg leading-8 font-bold md:text-[24px] md:leading-[32px]"
|
||||
>
|
||||
{t("home.stories.subtitle")}
|
||||
</h3>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="flex-1 text-sm leading-6 text-[#575757] md:text-base md:leading-6">
|
||||
<div class="text-content flex-1 text-sm leading-6 md:text-base md:leading-6">
|
||||
{
|
||||
t("home.stories.description")
|
||||
.split("\n")
|
||||
@@ -41,7 +41,7 @@ const { t } = Astro.locals;
|
||||
<!-- Call to Action Button -->
|
||||
<a
|
||||
href="/donate"
|
||||
class="bg-purple-tint text-tertiary hover:bg-tertiary flex w-fit items-center justify-center gap-2 rounded-3xl px-6 py-4 text-sm leading-6 font-bold transition-all duration-200 hover:text-white md:text-base"
|
||||
class="bg-purple-tint text-secondary hover:bg-secondary flex w-fit items-center justify-center gap-2 rounded-3xl px-6 py-4 text-sm leading-6 font-bold transition-all duration-200 hover:text-white md:text-base"
|
||||
>
|
||||
{t("home.stories.button")}
|
||||
</a>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
import type { MouseEventHandler } from "svelte/elements";
|
||||
import { twMerge, type ClassNameValue } from "tailwind-merge";
|
||||
|
||||
const baseStyle = [
|
||||
"w-auto",
|
||||
"font-[700]",
|
||||
"text-secondary",
|
||||
"transition",
|
||||
"flex justify-center items-center gap-2",
|
||||
"hover:cursor-pointer",
|
||||
"disabled:bg-light-muted",
|
||||
];
|
||||
|
||||
const sizeStyles = {
|
||||
md: "px-8 py-4 rounded-[24px]",
|
||||
sm: "px-4 py-2 rounded-[16px]",
|
||||
};
|
||||
|
||||
const kindStyles = {
|
||||
primary: "bg-primary",
|
||||
secondary: "bg-purple-tint",
|
||||
ghost: "inset-ring-1 inset-ring-secondary",
|
||||
invert: "",
|
||||
};
|
||||
|
||||
let {
|
||||
children,
|
||||
form = undefined,
|
||||
type = "button",
|
||||
disabled = false,
|
||||
class: className = "",
|
||||
size = "md",
|
||||
kind = "primary",
|
||||
onclick,
|
||||
}: {
|
||||
children: Snippet;
|
||||
form?: string;
|
||||
type?: "button" | "submit";
|
||||
disabled?: boolean;
|
||||
size?: keyof typeof sizeStyles;
|
||||
kind?: keyof typeof kindStyles;
|
||||
class?: ClassNameValue;
|
||||
onclick?: MouseEventHandler<HTMLButtonElement>;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<button
|
||||
{type}
|
||||
{form}
|
||||
{disabled}
|
||||
{onclick}
|
||||
class={twMerge(baseStyle.join(" "), sizeStyles[size], kindStyles[kind], className)}
|
||||
>
|
||||
{@render children()}
|
||||
</button>
|
||||
@@ -0,0 +1,42 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
import { twMerge, type ClassNameValue } from "tailwind-merge";
|
||||
|
||||
const baseStyle = [
|
||||
"w-auto",
|
||||
"rounded-[32px]",
|
||||
"px-[16px]",
|
||||
"py-[8px]",
|
||||
"font-[700]",
|
||||
"hover:bg-purple-tint",
|
||||
"hover:text-tertiary",
|
||||
];
|
||||
|
||||
const styles = {
|
||||
default: "inset-ring-1 hover:inset-ring-0 inset-ring-secondary bg-light-surface",
|
||||
active: "bg-secondary text-primary",
|
||||
ghost: "",
|
||||
};
|
||||
|
||||
let {
|
||||
type = "default",
|
||||
disabled = false,
|
||||
class: className = "",
|
||||
onclick,
|
||||
children,
|
||||
}: {
|
||||
type?: keyof typeof styles;
|
||||
disabled?: boolean;
|
||||
class?: ClassNameValue;
|
||||
onclick?: (event: MouseEvent) => void;
|
||||
children: Snippet;
|
||||
} = $props();
|
||||
</script>
|
||||
|
||||
<button
|
||||
{disabled}
|
||||
class={twMerge(baseStyle.join(" "), styles[type], className)}
|
||||
onclick={(e) => onclick?.(e)}
|
||||
>
|
||||
{@render children()}
|
||||
</button>
|
||||
@@ -0,0 +1,66 @@
|
||||
<script lang="ts">
|
||||
import Category from "./Category.svelte";
|
||||
|
||||
export type Option = {
|
||||
id: number | string;
|
||||
text: string;
|
||||
};
|
||||
|
||||
let {
|
||||
options,
|
||||
selected = $bindable([]),
|
||||
selectedIds = $bindable([]),
|
||||
max,
|
||||
onchange,
|
||||
}: {
|
||||
options: Option[];
|
||||
selected?: Option[];
|
||||
selectedIds?: (number | string)[];
|
||||
max?: number;
|
||||
onchange?: (selected: Option[], option: Option) => void;
|
||||
} = $props();
|
||||
|
||||
function isSelected(option: Option): boolean {
|
||||
return selectedIds.includes(option.id);
|
||||
}
|
||||
|
||||
function handleClick(option: Option): void {
|
||||
if (isSelected(option)) {
|
||||
selectedIds = selectedIds.filter((id) => id !== option.id);
|
||||
} else {
|
||||
selectedIds = selectedIds.concat(option.id);
|
||||
}
|
||||
|
||||
selected = options.filter((option) => selectedIds.includes(option.id));
|
||||
|
||||
onchange?.(selected, option);
|
||||
}
|
||||
|
||||
function calcTagType(option: Option) {
|
||||
if (max === selectedIds.length) {
|
||||
return isSelected(option) ? "active" : "ghost";
|
||||
}
|
||||
|
||||
return isSelected(option) ? "active" : "default";
|
||||
}
|
||||
|
||||
function calcTagDisabled(option: Option) {
|
||||
if (max === selectedIds.length && !isSelected(option)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-wrap gap-[16px]">
|
||||
{#each options as option}
|
||||
<Category
|
||||
type={calcTagType(option)}
|
||||
disabled={calcTagDisabled(option)}
|
||||
onclick={(e) => handleClick(option)}
|
||||
>
|
||||
{option.text}
|
||||
</Category>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -0,0 +1,87 @@
|
||||
<script lang="ts">
|
||||
import { twMerge, type ClassNameValue } from "tailwind-merge";
|
||||
|
||||
const baseStyle = [
|
||||
"peer",
|
||||
"w-full p-4",
|
||||
"bg-light-surface rounded-md border border-secondary",
|
||||
"text-base text-gray-700 placeholder-gray-400",
|
||||
"focus:ring-1 focus:ring-tertiary focus:outline-none",
|
||||
];
|
||||
|
||||
let {
|
||||
value = $bindable(""),
|
||||
id = undefined,
|
||||
name = undefined,
|
||||
placeholder = undefined,
|
||||
type = "text",
|
||||
required = false,
|
||||
disabled = false,
|
||||
class: className = "",
|
||||
labelText = undefined,
|
||||
helperText = undefined,
|
||||
}: {
|
||||
value?: string;
|
||||
id?: string;
|
||||
name?: string;
|
||||
placeholder?: string;
|
||||
type?: "text" | "email" | "password" | "tel" | "url";
|
||||
required?: boolean;
|
||||
disabled?: boolean;
|
||||
class?: ClassNameValue;
|
||||
labelText?: string;
|
||||
helperText?: string;
|
||||
} = $props();
|
||||
|
||||
const finalId = id ? id : getIdForInput();
|
||||
|
||||
function getIdForInput(): string {
|
||||
const cyrb53hash = cyrb53(type + name + placeholder + labelText + helperText);
|
||||
|
||||
return `input-${cyrb53hash}`;
|
||||
}
|
||||
|
||||
function cyrb53(str: string, seed = 0) {
|
||||
let h1 = 0xdeadbeef ^ seed,
|
||||
h2 = 0x41c6ce57 ^ seed;
|
||||
|
||||
for (let i = 0, ch; i < str.length; i++) {
|
||||
ch = str.charCodeAt(i);
|
||||
h1 = Math.imul(h1 ^ ch, 2654435761);
|
||||
h2 = Math.imul(h2 ^ ch, 1597334677);
|
||||
}
|
||||
|
||||
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507);
|
||||
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
||||
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507);
|
||||
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
||||
|
||||
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class={twMerge("relative", disabled && "opacity-40")}>
|
||||
{#if labelText}
|
||||
<label
|
||||
for={finalId}
|
||||
class="absolute -top-2 left-4 -translate-y-1/2 transform text-[10px] font-medium text-gray-500 transition-all"
|
||||
>
|
||||
{labelText}
|
||||
</label>
|
||||
{/if}
|
||||
<input
|
||||
bind:value
|
||||
id={finalId}
|
||||
{name}
|
||||
{type}
|
||||
{required}
|
||||
{disabled}
|
||||
{placeholder}
|
||||
class={twMerge(baseStyle, disabled && "cursor-not-allowed", className)}
|
||||
/>
|
||||
{#if helperText}
|
||||
<span id={`helper-${finalId}`} class="ml-4 text-[12px]">
|
||||
{helperText}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -26,7 +26,7 @@
|
||||
>
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="text-tertiary flex flex-col gap-2">
|
||||
<div class="text-secondary flex flex-col gap-2">
|
||||
<p class="text-4xl leading-tight font-bold">
|
||||
{$t("profile.donorType.fan.title")}
|
||||
</p>
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-10">
|
||||
<div class="text-tertiary flex flex-col">
|
||||
<div class="text-secondary flex flex-col">
|
||||
<p class="text-base leading-6">
|
||||
{$t("profile.donorType.fan.projectsDonated")}
|
||||
</p>
|
||||
@@ -47,7 +47,7 @@
|
||||
{projectsDonated.toString().padStart(2, "0")}
|
||||
</p>
|
||||
</div>
|
||||
<div class="text-tertiary flex flex-col">
|
||||
<div class="text-secondary flex flex-col">
|
||||
<p class="text-base leading-6">
|
||||
{$t("profile.donorType.fan.moneyDonated")}
|
||||
</p>
|
||||
@@ -64,10 +64,10 @@
|
||||
class="border-light-muted bg-light-surface flex max-h-64 grow basis-0 flex-col gap-6 rounded-3xl border p-6"
|
||||
>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-tertiary text-4xl leading-tight font-bold">
|
||||
<p class="text-secondary text-4xl leading-tight font-bold">
|
||||
{$t("profile.donorType.nextLevel.title")}
|
||||
</p>
|
||||
<p class="text-secondary text-base leading-6">
|
||||
<p class="text-tertiary text-base leading-6">
|
||||
{$t("profile.donorType.nextLevel.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@ const defaultAvatar = "https://placehold.co/204x204/e6e5f7/462949?text=User&font
|
||||
<div class="absolute right-6 bottom-6 flex gap-3">
|
||||
<!-- Share Button -->
|
||||
<button
|
||||
class="bg-purple-tint text-tertiary flex items-center gap-2 rounded-3xl px-6 py-4 font-bold transition hover:opacity-90"
|
||||
class="bg-purple-tint text-secondary flex items-center gap-2 rounded-3xl px-6 py-4 font-bold transition hover:opacity-90"
|
||||
>
|
||||
<ShareIcon class="size-6" />
|
||||
{t("profile.share")}
|
||||
@@ -35,7 +35,7 @@ const defaultAvatar = "https://placehold.co/204x204/e6e5f7/462949?text=User&font
|
||||
<!-- Subscribe Button -->
|
||||
{
|
||||
onSubscribe && (
|
||||
<button class="bg-primary text-tertiary rounded-3xl px-6 py-4 font-bold transition hover:opacity-90">
|
||||
<button class="bg-primary text-secondary rounded-3xl px-6 py-4 font-bold transition hover:opacity-90">
|
||||
{t("profile.subscribe")}
|
||||
</button>
|
||||
)
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="bg-purple-tint text-tertiary flex size-6 items-center justify-center rounded-[4.8px] p-1 transition hover:opacity-90"
|
||||
class="bg-purple-tint text-secondary flex size-6 items-center justify-center rounded-[4.8px] p-1 transition hover:opacity-90"
|
||||
aria-label={link.label}
|
||||
>
|
||||
<link.icon class="size-full" />
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
<section class="flex flex-col gap-6 py-10 lg:flex-row">
|
||||
<div class="flex flex-row items-center justify-center gap-4">
|
||||
<div><DonatorIcon /></div>
|
||||
<div class="text-[#575757]">
|
||||
<div class="text-content">
|
||||
{@html $t(
|
||||
"project.banner.donator.description",
|
||||
{ owner: `<a href="#" class="font-bold text-tertiary">${ownerName}</a>` },
|
||||
{ owner: `<a href="#" class="font-bold text-secondary">${ownerName}</a>` },
|
||||
{ allowHTML: true },
|
||||
)}
|
||||
<a href="#" class="text-tertiary font-bold"
|
||||
<a href="#" class="text-secondary font-bold"
|
||||
>{$t("project.banner.donator.learnMore")}
|
||||
</a>
|
||||
</div>
|
||||
@@ -23,9 +23,9 @@
|
||||
<div class="flex flex-row items-center justify-center gap-4">
|
||||
<div><CertificateIcon /></div>
|
||||
<div>
|
||||
<div class="text-[#575757]">
|
||||
<div class="text-content">
|
||||
{$t("project.banner.certificate.description")}
|
||||
<a href="#" class="text-tertiary font-bold"
|
||||
<a href="#" class="text-secondary font-bold"
|
||||
>{$t("project.banner.certificate.learnMore")}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<div class="h-full w-full border-r border-dashed border-r-white"></div>
|
||||
|
||||
<span
|
||||
class="bg-tertiary absolute right-0 h-2 w-2 translate-x-1/2 rounded-full"
|
||||
class="bg-secondary absolute right-0 h-2 w-2 translate-x-1/2 rounded-full"
|
||||
class:top-0={budgetAmount === "optimum"}
|
||||
class:bottom-0={budgetAmount !== "optimum"}
|
||||
></span>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { formatCurrency } from "../../utils/currencies";
|
||||
import ProgressChart from "./ProgressChart.svelte";
|
||||
import { t } from "../../i18n/store";
|
||||
import Button from "../library/Button.svelte";
|
||||
|
||||
export let project: Project;
|
||||
export let totalSupports: number = 0;
|
||||
@@ -34,15 +35,19 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class=" flex h-full flex-col gap-6 rounded-[32px] border border-[#F3F3EF] bg-[#fff] p-6 shadow-[0_1px_3px_0_#0000001A,0_6px_6px_0_#00000017,0_13px_8px_0_#0000000D,0_22px_9px_0_#00000003,0_35px_10px_0_#00000000]"
|
||||
class=" border-light-muted flex h-full flex-col gap-6 rounded-[32px] border bg-[#fff] p-6 shadow-[0_1px_3px_0_#0000001A,0_6px_6px_0_#00000017,0_13px_8px_0_#0000000D,0_22px_9px_0_#00000003,0_35px_10px_0_#00000000]"
|
||||
>
|
||||
<div class="flex w-full items-center justify-end">
|
||||
{#if hasReached(project.budget?.optimum?.money)}
|
||||
<span class="border-tertiary self-end rounded-2xl border px-2 py-1 text-xs text-nowrap">
|
||||
<span
|
||||
class="border-secondary self-end rounded-2xl border px-2 py-1 text-xs text-nowrap"
|
||||
>
|
||||
{$t("campaignProgress.optimumReached")}
|
||||
</span>
|
||||
{:else if hasReached(project.budget?.minimum?.money)}
|
||||
<span class="border-tertiary self-end rounded-2xl border px-2 py-1 text-xs text-nowrap">
|
||||
<span
|
||||
class="border-secondary self-end rounded-2xl border px-2 py-1 text-xs text-nowrap"
|
||||
>
|
||||
{$t("campaignProgress.minimumReached")}
|
||||
</span>
|
||||
{/if}
|
||||
@@ -51,8 +56,8 @@
|
||||
<div class="col-span-2 grid grid-cols-2 gap-6">
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<p class="text-sm text-[#575757]">{$t(`campaignProgress.obtained`)}</p>
|
||||
<p class="text-secondary text-3xl font-bold">
|
||||
<p class="text-content text-sm">{$t(`campaignProgress.obtained`)}</p>
|
||||
<p class="text-3xl font-bold text-black">
|
||||
{formatCurrency(
|
||||
Number(accounting.balance?.amount) || 0,
|
||||
accounting.balance?.currency ?? undefined,
|
||||
@@ -60,16 +65,16 @@
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-[#575757]">{$t(`campaignProgress.supports`)}</p>
|
||||
<p class="text-secondary text-2xl font-bold">
|
||||
<p class="text-content text-sm">{$t(`campaignProgress.supports`)}</p>
|
||||
<p class="text-2xl font-bold text-black">
|
||||
{totalSupports}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<p class="text-sm text-[#575757]">{$t(`campaignProgress.optimum`)}</p>
|
||||
<p class="text-secondary text-3xl font-bold">
|
||||
<p class="text-content text-sm">{$t(`campaignProgress.optimum`)}</p>
|
||||
<p class="text-3xl font-bold text-black">
|
||||
{formatCurrency(
|
||||
project.budget?.optimum?.money?.amount ?? 0,
|
||||
project.budget?.optimum?.money?.currency ?? undefined,
|
||||
@@ -77,8 +82,8 @@
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-[#575757]">{$t(`campaignProgress.minimum`)}</p>
|
||||
<p class="text-secondary text-2xl font-bold">
|
||||
<p class="text-content text-sm">{$t(`campaignProgress.minimum`)}</p>
|
||||
<p class="text-2xl font-bold text-black">
|
||||
{formatCurrency(
|
||||
project.budget?.minimum?.money?.amount ?? 0,
|
||||
project.budget?.minimum?.money?.currency ?? undefined,
|
||||
@@ -87,10 +92,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="bg-primary bold text-tertiary w-full cursor-pointer rounded-3xl px-6 py-4 font-bold"
|
||||
on:click={scrollToRewards}
|
||||
>
|
||||
<Button class="w-full" onclick={scrollToRewards}>
|
||||
{$t("campaignProgress.donate")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
{/each}
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<div class="bg-tertiary h-2 w-2 rounded-full"></div>
|
||||
<div class="bg-secondary h-2 w-2 rounded-full"></div>
|
||||
<span class="text-sm">{$t("project.tabs.budget.campaingState")}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-col gap-6">
|
||||
<span class="text-tertiary text-3xl font-bold">
|
||||
<span class="text-secondary text-3xl font-bold">
|
||||
{$t("project.tabs.budget.minimum")}:
|
||||
{formatCurrency(
|
||||
project.budget?.minimum?.money?.amount,
|
||||
@@ -96,13 +96,13 @@
|
||||
class="flex w-full flex-col justify-between gap-6 rounded-4xl bg-white p-6 font-bold"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-tertiary line-clamp-1 text-2xl">{item.title}</h2>
|
||||
<p class="line-clamp-3 font-normal text-[#575757]">
|
||||
<h2 class="text-secondary line-clamp-1 text-2xl">{item.title}</h2>
|
||||
<p class="text-content line-clamp-3 font-normal">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<p class="text-secondary text-2xl">
|
||||
<p class="text-2xl text-black">
|
||||
{formatCurrency(item.money.amount, item.money.currency)}
|
||||
</p>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -119,7 +119,7 @@
|
||||
</div>
|
||||
<div class="flex flex-col gap-6">
|
||||
<div></div>
|
||||
<span class="text-tertiary text-3xl font-bold">
|
||||
<span class="text-secondary text-3xl font-bold">
|
||||
{$t("project.tabs.budget.optimal")}:
|
||||
|
||||
{formatCurrency(
|
||||
@@ -141,13 +141,13 @@
|
||||
class="flex w-full flex-col justify-between gap-6 rounded-4xl bg-white p-6 font-bold"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-tertiary line-clamp-1 text-2xl">{item.title}</h2>
|
||||
<p class="line-clamp-3 font-normal text-[#575757]">
|
||||
<h2 class="text-secondary line-clamp-1 text-2xl">{item.title}</h2>
|
||||
<p class="text-content line-clamp-3 font-normal">
|
||||
{item.description}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<p class="text-secondary text-2xl">
|
||||
<p class="text-2xl text-black">
|
||||
{formatCurrency(item.money.amount, item.money.currency)}
|
||||
</p>
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<Loader />
|
||||
</div>
|
||||
{:else}
|
||||
<h2 class="text-tertiary line-clamp-2 flex max-w-2xl text-3xl font-bold">
|
||||
<h2 class="text-secondary line-clamp-2 flex max-w-2xl text-3xl font-bold">
|
||||
{$t("project.tabs.community.content.title")}
|
||||
</h2>
|
||||
<div class="flex flex-col gap-6">
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
<Modal
|
||||
bind:open={openModal}
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] rounded-4xl hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary rounded-4xl hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent"
|
||||
class="fixed top-1/2 left-1/2 w-full max-w-[475px] -translate-x-1/2 -translate-y-1/2 rounded-3xl bg-white p-6 shadow-lg backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
headerClass="py-2"
|
||||
>
|
||||
@@ -132,10 +132,10 @@
|
||||
<div class="flex h-16 w-16 items-center justify-center rounded-lg">😀</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<div class="text-secondary font-bold">
|
||||
<div class="font-bold text-black">
|
||||
{$t("project.tabs.community.contribution")}
|
||||
</div>
|
||||
<p class="text-secondary text-2xl font-bold">
|
||||
<p class="text-2xl font-bold text-black">
|
||||
{formatCurrency(
|
||||
selectedProjectSupport.money?.amount ?? 0,
|
||||
selectedProjectSupport.money?.currency ?? "undefined",
|
||||
@@ -143,10 +143,10 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-secondary text-2xl font-bold">
|
||||
<div class="text-2xl font-bold text-black">
|
||||
{selectedProjectSupport.displayName}
|
||||
</div>
|
||||
<div class="text-sm text-[#575757]">
|
||||
<div class="text-content text-sm">
|
||||
{selectedProjectSupport.message}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="flex w-full flex-col gap-4 p-6 md:w-2/3">
|
||||
<div class="text-secondary flex flex-col items-start gap-2 font-bold md:items-end">
|
||||
<div class="flex flex-col items-start gap-2 font-bold text-black md:items-end">
|
||||
<span>{$t("project.tabs.community.matchfunding.contribution")}</span>
|
||||
<div class="flex flex-col items-start text-2xl md:items-end">
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
@@ -49,10 +49,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-secondary line-clamp-2 text-left text-2xl font-bold md:text-right">
|
||||
<div class="line-clamp-2 text-left text-2xl font-bold text-black md:text-right">
|
||||
{$t("project.tabs.community.anonymous.title")}
|
||||
</div>
|
||||
<p class="line-clamp-2 text-left text-sm text-[#575757] md:text-right">
|
||||
<p class="text-content line-clamp-2 text-left text-sm md:text-right">
|
||||
{$t("project.tabs.community.anonymous.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
>
|
||||
<div class="flex w-1/3 items-center justify-center bg-red-500">😀</div>
|
||||
<div class="flex w-2/3 flex-col gap-4 p-6">
|
||||
<div class="text-secondary flex flex-col items-end gap-2 font-bold">
|
||||
<div class="text-tertiary flex flex-col items-end gap-2 font-bold">
|
||||
<span>{$t("project.tabs.community.matchfunding.contribution")}</span>
|
||||
<div class="flex flex-col items-end text-2xl">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -26,7 +26,7 @@
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-[#5757577A]">
|
||||
<div class="text-content flex items-center gap-2">
|
||||
<span>{$t("project.tabs.community.matchfunding.up_to")}</span>
|
||||
<span class="font-bold">
|
||||
{formatCurrency(item.money?.amount ?? 0, item.money?.currency ?? "")}
|
||||
@@ -34,10 +34,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-secondary line-clamp-2 text-2xl font-bold">
|
||||
<div class="text-tertiary line-clamp-2 text-2xl font-bold">
|
||||
{item.displayName}
|
||||
</div>
|
||||
<p class="line-clamp-2 text-sm text-[#575757]">
|
||||
<p class="text-content line-clamp-2 text-sm">
|
||||
{item.message}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
<div class="flex flex-row items-center justify-between gap-4">
|
||||
<div class="flex h-16 w-16 items-center justify-center rounded-lg">😀</div>
|
||||
<div class="flex flex-col items-end">
|
||||
<div class="text-secondary font-bold">
|
||||
<div class="font-bold text-black">
|
||||
{$t("project.tabs.community.contribution")}
|
||||
</div>
|
||||
<p class="text-secondary text-2xl font-bold">
|
||||
<p class="text-2xl font-bold text-black">
|
||||
{formatCurrency(item.money?.amount ?? 0, item.money?.currency ?? "")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-secondary self-start text-left text-2xl font-bold">
|
||||
<div class="self-start text-left text-2xl font-bold text-black">
|
||||
{item.displayName}
|
||||
</div>
|
||||
<div class="line-clamp-2 self-start text-left text-sm text-[#575757]">
|
||||
<div class="text-content line-clamp-2 self-start text-left text-sm">
|
||||
{#if item.message}
|
||||
{item.message}
|
||||
{:else}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { cart } from "../../stores/cart";
|
||||
import { getUnit } from "../../utils/currencies";
|
||||
import { extractId } from "../../utils/extractId";
|
||||
import Button from "../library/Button.svelte";
|
||||
import Reward from "../Reward.svelte";
|
||||
|
||||
let {
|
||||
@@ -73,17 +74,17 @@
|
||||
|
||||
<section>
|
||||
<div class="flex flex-col gap-12">
|
||||
<h2 class="text-tertiary text-3xl font-bold">
|
||||
<h2 class="text-secondary text-3xl font-bold">
|
||||
{$t("rewards.title")}
|
||||
</h2>
|
||||
<ul class="grid gap-6 lg:grid-cols-3">
|
||||
<li
|
||||
class:opacity-50={!isAvailable}
|
||||
class:cursor-not-allowed={!isAvailable}
|
||||
class="flex basis-1/3 flex-col justify-between gap-6 rounded-4xl border border-[#F3F3EF] bg-[#FFF] p-6 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class="border-light-muted flex basis-1/3 flex-col justify-between gap-6 rounded-4xl border bg-[#FFF] p-6 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
>
|
||||
<div class="flex flex-col gap-6">
|
||||
<h3 class="text-tertiary w-full text-left text-2xl font-semibold">
|
||||
<h3 class="text-secondary w-full text-left text-2xl font-semibold">
|
||||
{$t("rewards.donation-free.title")}
|
||||
</h3>
|
||||
<p class="text-sm whitespace-pre-line text-gray-800">
|
||||
@@ -97,16 +98,14 @@
|
||||
placeholder={$t("rewards.donation-free.placeholder")}
|
||||
bind:value={freeAmount}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onclick={handleFreeDonation}
|
||||
<Button
|
||||
kind="secondary"
|
||||
class="w-full"
|
||||
disabled={!isAvailable}
|
||||
class:cursor-pointer={isAvailable}
|
||||
class:cursor-not-allowed={!isAvailable}
|
||||
class="text-tertiary inline-block w-full cursor-pointer rounded-3xl bg-[#E6E5F7] px-6 py-4 font-bold transition"
|
||||
onclick={handleFreeDonation}
|
||||
>
|
||||
{$t("rewards.donation-free.btn")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
{#each rewards as reward}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { apiProjectUpdatesGetCollection } from "../../openapi/client/index";
|
||||
import Carousel from "../Carousel.svelte";
|
||||
import { renderMarkdown } from "../../utils/renderMarkdown";
|
||||
import Button from "../library/Button.svelte";
|
||||
|
||||
let {
|
||||
lang = $bindable(),
|
||||
@@ -103,7 +104,7 @@
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-10">
|
||||
<h2 class="text-tertiary line-clamp-2 flex max-w-2xl text-3xl font-bold">
|
||||
<h2 class="text-secondary line-clamp-2 flex max-w-2xl text-3xl font-bold">
|
||||
{$t("project.tabs.updates.content.title")}
|
||||
</h2>
|
||||
<Carousel gap={16} showDots={true} {itemsPerGroup}>
|
||||
@@ -120,7 +121,7 @@
|
||||
class="flex w-full flex-col justify-between gap-6 rounded-4xl bg-white p-6 font-bold"
|
||||
>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="text-tertiary flex flex-row items-center gap-2">
|
||||
<div class="text-secondary flex flex-row items-center gap-2">
|
||||
{formatDate(update.date ?? "")}
|
||||
<ActiveFilterIcon />
|
||||
</div>
|
||||
@@ -134,22 +135,22 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-tertiary text-lg font-semibold">{update.title}</h2>
|
||||
<h2 class="text-secondary text-lg font-semibold">{update.title}</h2>
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="text-secondary text-sm">{update.subtitle}</p>
|
||||
<p class="line-clamp-2 text-sm text-[#575757]">{update.body}</p>
|
||||
<p class="text-tertiary text-sm">{update.subtitle}</p>
|
||||
<p class="text-content line-clamp-2 text-sm">{update.body}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full items-center justify-end">
|
||||
<button
|
||||
class="text-tertiary border-tertiary flex w-full cursor-pointer justify-center truncate rounded-3xl border px-6 py-4 whitespace-nowrap lg:max-w-max"
|
||||
<Button
|
||||
kind="ghost"
|
||||
onclick={() => {
|
||||
selected = update;
|
||||
openModal = true;
|
||||
}}
|
||||
>
|
||||
{$t("project.tabs.updates.content.btn.read-more")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
@@ -157,17 +158,17 @@
|
||||
|
||||
<Modal
|
||||
bind:open={openModal}
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent"
|
||||
class="fixed top-1/2 left-1/2 w-full max-w-[800px] -translate-x-1/2 -translate-y-1/2 rounded-3xl bg-white p-6 shadow-lg backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
>
|
||||
{#if selected}
|
||||
{#if shouldShowHeader(selected.date)}
|
||||
<div class="flex items-center gap-2 text-base font-bold text-[#462949]">
|
||||
<div class="text-secondary flex items-center gap-2 text-base font-bold">
|
||||
<AlertIcon />
|
||||
{$t("project.tabs.updates.modal-title")}
|
||||
</div>
|
||||
{/if}
|
||||
<h3 class="text-3xl font-bold text-[#462949]">
|
||||
<h3 class="text-secondary text-3xl font-bold">
|
||||
{selected?.title}
|
||||
</h3>
|
||||
<div class="marked-content flex flex-col gap-4 text-gray-700">
|
||||
@@ -177,12 +178,10 @@
|
||||
</div>
|
||||
|
||||
<div class="flex w-full justify-end">
|
||||
<button
|
||||
class="bg-primary flex cursor-pointer flex-row gap-2 rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
>
|
||||
<Button>
|
||||
<ShareIcon />
|
||||
{$t("project.tabs.updates.content.btn.share")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</Modal>
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-6 lg:flex-row">
|
||||
<div class="text-tertiary basis-1/3 text-3xl font-bold">
|
||||
<div class="text-secondary basis-1/3 text-3xl font-bold">
|
||||
{$t("project.tabs.budget.chart-title")}
|
||||
</div>
|
||||
|
||||
<div class="flex basis-2/3 flex-col gap-8 rounded-xl bg-[#f1efff] p-6">
|
||||
<div class="text-tertiary flex flex-col gap-4">
|
||||
<div class="text-secondary flex flex-col gap-4">
|
||||
<div class="flex flex-row gap-2">
|
||||
{$t("project.tabs.budget.minimum")}:
|
||||
<span>
|
||||
@@ -32,7 +32,7 @@
|
||||
<BudgetBar {project} {accounting} budgetAmount={"minimum"} />
|
||||
</div>
|
||||
|
||||
<div class="text-tertiary flex flex-col gap-4">
|
||||
<div class="text-secondary flex flex-col gap-4">
|
||||
<div class="flex flex-row gap-2">
|
||||
{$t("project.tabs.budget.optimal")}:
|
||||
<span>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
<button
|
||||
onclick={() => (openModal = true)}
|
||||
class="text-tertiary flex cursor-pointer flex-row items-center gap-2 p-2 font-bold"
|
||||
class="text-secondary flex cursor-pointer flex-row items-center gap-2 p-2 font-bold"
|
||||
>
|
||||
<ShareIcon />
|
||||
{$t("project.actions.share")}
|
||||
@@ -67,17 +67,17 @@
|
||||
|
||||
<Modal
|
||||
bind:open={openModal}
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent cursor-pointer"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent cursor-pointer"
|
||||
class="fixed top-1/2 left-1/2 w-full max-w-[475px] -translate-x-1/2 -translate-y-1/2 rounded-3xl bg-white p-6 shadow-lg backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
title={$t("project.share.modal.title")}
|
||||
headerClass="py-2 text-tertiary text-2xl"
|
||||
headerClass="py-2 text-secondary text-2xl"
|
||||
>
|
||||
<p>{$t("project.share.modal.description")}</p>
|
||||
|
||||
<div class="flex flex-row items-center justify-center gap-6">
|
||||
<Tooltip
|
||||
text={$t("contributions.tootip.copied")}
|
||||
tooltipClass="bg-[#462949] -translate-x-[50%]"
|
||||
tooltipClass="bg-secondary -translate-x-[50%]"
|
||||
className="cursor-copy shrink-0 w-auto h-auto"
|
||||
>
|
||||
<button
|
||||
@@ -115,10 +115,10 @@
|
||||
|
||||
<Modal
|
||||
bind:open={iframeModal}
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-[#462949] hover:bg-transparent hover:text-[#462949] hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-[#462949] dark:hover:text-[#462949] dark:hover:bg-transparent cursor-pointer"
|
||||
closeBtnClass="top-7 end-7 bg-transparent text-secondary hover:bg-transparent hover:text-secondary hover:scale-110 transition-transform duration-200 transform focus:ring-0 shadow-none dark:text-secondary dark:hover:text-secondary dark:hover:bg-transparent cursor-pointer"
|
||||
class="!left-1/2 max-w-[600px] p-4 backdrop:bg-[#878282B2] backdrop:backdrop-blur-[5px]"
|
||||
title={$t("project.share.iframe-modal.title")}
|
||||
headerClass="py-2 text-tertiary text-2xl"
|
||||
headerClass="py-2 text-secondary text-2xl"
|
||||
>
|
||||
<p>{$t("project.share.iframe-modal.description")}</p>
|
||||
|
||||
@@ -149,9 +149,9 @@
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="bg-primary text-tertiary h-auto w-full cursor-pointer rounded-3xl px-6 py-4 font-bold"
|
||||
class="bg-primary text-secondary h-auto w-full cursor-pointer rounded-3xl px-6 py-4 font-bold"
|
||||
class:bg-primary={!copied}
|
||||
class:bg-[#E6E5F7]={copied}
|
||||
class:bg-purple-tint={copied}
|
||||
onclick={() => {
|
||||
navigator.clipboard.writeText(iframeCode);
|
||||
copied = true;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
import RememberIcon from "../../svgs/RememberIcon.svelte";
|
||||
import { getDefaultLanguage } from "../../utils/consts";
|
||||
import TopRewards from "./TopRewards.svelte";
|
||||
import Button from "../library/Button.svelte";
|
||||
|
||||
let {
|
||||
lang = $bindable(),
|
||||
@@ -39,10 +40,7 @@
|
||||
} = $props();
|
||||
|
||||
let poster = { src: project.video?.thumbnail || "", alt: "Miniatura del video" };
|
||||
let showFull = $state(false);
|
||||
|
||||
let paragraphRef: HTMLParagraphElement;
|
||||
let showToggle = $state(false);
|
||||
const countdownEnd = project.calendar?.optimum ? new Date(project.calendar.optimum) : undefined;
|
||||
|
||||
async function getProjectData(code?: string) {
|
||||
@@ -57,47 +55,25 @@
|
||||
|
||||
project = data!;
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const twoLinesHeight = parseFloat(getComputedStyle(paragraphRef).lineHeight) * 2;
|
||||
if (paragraphRef.scrollHeight > twoLinesHeight + 1) {
|
||||
showToggle = true;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="wrapper">
|
||||
<div class="my-10 flex w-full flex-col-reverse gap-5 lg:flex-row lg:justify-between">
|
||||
<div class="flex w-full flex-col gap-2.5 lg:w-[70%]">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h3 class="text-xl font-bold text-[#575757] lg:text-2xl">
|
||||
<h3 class="text-content text-xl font-bold lg:text-2xl">
|
||||
{$t("project.owner")}
|
||||
<span class="text-tertiary font-bold underline"> {ownerName}</span>
|
||||
<span class="font-bold text-black underline"> {ownerName}</span>
|
||||
</h3>
|
||||
<h1 class="text-3xl font-bold text-[#575757] lg:text-4xl">
|
||||
<h1 class="text-content text-3xl font-bold lg:text-4xl">
|
||||
{project.title}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p
|
||||
bind:this={paragraphRef}
|
||||
class="text-[#575757] transition-all duration-300 ease-in-out {showFull
|
||||
? ''
|
||||
: 'line-clamp-2'}"
|
||||
>
|
||||
<p class="text-content transition-all duration-300 ease-in-out">
|
||||
{project.subtitle}
|
||||
</p>
|
||||
|
||||
{#if showToggle}
|
||||
<button
|
||||
type="button"
|
||||
class="mt-2 text-sm font-medium text-blue-600 hover:underline"
|
||||
onclick={() => (showFull = !showFull)}
|
||||
>
|
||||
{showFull ? $t("project.actions.viewLess") : $t("project.actions.viewMore")}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -137,30 +113,25 @@
|
||||
<Tags {project} {lang} />
|
||||
<div class="flex flex-row justify-between gap-6">
|
||||
<Sharebutton {project} />
|
||||
<button
|
||||
class="text-tertiary flex cursor-pointer flex-row items-center gap-2 p-2 font-bold"
|
||||
>
|
||||
<RememberIcon /> {$t("project.actions.remember")}</button
|
||||
>
|
||||
<Button kind="invert" size="sm" class="px-0">
|
||||
<RememberIcon />
|
||||
{$t("project.actions.remember")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-8">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-2xl font-bold text-black">
|
||||
{$t("reward.trending")}
|
||||
</h2>
|
||||
<button
|
||||
class="text-tertiary hidden cursor-pointer items-center gap-4 rounded-3xl bg-[#E6E5F7] px-6 py-4 font-bold transition lg:flex"
|
||||
>
|
||||
<Button kind="secondary" class="hidden lg:flex">
|
||||
<ArrowRightIcon />{$t("reward.showAll")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
<TopRewards bind:lang {project} />
|
||||
<button
|
||||
class="text-tertiary flex cursor-pointer items-center justify-center gap-4 rounded-3xl bg-[#E6E5F7] px-6 py-4 font-bold transition lg:hidden"
|
||||
>
|
||||
<Button kind="secondary" class="lg:hidden">
|
||||
<ArrowRightIcon />{$t("reward.showAll")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
<Banner {ownerName} />
|
||||
</section>
|
||||
|
||||
@@ -66,22 +66,22 @@
|
||||
<div class="relative h-[160px] w-full border">
|
||||
{#if !isLoaded}
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
<span class="text-[#575757]">Cargando...</span>
|
||||
<span class="text-content">Cargando...</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div bind:this={mainCarousel} class="main-carousel h-full w-full">
|
||||
{#each slides as { title, subtitle, date, body, cover }}
|
||||
<div
|
||||
class="carousel-cell mr-6 flex h-full w-[100%] flex-col items-start justify-center gap-4 rounded-xl border border-[red] bg-[#faf9ff] p-8 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
class="carousel-cell bg-soft-purple mr-6 flex h-full w-[100%] flex-col items-start justify-center gap-4 rounded-xl border border-[red] p-8 shadow-[0px_1px_3px_0px_#0000001A]"
|
||||
>
|
||||
<span class="text-base font-semibold text-[#575757]">{date}</span>
|
||||
<span class="text-content text-base font-semibold">{date}</span>
|
||||
{#if cover}
|
||||
<img src={cover} alt={title} class="mt-4 w-full rounded-lg object-cover" />
|
||||
{/if}
|
||||
<span class="text-base font-semibold text-[#575757]">{title}</span>
|
||||
<span class="text-secondary text-3xl">{subtitle}</span>
|
||||
<p class="text-sm text-[#575757]">{body}</p>
|
||||
<span class="text-content text-base font-semibold">{title}</span>
|
||||
<span class="text-tertiary text-3xl">{subtitle}</span>
|
||||
<p class="text-content text-sm">{body}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="relative">
|
||||
<button
|
||||
onclick={() => scrollTabs("left")}
|
||||
class="absolute top-5 left-0 z-10 h-8 w-8 -translate-y-1/2 rounded-r-sm bg-[#e6e5f7] p-2 shadow-md lg:hidden"
|
||||
class="bg-purple-tint absolute top-5 left-0 z-10 h-8 w-8 -translate-y-1/2 rounded-r-sm p-2 shadow-md lg:hidden"
|
||||
class:opacity-50={!canScrollLeft}
|
||||
class:pointer-events-none={!canScrollLeft}
|
||||
aria-label="Scroll tabs left"
|
||||
@@ -89,8 +89,8 @@
|
||||
aria-selected={activeTab === tab.id}
|
||||
aria-controls={`tab-${tab.id}`}
|
||||
id={`tab-button-${tab.id}`}
|
||||
class="text-tertiary inline-flex flex-shrink-0 items-center rounded-t-lg px-6 py-2 font-bold whitespace-nowrap transition-colors duration-100 ease-in-out lg:border-t-1 lg:border-r-1 lg:border-l-1 lg:border-[#E6E5F7]"
|
||||
class:bg-[#E6E5F7]={activeTab === tab.id}
|
||||
class="text-secondary lg:border-purple-tint inline-flex flex-shrink-0 items-center rounded-t-lg px-6 py-2 font-bold whitespace-nowrap transition-colors duration-100 ease-in-out lg:border-t-1 lg:border-r-1 lg:border-l-1"
|
||||
class:bg-purple-tint={activeTab === tab.id}
|
||||
onclick={() => selectTab(tab.id)}
|
||||
>
|
||||
{tab.label}
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
<button
|
||||
onclick={() => scrollTabs("right")}
|
||||
class="absolute top-5 right-0 z-10 h-8 w-8 -translate-y-1/2 rounded-l-sm bg-[#e6e5f7] p-2 shadow-md lg:hidden"
|
||||
class="bg-purple-tint absolute top-5 right-0 z-10 h-8 w-8 -translate-y-1/2 rounded-l-sm p-2 shadow-md lg:hidden"
|
||||
class:opacity-50={!canScrollRight}
|
||||
class:pointer-events-none={!canScrollRight}
|
||||
aria-label="Scroll tabs right"
|
||||
@@ -117,7 +117,7 @@
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="flex w-full justify-center bg-[#E6E5F7] py-10 lg:py-20">
|
||||
<div class="bg-purple-tint flex w-full justify-center py-10 lg:py-20">
|
||||
<div class="wrapper flex items-center justify-center">
|
||||
{#if activeTab === "rewards"}
|
||||
<div
|
||||
|
||||
@@ -8,10 +8,10 @@ import Contributions from "../../../components/Admin/Contributions.svelte";
|
||||
<main class="wrapper">
|
||||
<div class="flex w-full flex-col gap-8 py-10">
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("contributions.title")}
|
||||
</h2>
|
||||
<p class="text-[#575757]">{t("contributions.description")}</p>
|
||||
<p class="text-content">{t("contributions.description")}</p>
|
||||
</div>
|
||||
|
||||
<Contributions client:load />
|
||||
|
||||
@@ -18,10 +18,10 @@ const accountingIdPlatoniq = Number(getPlatoniqAccountingId() || 0);
|
||||
<BackButton />
|
||||
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("checkout.title")}
|
||||
</h2>
|
||||
<p class="text-[#575757]">
|
||||
<p class="text-content">
|
||||
{t("checkout.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -29,14 +29,14 @@ const accountingIdPlatoniq = Number(getPlatoniqAccountingId() || 0);
|
||||
<Cart client:load {defaultCurrency} {accountingIdPlatoniq} />
|
||||
</div>
|
||||
<div
|
||||
class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
>
|
||||
<Summary client:load {defaultCurrency} {accountingIdPlatoniq} />
|
||||
<Steps step={1} client:load />
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
<p class="text-sm text-[#575757]">{t("checkout.summary.deduct")}</p>
|
||||
<p class="text-content text-sm">{t("checkout.summary.deduct")}</p>
|
||||
<a
|
||||
class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
class="bg-primary text-secondary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold"
|
||||
href="/payment"
|
||||
>
|
||||
{t("global.btn.continue")}
|
||||
|
||||
@@ -4,6 +4,7 @@ import LoginForm from "../../components/LoginForm.astro";
|
||||
import Summary from "../../components/Checkout/Summary.svelte";
|
||||
import Steps from "../../components/Checkout/Steps.svelte";
|
||||
import Oauth from "../../components/Oauth.astro";
|
||||
import Button from "../../components/library/Button.svelte";
|
||||
import BackButton from "../../components/BackButton.astro";
|
||||
import { itemCount } from "../../stores/cart";
|
||||
|
||||
@@ -24,20 +25,20 @@ itemCount.subscribe((count) => {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("login.page.title")}
|
||||
</h2>
|
||||
{hasCart && <p class="text-[#575757]">{t("login.page.description")}</p>}
|
||||
{hasCart && <p class="text-content">{t("login.page.description")}</p>}
|
||||
</div>
|
||||
<div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-2xl font-bold text-black">
|
||||
{t("login.page.registerOr")}
|
||||
</h2>
|
||||
<a
|
||||
href="/register"
|
||||
class="text-tertiary rounded-2xl bg-[#E6E5F7] px-4 py-2 font-bold"
|
||||
class="text-secondary bg-purple-tint rounded-2xl px-4 py-2 font-bold"
|
||||
>
|
||||
{t("login.page.registerBtnLabel")}
|
||||
</a>
|
||||
@@ -53,42 +54,34 @@ itemCount.subscribe((count) => {
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
>
|
||||
{hasCart && <Summary client:load />}
|
||||
{hasCart && <Steps step={2} client:load />}
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
{
|
||||
hasCart && (
|
||||
<p class="text-sm text-[#575757]">{t("checkout.summary.deduct")}</p>
|
||||
)
|
||||
}
|
||||
{hasCart && <p class="text-content text-sm">{t("checkout.summary.deduct")}</p>}
|
||||
|
||||
{
|
||||
!hasCart && (
|
||||
<div class="flex flex-col gap-6 pt-6 pb-0">
|
||||
<div>
|
||||
<h2
|
||||
class={`text-[56px] leading-tight font-semibold text-[#462949]`}
|
||||
class={`text-secondary text-[56px] leading-tight font-semibold`}
|
||||
>
|
||||
{t("login.page.welcome.title")}
|
||||
</h2>
|
||||
<p class="font-light text-[#575757]">
|
||||
<p class="text-content font-light">
|
||||
{t("login.page.welcome.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
<hr class="bg-[#462949]" />
|
||||
<hr class="bg-secondary" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<button
|
||||
form="login"
|
||||
class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
onclick="document.getElementById('login')?.requestSubmit(); return false;"
|
||||
>
|
||||
<Button type="submit" form="login" class="w-fit">
|
||||
{t("global.btn.continue")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import Layout from "../../../layouts/Layout.astro";
|
||||
import Summary from "../../../components/Checkout/Summary.svelte";
|
||||
import PaymentMethod from "../../../components/Checkout/PaymentMethod.astro";
|
||||
import Steps from "../../../components/Checkout/Steps.svelte";
|
||||
import Button from "../../../components/library/Button.svelte";
|
||||
import BackButton from "../../../components/BackButton.astro";
|
||||
import { getDefaultCurrency } from "../../../utils/consts.ts";
|
||||
import { apiAccountingsIdGet, apiGatewaysGetCollection } from "../../../openapi/client/index";
|
||||
@@ -37,10 +38,10 @@ const { data: paymentGateways } = await apiGatewaysGetCollection();
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("payment.page.title")}
|
||||
</h2>
|
||||
<p class="text-[#575757]">
|
||||
<p class="text-content">
|
||||
{t("payment.page.description")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -50,19 +51,17 @@ const { data: paymentGateways } = await apiGatewaysGetCollection();
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
>
|
||||
<Summary client:load {defaultCurrency} />
|
||||
<Steps step={3} client:load />
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
<p class="text-sm text-[#575757]">{t("checkout.summary.deduct")}</p>
|
||||
<button
|
||||
class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
form="payment"
|
||||
onclick="document.getElementById('payment')?.requestSubmit(); return false;"
|
||||
>
|
||||
<p class="text-content text-sm">
|
||||
{t("checkout.summary.deduct")}
|
||||
</p>
|
||||
<Button type="submit" form="payment" class="w-fit">
|
||||
{t("global.btn.continue")}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -70,10 +70,10 @@ try {
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-row items-center justify-between gap-6">
|
||||
<div class="flex w-2/3 flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("payment.page-error.title")}
|
||||
</h2>
|
||||
<p class="text-[#575757]">
|
||||
<p class="text-content">
|
||||
{t("payment.page-error.description")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -88,12 +88,12 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white">
|
||||
<div class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white">
|
||||
<Summary client:load hasError={!!error} {defaultCurrency} {amount} />
|
||||
<Steps client:load step={4} hasError={!!error} />
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
<p class="text-sm text-[#575757]">{t("checkout.summary.deduct")}</p>
|
||||
<a class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]">
|
||||
<p class="text-content text-sm">{t("checkout.summary.deduct")}</p>
|
||||
<a class="bg-primary text-secondary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold">
|
||||
{t("global.btn.continue")}
|
||||
</a>
|
||||
</div>
|
||||
@@ -109,10 +109,10 @@ try {
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-row items-center justify-between gap-6">
|
||||
<div class="flex w-2/3 flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("payment.page-aproved.title")}
|
||||
</h2>
|
||||
<p class="text-[#575757]">
|
||||
<p class="text-content">
|
||||
{t("payment.page-aproved.description")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -124,14 +124,14 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white">
|
||||
<div class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white">
|
||||
<Summary client:load {defaultCurrency} {amount} />
|
||||
<Steps step={4} client:load />
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
<p class="text-sm text-[#575757]">
|
||||
<p class="text-content text-sm">
|
||||
{t("checkout.summary.deduct")}
|
||||
</p>
|
||||
<a class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]">
|
||||
<a class="bg-primary text-secondary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold">
|
||||
{t("global.btn.continue")}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -30,10 +30,10 @@ const { data: accounting } = await apiAccountingsIdGet({
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("payment.wallet-confirmation.title")}
|
||||
</h2>
|
||||
<p class="text-[#575757]">
|
||||
<p class="text-content">
|
||||
{t("payment.wallet-confirmation.description")}
|
||||
</p>
|
||||
</div>
|
||||
@@ -43,14 +43,14 @@ const { data: accounting } = await apiAccountingsIdGet({
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
>
|
||||
<Summary client:load {defaultCurrency} />
|
||||
<Steps step={3} client:load />
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
<p class="text-sm text-[#575757]">{t("checkout.summary.deduct")}</p>
|
||||
<p class="text-content text-sm">{t("checkout.summary.deduct")}</p>
|
||||
<a
|
||||
class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
class="bg-primary text-secondary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold"
|
||||
>
|
||||
{t("global.btn.continue")}
|
||||
</a>
|
||||
|
||||
@@ -168,7 +168,7 @@ const avatarImage = user?.avatar || undefined; // Use user avatar or default pla
|
||||
{
|
||||
errorMessage ? (
|
||||
<div class="flex min-h-screen items-center justify-center">
|
||||
<p class="text-secondary text-xl">{errorMessage}</p>
|
||||
<p class="text-tertiary text-xl">{errorMessage}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div class="flex w-full flex-col items-center gap-10">
|
||||
@@ -193,7 +193,7 @@ const avatarImage = user?.avatar || undefined; // Use user avatar or default pla
|
||||
{bio && (
|
||||
<div class="mx-auto mt-10 w-full max-w-[898px] px-4">
|
||||
<div
|
||||
class="prose prose-base text-secondary leading-6"
|
||||
class="prose prose-base text-tertiary leading-6"
|
||||
set:html={renderMarkdown(bio)}
|
||||
/>
|
||||
</div>
|
||||
@@ -208,7 +208,7 @@ const avatarImage = user?.avatar || undefined; // Use user avatar or default pla
|
||||
</div>
|
||||
) : (
|
||||
<div class="mx-auto mt-10 w-full max-w-[898px] px-4 text-center">
|
||||
<p class="text-secondary text-base">{t("profile.noProjects")}</p>
|
||||
<p class="text-tertiary text-base">{t("profile.noProjects")}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import Layout from "../../layouts/Layout.astro";
|
||||
import RegisterForm from "../../components/RegisterForm.astro";
|
||||
import Summary from "../../components/Checkout/Summary.svelte";
|
||||
import Steps from "../../components/Checkout/Steps.svelte";
|
||||
import Button from "../../components/library/Button.svelte";
|
||||
import Oauth from "../../components/Oauth.astro";
|
||||
import { itemCount } from "../../stores/cart";
|
||||
|
||||
@@ -21,12 +22,12 @@ itemCount.subscribe((count) => {
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col gap-10">
|
||||
<div class="flex flex-col gap-4">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-[#3D3D3D]">
|
||||
<h2 class="text-[40px]/[48px] font-bold tracking-[0%] text-black">
|
||||
{t("register.page.title")}
|
||||
</h2>
|
||||
{
|
||||
hasCart && (
|
||||
<p class="text-[#575757]">{t("register.page.description")}</p>
|
||||
<p class="text-content">{t("register.page.description")}</p>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
@@ -34,16 +35,16 @@ itemCount.subscribe((count) => {
|
||||
<div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<h2 class="text-secondary text-2xl font-bold">
|
||||
<h2 class="text-2xl font-bold text-black">
|
||||
{t("register.page.registerOr")}
|
||||
</h2>
|
||||
<a
|
||||
href="login"
|
||||
class="text-tertiary rounded-2xl bg-[#E6E5F7] px-4 py-2 font-bold"
|
||||
class="text-secondary bg-purple-tint rounded-2xl px-4 py-2 font-bold"
|
||||
>{t("register.page.loginBtnLabel")}
|
||||
</a>
|
||||
</div>
|
||||
<p class="text-[#575757]">{t("register.page.goteoUserInfo")}</p>
|
||||
<p class="text-content">{t("register.page.goteoUserInfo")}</p>
|
||||
</div>
|
||||
<RegisterForm />
|
||||
</div>
|
||||
@@ -56,40 +57,34 @@ itemCount.subscribe((count) => {
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="border-tertiary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
class="border-secondary sticky top-10 flex h-fit w-1/2 flex-col gap-6 rounded-[40px] border bg-white"
|
||||
>
|
||||
{hasCart && <Summary client:load />}
|
||||
{hasCart && <Steps step={2} client:load />}
|
||||
<div class="flex flex-col gap-4 px-6 pt-0 pb-6">
|
||||
{
|
||||
hasCart && (
|
||||
<p class="text-sm text-[#575757]">{t("checkout.summary.deduct")}</p>
|
||||
)
|
||||
}
|
||||
{hasCart && <p class="text-content text-sm">{t("checkout.summary.deduct")}</p>}
|
||||
|
||||
{
|
||||
!hasCart && (
|
||||
<div class="flex flex-col gap-6 pt-6 pb-0">
|
||||
<div>
|
||||
<h2
|
||||
class={`text-[56px] leading-tight font-semibold text-[#462949]`}
|
||||
class={`text-secondary text-[56px] leading-tight font-semibold`}
|
||||
>
|
||||
{t("login.page.welcome.title")}
|
||||
</h2>
|
||||
<p class="font-light text-[#575757]">
|
||||
<p class="text-content font-light">
|
||||
{t("login.page.welcome.subtitle")}
|
||||
</p>
|
||||
</div>
|
||||
<hr class="bg-[#462949]" />
|
||||
<hr class="bg-secondary" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<a
|
||||
class="bg-primary w-fit cursor-pointer rounded-3xl px-6 py-4 font-bold text-[#462949]"
|
||||
>
|
||||
{t("global.btn.continue")}
|
||||
</a>
|
||||
<Button type="submit" form="register" class="w-fit">
|
||||
{t("register.form.btnSubmit")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,18 +12,21 @@
|
||||
@theme {
|
||||
/* Light Theme (default) */
|
||||
--color-primary: #59e9d3;
|
||||
--color-secondary: #3d3d3d;
|
||||
--color-tertiary: #462949;
|
||||
--color-secondary: #462949;
|
||||
--color-tertiary: #e94668;
|
||||
--color-background: #f8fafc;
|
||||
--color-content: #575757;
|
||||
--color-body: #1e293b;
|
||||
|
||||
/* Extended color tokens for components */
|
||||
--color-white: #fbfbfb;
|
||||
--color-black: #3d3d3d;
|
||||
--color-light-accent: #e6d9f3; /* Light purple accent for buttons */
|
||||
--color-light-surface: #fbfbfb; /* Light background surface */
|
||||
--color-light-muted: #f3f3ef; /* Muted light background */
|
||||
--color-purple-tint: #e6e5f7; /* Light purple tint */
|
||||
--color-soft-purple: #faf9ff;
|
||||
--color-neutral-light: #e6e6e6; /* Light neutral border */
|
||||
--color-white: #ffffff; /* Pure white */
|
||||
|
||||
--font-body: "Karla", sans-serif;
|
||||
--body-regular: 1rem;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</script>
|
||||
|
||||
<svg
|
||||
class={`fill-(--color-tertiary) ${className}`}
|
||||
class={`fill-(--color-secondary) ${className}`}
|
||||
{width}
|
||||
{height}
|
||||
viewBox="0 0 32 32"
|
||||
|
||||
Reference in New Issue
Block a user