-
Deforestation-free suppliers
-
-
- 31%
of suppliers
+
+ {/*
+
+
+
Deforestation-free suppliers
+
+
+ 31% of suppliers
+
+
+
+
+
-
-
+
+
+ test
+
+
+
+
+
+
Suppliers with deforestation alerts
+
+
+ 36% of suppliers
+
+
+
+
-
-
-
-
-
-
-
Suppliers with deforestation alerts
-
-
- 36%
of suppliers
+
+
+ test
+
+
+
+
+
+
Suppliers with no location data
+
+
+ 33% of suppliers
+
+
+
+
+
+
-
-
-
-
-
-
-
-
Suppliers with no location data
-
-
- 33% of suppliers
-
-
-
-
-
-
-
+
+
+ test
+
+ */}
);
diff --git a/client/src/lib/utils.ts b/client/src/lib/utils.ts
new file mode 100644
index 0000000000..9ad0df4269
--- /dev/null
+++ b/client/src/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/client/src/styles/globals.css b/client/src/styles/globals.css
index 1ce4c66ed8..39e3f37c1f 100644
--- a/client/src/styles/globals.css
+++ b/client/src/styles/globals.css
@@ -2,15 +2,76 @@
@tailwind components;
@tailwind utilities;
-@-webkit-keyframes autofill {
- 0%,
- 100% {
- color: #666;
- @apply bg-transparent;
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 222.2 84% 4.9%;
+
+ --card: 0 0% 100%;
+ --card-foreground: 222.2 84% 4.9%;
+
+ --popover: 0 0% 100%;
+ --popover-foreground: 222.2 84% 4.9%;
+
+ --primary: 222.2 47.4% 11.2%;
+ --primary-foreground: 210 40% 98%;
+
+ --secondary: 210 40% 96.1%;
+ --secondary-foreground: 222.2 47.4% 11.2%;
+
+ --muted: 210 40% 96.1%;
+ --muted-foreground: 215.4 16.3% 46.9%;
+
+ --accent: 210 40% 96.1%;
+ --accent-foreground: 222.2 47.4% 11.2%;
+
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 210 40% 98%;
+
+ --border: 214.3 31.8% 91.4%;
+ --input: 214.3 31.8% 91.4%;
+ --ring: 222.2 84% 4.9%;
+
+ --radius: 0.5rem;
}
-}
-@layer base {
+ .dark {
+ --background: 222.2 84% 4.9%;
+ --foreground: 210 40% 98%;
+
+ --card: 222.2 84% 4.9%;
+ --card-foreground: 210 40% 98%;
+
+ --popover: 222.2 84% 4.9%;
+ --popover-foreground: 210 40% 98%;
+
+ --primary: 210 40% 98%;
+ --primary-foreground: 222.2 47.4% 11.2%;
+
+ --secondary: 217.2 32.6% 17.5%;
+ --secondary-foreground: 210 40% 98%;
+
+ --muted: 217.2 32.6% 17.5%;
+ --muted-foreground: 215 20.2% 65.1%;
+
+ --accent: 217.2 32.6% 17.5%;
+ --accent-foreground: 210 40% 98%;
+
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 210 40% 98%;
+
+ --border: 217.2 32.6% 17.5%;
+ --input: 217.2 32.6% 17.5%;
+ --ring: 212.7 26.8% 83.9%;
+ }
+
+ * {
+ @apply border-border;
+ }
+ /* body {
+ @apply bg-background text-foreground;
+ } */
+
input[type='search']::-webkit-search-decoration,
input[type='search']::-webkit-search-cancel-button,
input[type='search']::-webkit-search-results-button,
@@ -56,9 +117,15 @@
}
}
-@layer utilities {
+@-webkit-keyframes autofill {
+ 0%,
+ 100% {
+ color: #666;
+ @apply bg-transparent;
+ }
}
+
.rc-tree .rc-tree-checkbox {
@apply hidden;
}
diff --git a/client/src/utils/number-format.ts b/client/src/utils/number-format.ts
index 3e35866e80..b14809c04c 100644
--- a/client/src/utils/number-format.ts
+++ b/client/src/utils/number-format.ts
@@ -19,3 +19,7 @@ export function formatNumber(number: number): string {
export const PRECISE_NUMBER_FORMAT = format(',.3~r');
export const BIG_NUMBER_FORMAT = format('s');
+
+export const formatPercentage = (value: number, options: Intl.NumberFormatOptions = {}) => {
+ return Intl.NumberFormat(undefined, { style: 'percent', ...options }).format(value);
+};
diff --git a/client/tailwind.config.ts b/client/tailwind.config.ts
new file mode 100644
index 0000000000..de906dfb55
--- /dev/null
+++ b/client/tailwind.config.ts
@@ -0,0 +1,150 @@
+import type { Config } from 'tailwindcss';
+
+const forms = require('@tailwindcss/forms');
+const typography = require('@tailwindcss/typography');
+const colors = require('tailwindcss/colors');
+
+const config = {
+ darkMode: ['class'],
+ content: ['./src/**/*.{ts,tsx}'],
+ prefix: '',
+ theme: {
+ container: {
+ center: true,
+ padding: '2rem',
+ screens: {
+ '2xl': '1400px',
+ },
+ },
+ extend: {
+ fontFamily: {
+ sans: ['Public Sans', 'sans-serif'],
+ },
+ fontSize: {
+ '2xs': '0.625rem', // 10px
+ xs: ['0.75rem', '1rem'], // 12px
+ sm: ['0.875rem', '1.25rem'], // 14px
+ base: ['1rem', '1.5rem'], // 16px
+ lg: ['1.125rem', '1.75rem'], // 18px
+ '2xl': ['1.5rem', '2rem'], // 20px
+ '3xl': ['1.875rem', '2.25rem'], // 24px
+ '4xl': ['2.25rem', '2.5rem'], // 28px
+ },
+ height: {
+ 'screen-minus-header': "calc(100vh - theme('spacing.16'))",
+ },
+ spacing: {
+ 125: '30.875rem',
+ 250: '48.75rem',
+ },
+ backgroundImage: {
+ auth: 'linear-gradient(240.36deg, #2E34B0 0%, #0C1063 68.13%)',
+ },
+ boxShadow: {
+ menu: '0 4px 4px 0px rgba(0, 0, 0, 0.25)',
+ 'button-hovered':
+ '0px 0px 0px 6px rgba(0, 0, 0, 0.26), 0px 4px 4px 0px rgba(0, 0, 0, 0.25)',
+ 'button-focused': '0px 0px 0px 4px rgba(63, 89, 224, 0.20), 0px 0px 0px 1px #FFF',
+ },
+ colors: {
+ border: 'hsl(var(--border))',
+ input: 'hsl(var(--input))',
+ ring: 'hsl(var(--ring))',
+ background: 'hsl(var(--background))',
+ foreground: 'hsl(var(--foreground))',
+ primary: {
+ DEFAULT: 'hsl(var(--primary))',
+ foreground: 'hsl(var(--primary-foreground))',
+ },
+ secondary: {
+ DEFAULT: 'hsl(var(--secondary))',
+ foreground: 'hsl(var(--secondary-foreground))',
+ },
+ destructive: {
+ DEFAULT: 'hsl(var(--destructive))',
+ foreground: 'hsl(var(--destructive-foreground))',
+ },
+ muted: {
+ DEFAULT: 'hsl(var(--muted))',
+ foreground: 'hsl(var(--muted-foreground))',
+ },
+ accent: {
+ DEFAULT: 'hsl(var(--accent))',
+ foreground: 'hsl(var(--accent-foreground))',
+ },
+ popover: {
+ DEFAULT: 'hsl(var(--popover))',
+ foreground: 'hsl(var(--popover-foreground))',
+ },
+ card: {
+ DEFAULT: 'hsl(var(--card))',
+ foreground: 'hsl(var(--card-foreground))',
+ },
+ gray: {
+ 900: '#15181F',
+ 600: '#40424B',
+ 500: '#60626A',
+ 400: '#8F9195',
+ 300: '#AEB1B5',
+ 200: '#D1D5DB',
+ 100: '#F3F4F6',
+ 50: '#F9FAFB',
+ },
+ navy: {
+ 50: '#F0F2FD', // light navy
+ 200: '#C7CDEA', // light mid navy
+ 400: '#3F59E0', // navy
+ 600: '#2E34B0', // mid navy
+ 900: '#152269', // dark navy
+ },
+ orange: {
+ 500: '#FFA000', // orange
+ 300: '#F0B957', // light mid orange
+ 100: '#F9DFB1', // light orange
+ 50: '#FFF1D9', // lightest orange
+ },
+ blue: {
+ 400: '#4AB7F3', // blue
+ 200: '#C7F0FF', // soft blue
+ },
+ green: {
+ 800: '#006D2C',
+ 400: '#078A3C',
+ 200: '#CDE8D8',
+ 50: '#E6F9EE',
+ },
+ red: {
+ 800: '#BA1809', // dark red
+ 400: '#E93323', // red
+ 50: '#FEF2F2', // light red
+ },
+ },
+ borderRadius: {
+ lg: 'var(--radius)',
+ md: 'calc(var(--radius) - 2px)',
+ sm: 'calc(var(--radius) - 4px)',
+ },
+ keyframes: {
+ 'accordion-down': {
+ from: { height: '0' },
+ to: { height: 'var(--radix-accordion-content-height)' },
+ },
+ 'accordion-up': {
+ from: { height: 'var(--radix-accordion-content-height)' },
+ to: { height: '0' },
+ },
+ },
+ animation: {
+ 'accordion-down': 'accordion-down 0.2s ease-out',
+ 'accordion-up': 'accordion-up 0.2s ease-out',
+ },
+ },
+ },
+ plugins: [
+ require('tailwindcss-animate'),
+ require('@tailwindcss/forms'),
+ require('@tailwindcss/typography'),
+ ],
+} satisfies Config;
+
+export default config;
diff --git a/client/tailwind.config.js b/client/tailwind.config_old.js
similarity index 100%
rename from client/tailwind.config.js
rename to client/tailwind.config_old.js
diff --git a/client/yarn.lock b/client/yarn.lock
index 4650448ed6..b8c55dc06a 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -209,6 +209,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.23.7":
+ version: 7.24.0
+ resolution: "@babel/runtime@npm:7.24.0"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: 7a6a5d40fbdd68491ec183ba2e631c07415119960083b4fd76564cce3751e9acd2f12ab89575e38496fa389fa06d458732776e69ee1858e366cc3fbdb049f847
+ languageName: node
+ linkType: hard
+
"@babel/runtime@npm:^7.20.0":
version: 7.20.1
resolution: "@babel/runtime@npm:7.20.1"
@@ -1565,6 +1574,191 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/primitive@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/primitive@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ checksum: 2b93e161d3fdabe9a64919def7fa3ceaecf2848341e9211520c401181c9eaebb8451c630b066fad2256e5c639c95edc41de0ba59c40eff37e799918d019822d1
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-collapsible@npm:1.0.3":
+ version: 1.0.3
+ resolution: "@radix-ui/react-collapsible@npm:1.0.3"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@radix-ui/primitive": 1.0.1
+ "@radix-ui/react-compose-refs": 1.0.1
+ "@radix-ui/react-context": 1.0.1
+ "@radix-ui/react-id": 1.0.1
+ "@radix-ui/react-presence": 1.0.1
+ "@radix-ui/react-primitive": 1.0.3
+ "@radix-ui/react-use-controllable-state": 1.0.1
+ "@radix-ui/react-use-layout-effect": 1.0.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 26976e4a72a3e0f4b2c62af2898b3e205c3652af46a3b41cda9a43567fe8381d9ef6afb0b29e3214c450b847f4f2099a533cffc5045844ecab290e9fa6114ca9
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-compose-refs@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-compose-refs@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 2b9a613b6db5bff8865588b6bf4065f73021b3d16c0a90b2d4c23deceeb63612f1f15de188227ebdc5f88222cab031be617a9dd025874c0487b303be3e5cc2a8
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-context@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-context@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 60e9b81d364f40c91a6213ec953f7c64fcd9d75721205a494a5815b3e5ae0719193429b62ee6c7002cd6aaf70f8c0e2f08bdbaba9ffcc233044d32b56d2127d1
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-id@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-id@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@radix-ui/react-use-layout-effect": 1.0.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 446a453d799cc790dd2a1583ff8328da88271bff64530b5a17c102fa7fb35eece3cf8985359d416f65e330cd81aa7b8fe984ea125fc4f4eaf4b3801d698e49fe
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-presence@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-presence@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@radix-ui/react-compose-refs": 1.0.1
+ "@radix-ui/react-use-layout-effect": 1.0.1
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: ed2ff9faf9e4257a4065034d3771459e5a91c2d840b2fcec94661761704dbcb65bcdd927d28177a2a129b3dab5664eb90a9b88309afe0257a9f8ba99338c0d95
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-primitive@npm:1.0.3":
+ version: 1.0.3
+ resolution: "@radix-ui/react-primitive@npm:1.0.3"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@radix-ui/react-slot": 1.0.2
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 9402bc22923c8e5c479051974a721c301535c36521c0237b83e5fa213d013174e77f3ad7905e6d60ef07e14f88ec7f4ea69891dc7a2b39047f8d3640e8f8d713
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-slot@npm:1.0.2":
+ version: 1.0.2
+ resolution: "@radix-ui/react-slot@npm:1.0.2"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@radix-ui/react-compose-refs": 1.0.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: edf5edf435ff594bea7e198bf16d46caf81b6fb559493acad4fa8c308218896136acb16f9b7238c788fd13e94a904f2fd0b6d834e530e4cae94522cdb8f77ce9
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-callback-ref@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-use-callback-ref@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: b9fd39911c3644bbda14a84e4fca080682bef84212b8d8931fcaa2d2814465de242c4cfd8d7afb3020646bead9c5e539d478cea0a7031bee8a8a3bb164f3bc4c
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-controllable-state@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-use-controllable-state@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@radix-ui/react-use-callback-ref": 1.0.1
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: dee2be1937d293c3a492cb6d279fc11495a8f19dc595cdbfe24b434e917302f9ac91db24e8cc5af9a065f3f209c3423115b5442e65a5be9fd1e9091338972be9
+ languageName: node
+ linkType: hard
+
+"@radix-ui/react-use-layout-effect@npm:1.0.1":
+ version: 1.0.1
+ resolution: "@radix-ui/react-use-layout-effect@npm:1.0.1"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: bed9c7e8de243a5ec3b93bb6a5860950b0dba359b6680c84d57c7a655e123dec9b5891c5dfe81ab970652e7779fe2ad102a23177c7896dde95f7340817d47ae5
+ languageName: node
+ linkType: hard
+
"@reduxjs/toolkit@npm:1.8.2":
version: 1.8.2
resolution: "@reduxjs/toolkit@npm:1.8.2"
@@ -3229,6 +3423,15 @@ __metadata:
languageName: node
linkType: hard
+"class-variance-authority@npm:0.7.0":
+ version: 0.7.0
+ resolution: "class-variance-authority@npm:0.7.0"
+ dependencies:
+ clsx: 2.0.0
+ checksum: e7fd1fab433ef06f52a1b7b241b70b4a185864deef199d3b0a2c3412f1cc179517288264c383f3b971a00d76811625fc8f7ffe709e6170219e88cd7368f08a20
+ languageName: node
+ linkType: hard
+
"classnames@npm:2.3.1, classnames@npm:2.x, classnames@npm:^2.2.1, classnames@npm:^2.2.6":
version: 2.3.1
resolution: "classnames@npm:2.3.1"
@@ -3300,6 +3503,20 @@ __metadata:
languageName: node
linkType: hard
+"clsx@npm:2.0.0":
+ version: 2.0.0
+ resolution: "clsx@npm:2.0.0"
+ checksum: a2cfb2351b254611acf92faa0daf15220f4cd648bdf96ce369d729813b85336993871a4bf6978ddea2b81b5a130478339c20d9d0b5c6fc287e5147f0c059276e
+ languageName: node
+ linkType: hard
+
+"clsx@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "clsx@npm:2.1.0"
+ checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d
+ languageName: node
+ linkType: hard
+
"color-convert@npm:^1.9.0":
version: 1.9.3
resolution: "color-convert@npm:1.9.3"
@@ -6644,6 +6861,7 @@ __metadata:
"@json2csv/plainjs": ^6.1.3
"@loaders.gl/core": 3.3.1
"@luma.gl/constants": 8.5.18
+ "@radix-ui/react-collapsible": 1.0.3
"@reduxjs/toolkit": 1.8.2
"@tailwindcss/forms": 0.4.0
"@tailwindcss/typography": 0.5.0
@@ -6663,7 +6881,9 @@ __metadata:
autoprefixer: 10.2.5
axios: 1.3.4
chroma-js: 2.1.2
+ class-variance-authority: 0.7.0
classnames: 2.3.1
+ clsx: ^2.1.0
cypress: 13.2.0
d3-array: 3.0.2
d3-format: 3.0.1
@@ -6703,7 +6923,9 @@ __metadata:
rooks: 7.14.1
sharp: 0.32.6
start-server-and-test: 1.14.0
+ tailwind-merge: 2.2.1
tailwindcss: 3.3.1
+ tailwindcss-animate: 1.0.7
typescript: 5.2.2
update-browserslist-db: ^1.0.13
uuid: 8.3.2
@@ -9862,6 +10084,24 @@ __metadata:
languageName: node
linkType: hard
+"tailwind-merge@npm:2.2.1":
+ version: 2.2.1
+ resolution: "tailwind-merge@npm:2.2.1"
+ dependencies:
+ "@babel/runtime": ^7.23.7
+ checksum: fd149409b1c18f3bc57aa30ae3a0e0c7f2913636666bd920c1aceeb8798b36766be55dfec8581e63860b83c7e405700ef530952a59c828ccff0c2a401fa67f05
+ languageName: node
+ linkType: hard
+
+"tailwindcss-animate@npm:1.0.7":
+ version: 1.0.7
+ resolution: "tailwindcss-animate@npm:1.0.7"
+ peerDependencies:
+ tailwindcss: "*"
+ checksum: c1760983eb3fec0c8421e95082bf308e6845df43e2f90862386366e82545c801b26b4d189c4cd23d6915252b76d18005c8e5f591f8b119944c7fb8650d0f8bce
+ languageName: node
+ linkType: hard
+
"tailwindcss@npm:3.3.1":
version: 3.3.1
resolution: "tailwindcss@npm:3.3.1"