@burdenoff/microfe-ecoimpacthub 2026.509.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +12 -0
  2. package/dist/dev/main.d.ts +2 -0
  3. package/dist/dev/main.d.ts.map +1 -0
  4. package/dist/ecoimpacthub/EcoImpactHubRoot.d.ts +5 -0
  5. package/dist/ecoimpacthub/EcoImpactHubRoot.d.ts.map +1 -0
  6. package/dist/ecoimpacthub/EcoImpactHubRoot.js +126 -0
  7. package/dist/ecoimpacthub/EcoImpactHubRoot.js.map +1 -0
  8. package/dist/ecoimpacthub/EcoImpactHubRoutes.d.ts +2 -0
  9. package/dist/ecoimpacthub/EcoImpactHubRoutes.d.ts.map +1 -0
  10. package/dist/ecoimpacthub/EcoImpactHubRoutes.js +55 -0
  11. package/dist/ecoimpacthub/EcoImpactHubRoutes.js.map +1 -0
  12. package/dist/ecoimpacthub/index.d.ts +5 -0
  13. package/dist/ecoimpacthub/index.d.ts.map +1 -0
  14. package/dist/ecoimpacthub/index.js +3 -0
  15. package/dist/ecoimpacthub/pages/ActionTrackerPage.d.ts +2 -0
  16. package/dist/ecoimpacthub/pages/ActionTrackerPage.d.ts.map +1 -0
  17. package/dist/ecoimpacthub/pages/ActionTrackerPage.js +449 -0
  18. package/dist/ecoimpacthub/pages/ActionTrackerPage.js.map +1 -0
  19. package/dist/ecoimpacthub/pages/ChallengesPage.d.ts +2 -0
  20. package/dist/ecoimpacthub/pages/ChallengesPage.d.ts.map +1 -0
  21. package/dist/ecoimpacthub/pages/ChallengesPage.js +242 -0
  22. package/dist/ecoimpacthub/pages/ChallengesPage.js.map +1 -0
  23. package/dist/ecoimpacthub/pages/CitizenSciencePage.d.ts +2 -0
  24. package/dist/ecoimpacthub/pages/CitizenSciencePage.d.ts.map +1 -0
  25. package/dist/ecoimpacthub/pages/CitizenSciencePage.js +443 -0
  26. package/dist/ecoimpacthub/pages/CitizenSciencePage.js.map +1 -0
  27. package/dist/ecoimpacthub/pages/CommunityPage.d.ts +2 -0
  28. package/dist/ecoimpacthub/pages/CommunityPage.d.ts.map +1 -0
  29. package/dist/ecoimpacthub/pages/CommunityPage.js +377 -0
  30. package/dist/ecoimpacthub/pages/CommunityPage.js.map +1 -0
  31. package/dist/ecoimpacthub/pages/DashboardPage.d.ts +2 -0
  32. package/dist/ecoimpacthub/pages/DashboardPage.d.ts.map +1 -0
  33. package/dist/ecoimpacthub/pages/DashboardPage.js +380 -0
  34. package/dist/ecoimpacthub/pages/DashboardPage.js.map +1 -0
  35. package/dist/ecoimpacthub/pages/LearningPage.d.ts +2 -0
  36. package/dist/ecoimpacthub/pages/LearningPage.d.ts.map +1 -0
  37. package/dist/ecoimpacthub/pages/LearningPage.js +276 -0
  38. package/dist/ecoimpacthub/pages/LearningPage.js.map +1 -0
  39. package/dist/ecoimpacthub/providers/EcoImpactHubProvider.d.ts +6 -0
  40. package/dist/ecoimpacthub/providers/EcoImpactHubProvider.d.ts.map +1 -0
  41. package/dist/ecoimpacthub/providers/EcoImpactHubProvider.js +27 -0
  42. package/dist/ecoimpacthub/providers/EcoImpactHubProvider.js.map +1 -0
  43. package/dist/ecoimpacthub/store/ecoimpacthubStore.d.ts +135 -0
  44. package/dist/ecoimpacthub/store/ecoimpacthubStore.d.ts.map +1 -0
  45. package/dist/ecoimpacthub/store/ecoimpacthubStore.js +551 -0
  46. package/dist/ecoimpacthub/store/ecoimpacthubStore.js.map +1 -0
  47. package/dist/ecoimpacthub/types/index.d.ts +51 -0
  48. package/dist/ecoimpacthub/types/index.d.ts.map +1 -0
  49. package/dist/ecoimpacthub/utils/cn.d.ts +4 -0
  50. package/dist/ecoimpacthub/utils/cn.d.ts.map +1 -0
  51. package/dist/ecoimpacthub/utils/i18n.d.ts +6 -0
  52. package/dist/ecoimpacthub/utils/i18n.d.ts.map +1 -0
  53. package/dist/ecoimpacthub/utils/i18n.js +15 -0
  54. package/dist/ecoimpacthub/utils/i18n.js.map +1 -0
  55. package/dist/ecoimpacthub/utils/navigation.d.ts +2 -0
  56. package/dist/ecoimpacthub/utils/navigation.d.ts.map +1 -0
  57. package/dist/ecoimpacthub/utils/navigation.js +8 -0
  58. package/dist/ecoimpacthub/utils/navigation.js.map +1 -0
  59. package/dist/generated/global-operations.d.ts +2 -0
  60. package/dist/generated/global-operations.d.ts.map +1 -0
  61. package/dist/generated/global-types.d.ts +18199 -0
  62. package/dist/generated/global-types.d.ts.map +1 -0
  63. package/dist/generated/wspace-operations.d.ts +2 -0
  64. package/dist/generated/wspace-operations.d.ts.map +1 -0
  65. package/dist/generated/wspace-types.d.ts +43046 -0
  66. package/dist/generated/wspace-types.d.ts.map +1 -0
  67. package/dist/index.d.ts +2 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +5 -0
  70. package/package.json +107 -0
@@ -0,0 +1,242 @@
1
+ import { useEcoImpactHubStore as e } from "../store/ecoimpacthubStore.js";
2
+ import { tWithFallback as t } from "../utils/i18n.js";
3
+ import { useState as n } from "react";
4
+ import { Award as r, Calendar as i, Leaf as a, Star as o, Target as s, Trophy as c, Users as l, Zap as u } from "lucide-react";
5
+ import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { Badge as f, Button as p, Card as m, CardContent as h } from "@burdenoff/fe-libs/ui";
7
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
8
+ //#region src/ecoimpacthub/pages/ChallengesPage.tsx
9
+ function v() {
10
+ let { t: v } = d(), { challenges: y } = e(), [b, x] = n("active"), [S, C] = n("all"), w = (e, n, r) => t(v, e, n, r), T = y.filter((e) => e.status === b && (S === "all" || e.category === S)), E = (e) => {
11
+ switch (e) {
12
+ case "easy": return "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300";
13
+ case "medium": return "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300";
14
+ case "hard": return "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300";
15
+ default: return "bg-muted text-muted-foreground";
16
+ }
17
+ }, D = (e) => {
18
+ switch (e) {
19
+ case "individual": return /* @__PURE__ */ g(s, { className: "h-4 w-4" });
20
+ case "community": return /* @__PURE__ */ g(l, { className: "h-4 w-4" });
21
+ case "global": return /* @__PURE__ */ g(r, { className: "h-4 w-4" });
22
+ default: return /* @__PURE__ */ g(o, { className: "h-4 w-4" });
23
+ }
24
+ }, O = (e) => {
25
+ switch (e) {
26
+ case "active": return w("ecoimpacthub.challenges.tabs.active", "Active");
27
+ case "completed": return w("ecoimpacthub.challenges.tabs.completed", "Completed");
28
+ case "upcoming": return w("ecoimpacthub.challenges.tabs.upcoming", "Upcoming");
29
+ default: return e;
30
+ }
31
+ }, k = (e) => {
32
+ switch (e) {
33
+ case "all": return w("ecoimpacthub.challenges.categories.all", "All");
34
+ case "individual": return w("ecoimpacthub.challenges.categories.individual", "Individual");
35
+ case "community": return w("ecoimpacthub.challenges.categories.community", "Community");
36
+ case "global": return w("ecoimpacthub.challenges.categories.global", "Global");
37
+ default: return e;
38
+ }
39
+ }, A = (e) => {
40
+ switch (e) {
41
+ case "easy": return w("ecoimpacthub.challenges.difficulty.easy", "Easy");
42
+ case "medium": return w("ecoimpacthub.challenges.difficulty.medium", "Medium");
43
+ case "hard": return w("ecoimpacthub.challenges.difficulty.hard", "Hard");
44
+ default: return e;
45
+ }
46
+ }, j = (e) => {
47
+ switch (e) {
48
+ case "active": return w("ecoimpacthub.challenges.actions.joinChallenge", "Join Challenge");
49
+ case "completed": return w("ecoimpacthub.challenges.actions.viewResults", "View Results");
50
+ case "upcoming": return w("ecoimpacthub.challenges.actions.setReminder", "Set Reminder");
51
+ default: return e;
52
+ }
53
+ }, M = [
54
+ {
55
+ label: w("ecoimpacthub.challenges.stats.totalPoints.label", "Total Points"),
56
+ value: "2,450",
57
+ sub: w("ecoimpacthub.challenges.stats.totalPoints.sub", "+180 this week"),
58
+ icon: c,
59
+ color: "text-primary"
60
+ },
61
+ {
62
+ label: w("ecoimpacthub.challenges.stats.activeStreak.label", "Active Streak"),
63
+ value: "12",
64
+ sub: w("ecoimpacthub.challenges.stats.activeStreak.sub", "days in a row"),
65
+ icon: u,
66
+ color: "text-green-600"
67
+ },
68
+ {
69
+ label: w("ecoimpacthub.challenges.stats.completed.label", "Completed"),
70
+ value: "8",
71
+ sub: w("ecoimpacthub.challenges.stats.completed.sub", "challenges this month"),
72
+ icon: r,
73
+ color: "text-blue-600"
74
+ },
75
+ {
76
+ label: w("ecoimpacthub.challenges.stats.impactScore.label", "Impact Score"),
77
+ value: "95",
78
+ sub: w("ecoimpacthub.challenges.stats.impactScore.sub", "environmental rating"),
79
+ icon: a,
80
+ color: "text-emerald-600"
81
+ }
82
+ ];
83
+ return /* @__PURE__ */ g("div", {
84
+ className: "min-h-screen",
85
+ children: /* @__PURE__ */ _("div", {
86
+ className: "mx-auto max-w-7xl space-y-8 px-4 py-8 sm:px-6 lg:px-8",
87
+ children: [
88
+ /* @__PURE__ */ _("div", {
89
+ className: "space-y-4 text-center",
90
+ children: [/* @__PURE__ */ g("h1", {
91
+ className: "text-4xl font-bold",
92
+ children: w("ecoimpacthub.challenges.title", "Environmental Challenges")
93
+ }), /* @__PURE__ */ g("p", {
94
+ className: "mx-auto max-w-3xl text-xl text-muted-foreground",
95
+ children: w("ecoimpacthub.challenges.subtitle", "Join thousands of eco-warriors in meaningful environmental actions. Complete challenges, earn points, and make a real impact on our planet.")
96
+ })]
97
+ }),
98
+ /* @__PURE__ */ g("div", {
99
+ className: "grid grid-cols-1 gap-6 md:grid-cols-4",
100
+ children: M.map((e) => {
101
+ let t = e.icon;
102
+ return /* @__PURE__ */ g(m, { children: /* @__PURE__ */ _(h, {
103
+ className: "space-y-2 p-6",
104
+ children: [
105
+ /* @__PURE__ */ _("div", {
106
+ className: `flex items-center gap-2 ${e.color}`,
107
+ children: [/* @__PURE__ */ g(t, { className: "h-5 w-5" }), /* @__PURE__ */ g("span", {
108
+ className: "font-semibold",
109
+ children: e.label
110
+ })]
111
+ }),
112
+ /* @__PURE__ */ g("div", {
113
+ className: "text-3xl font-bold",
114
+ children: e.value
115
+ }),
116
+ /* @__PURE__ */ g("div", {
117
+ className: "text-sm text-muted-foreground",
118
+ children: e.sub
119
+ })
120
+ ]
121
+ }) }, e.label);
122
+ })
123
+ }),
124
+ /* @__PURE__ */ _("div", {
125
+ className: "flex flex-col items-center justify-between gap-4 sm:flex-row",
126
+ children: [/* @__PURE__ */ g("div", {
127
+ className: "flex gap-2",
128
+ children: [
129
+ "active",
130
+ "completed",
131
+ "upcoming"
132
+ ].map((e) => /* @__PURE__ */ g(p, {
133
+ variant: b === e ? "default" : "outline",
134
+ size: "sm",
135
+ onClick: () => x(e),
136
+ children: O(e)
137
+ }, e))
138
+ }), /* @__PURE__ */ g("div", {
139
+ className: "flex gap-2",
140
+ children: [
141
+ "all",
142
+ "individual",
143
+ "community",
144
+ "global"
145
+ ].map((e) => /* @__PURE__ */ g(p, {
146
+ variant: S === e ? "default" : "outline",
147
+ size: "sm",
148
+ onClick: () => C(e),
149
+ children: k(e)
150
+ }, e))
151
+ })]
152
+ }),
153
+ /* @__PURE__ */ g("div", {
154
+ className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3",
155
+ children: T.map((e) => /* @__PURE__ */ g(m, {
156
+ className: "overflow-hidden transition-shadow hover:shadow-lg",
157
+ children: /* @__PURE__ */ _(h, {
158
+ className: "space-y-4 p-6",
159
+ children: [
160
+ /* @__PURE__ */ _("div", {
161
+ className: "flex items-start justify-between",
162
+ children: [/* @__PURE__ */ _("div", {
163
+ className: "flex items-center gap-3",
164
+ children: [/* @__PURE__ */ g("div", {
165
+ className: "text-2xl",
166
+ children: e.icon
167
+ }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("h3", {
168
+ className: "text-lg font-semibold",
169
+ children: e.title
170
+ }), /* @__PURE__ */ _("div", {
171
+ className: "flex items-center gap-2 text-sm text-muted-foreground",
172
+ children: [D(e.category), /* @__PURE__ */ g("span", { children: k(e.category) })]
173
+ })] })]
174
+ }), /* @__PURE__ */ g(f, {
175
+ className: E(e.difficulty),
176
+ children: A(e.difficulty)
177
+ })]
178
+ }),
179
+ /* @__PURE__ */ g("p", {
180
+ className: "line-clamp-3 text-sm text-muted-foreground",
181
+ children: e.description
182
+ }),
183
+ e.progress !== void 0 && /* @__PURE__ */ _("div", {
184
+ className: "space-y-2",
185
+ children: [/* @__PURE__ */ _("div", {
186
+ className: "flex justify-between text-sm",
187
+ children: [/* @__PURE__ */ g("span", { children: w("ecoimpacthub.challenges.progress.label", "Progress") }), /* @__PURE__ */ _("span", { children: [e.progress, "%"] })]
188
+ }), /* @__PURE__ */ g("div", {
189
+ className: "h-2 w-full rounded-full bg-muted",
190
+ children: /* @__PURE__ */ g("div", {
191
+ className: "h-2 rounded-full bg-primary transition-all",
192
+ style: { width: `${e.progress}%` }
193
+ })
194
+ })]
195
+ }),
196
+ /* @__PURE__ */ _("div", {
197
+ className: "flex items-center justify-between text-sm text-muted-foreground",
198
+ children: [/* @__PURE__ */ _("div", {
199
+ className: "flex items-center gap-4",
200
+ children: [/* @__PURE__ */ _("div", {
201
+ className: "flex items-center gap-1",
202
+ children: [/* @__PURE__ */ g(c, { className: "h-4 w-4" }), /* @__PURE__ */ g("span", { children: w("ecoimpacthub.challenges.card.points", "{{points}} pts", { points: e.points }) })]
203
+ }), /* @__PURE__ */ _("div", {
204
+ className: "flex items-center gap-1",
205
+ children: [/* @__PURE__ */ g(l, { className: "h-4 w-4" }), /* @__PURE__ */ g("span", { children: e.participants.toLocaleString() })]
206
+ })]
207
+ }), /* @__PURE__ */ _("div", {
208
+ className: "flex items-center gap-1",
209
+ children: [/* @__PURE__ */ g(i, { className: "h-4 w-4" }), /* @__PURE__ */ g("span", { children: new Date(e.endDate).toLocaleDateString() })]
210
+ })]
211
+ }),
212
+ /* @__PURE__ */ g(p, {
213
+ className: "w-full",
214
+ variant: e.status === "active" ? "default" : "outline",
215
+ children: j(e.status)
216
+ })
217
+ ]
218
+ })
219
+ }, e.id))
220
+ }),
221
+ T.length === 0 && /* @__PURE__ */ _("div", {
222
+ className: "py-12 text-center",
223
+ children: [
224
+ /* @__PURE__ */ g(c, { className: "mx-auto mb-4 h-16 w-16 text-muted-foreground" }),
225
+ /* @__PURE__ */ g("h3", {
226
+ className: "mb-2 text-xl font-semibold",
227
+ children: w("ecoimpacthub.challenges.empty.title", "No challenges found")
228
+ }),
229
+ /* @__PURE__ */ g("p", {
230
+ className: "text-muted-foreground",
231
+ children: w("ecoimpacthub.challenges.empty.description", "Try adjusting your filters or check back later for new challenges!")
232
+ })
233
+ ]
234
+ })
235
+ ]
236
+ })
237
+ });
238
+ }
239
+ //#endregion
240
+ export { v as ChallengesPage };
241
+
242
+ //# sourceMappingURL=ChallengesPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChallengesPage.js","names":[],"sources":["../../../src/ecoimpacthub/pages/ChallengesPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Badge, Button, Card, CardContent } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Trophy, Users, Calendar, Target, Award, Zap, Star, Leaf } from 'lucide-react';\nimport { useEcoImpactHubStore } from '../store/ecoimpacthubStore';\nimport { tWithFallback } from '../utils/i18n';\n\nexport function ChallengesPage() {\n const { t } = useI18n();\n const { challenges } = useEcoImpactHubStore();\n const [activeTab, setActiveTab] = useState<'active' | 'completed' | 'upcoming'>('active');\n const [selectedCategory, setSelectedCategory] = useState<\n 'all' | 'individual' | 'community' | 'global'\n >('all');\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n const filteredChallenges = challenges.filter(\n (challenge) =>\n challenge.status === activeTab &&\n (selectedCategory === 'all' || challenge.category === selectedCategory)\n );\n\n const getDifficultyColor = (difficulty: string) => {\n switch (difficulty) {\n case 'easy':\n return 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300';\n case 'medium':\n return 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300';\n case 'hard':\n return 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300';\n default:\n return 'bg-muted text-muted-foreground';\n }\n };\n\n const getCategoryIcon = (category: string) => {\n switch (category) {\n case 'individual':\n return <Target className=\"h-4 w-4\" />;\n case 'community':\n return <Users className=\"h-4 w-4\" />;\n case 'global':\n return <Award className=\"h-4 w-4\" />;\n default:\n return <Star className=\"h-4 w-4\" />;\n }\n };\n\n const getTabLabel = (tab: 'active' | 'completed' | 'upcoming') => {\n switch (tab) {\n case 'active':\n return translate('ecoimpacthub.challenges.tabs.active', 'Active');\n case 'completed':\n return translate('ecoimpacthub.challenges.tabs.completed', 'Completed');\n case 'upcoming':\n return translate('ecoimpacthub.challenges.tabs.upcoming', 'Upcoming');\n default:\n return tab;\n }\n };\n\n const getCategoryLabel = (category: 'all' | 'individual' | 'community' | 'global') => {\n switch (category) {\n case 'all':\n return translate('ecoimpacthub.challenges.categories.all', 'All');\n case 'individual':\n return translate('ecoimpacthub.challenges.categories.individual', 'Individual');\n case 'community':\n return translate('ecoimpacthub.challenges.categories.community', 'Community');\n case 'global':\n return translate('ecoimpacthub.challenges.categories.global', 'Global');\n default:\n return category;\n }\n };\n\n const getDifficultyLabel = (difficulty: string) => {\n switch (difficulty) {\n case 'easy':\n return translate('ecoimpacthub.challenges.difficulty.easy', 'Easy');\n case 'medium':\n return translate('ecoimpacthub.challenges.difficulty.medium', 'Medium');\n case 'hard':\n return translate('ecoimpacthub.challenges.difficulty.hard', 'Hard');\n default:\n return difficulty;\n }\n };\n\n const getActionLabel = (status: 'active' | 'completed' | 'upcoming') => {\n switch (status) {\n case 'active':\n return translate('ecoimpacthub.challenges.actions.joinChallenge', 'Join Challenge');\n case 'completed':\n return translate('ecoimpacthub.challenges.actions.viewResults', 'View Results');\n case 'upcoming':\n return translate('ecoimpacthub.challenges.actions.setReminder', 'Set Reminder');\n default:\n return status;\n }\n };\n\n const stats = [\n {\n label: translate('ecoimpacthub.challenges.stats.totalPoints.label', 'Total Points'),\n value: '2,450',\n sub: translate('ecoimpacthub.challenges.stats.totalPoints.sub', '+180 this week'),\n icon: Trophy,\n color: 'text-primary',\n },\n {\n label: translate('ecoimpacthub.challenges.stats.activeStreak.label', 'Active Streak'),\n value: '12',\n sub: translate('ecoimpacthub.challenges.stats.activeStreak.sub', 'days in a row'),\n icon: Zap,\n color: 'text-green-600',\n },\n {\n label: translate('ecoimpacthub.challenges.stats.completed.label', 'Completed'),\n value: '8',\n sub: translate('ecoimpacthub.challenges.stats.completed.sub', 'challenges this month'),\n icon: Award,\n color: 'text-blue-600',\n },\n {\n label: translate('ecoimpacthub.challenges.stats.impactScore.label', 'Impact Score'),\n value: '95',\n sub: translate('ecoimpacthub.challenges.stats.impactScore.sub', 'environmental rating'),\n icon: Leaf,\n color: 'text-emerald-600',\n },\n ];\n\n return (\n <div className=\"min-h-screen\">\n <div className=\"mx-auto max-w-7xl space-y-8 px-4 py-8 sm:px-6 lg:px-8\">\n <div className=\"space-y-4 text-center\">\n <h1 className=\"text-4xl font-bold\">\n {translate('ecoimpacthub.challenges.title', 'Environmental Challenges')}\n </h1>\n <p className=\"mx-auto max-w-3xl text-xl text-muted-foreground\">\n {translate(\n 'ecoimpacthub.challenges.subtitle',\n 'Join thousands of eco-warriors in meaningful environmental actions. Complete challenges, earn points, and make a real impact on our planet.'\n )}\n </p>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-4\">\n {stats.map((stat) => {\n const Icon = stat.icon;\n return (\n <Card key={stat.label}>\n <CardContent className=\"space-y-2 p-6\">\n <div className={`flex items-center gap-2 ${stat.color}`}>\n <Icon className=\"h-5 w-5\" />\n <span className=\"font-semibold\">{stat.label}</span>\n </div>\n <div className=\"text-3xl font-bold\">{stat.value}</div>\n <div className=\"text-sm text-muted-foreground\">{stat.sub}</div>\n </CardContent>\n </Card>\n );\n })}\n </div>\n\n <div className=\"flex flex-col items-center justify-between gap-4 sm:flex-row\">\n <div className=\"flex gap-2\">\n {(['active', 'completed', 'upcoming'] as const).map((tab) => (\n <Button\n key={tab}\n variant={activeTab === tab ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setActiveTab(tab)}\n >\n {getTabLabel(tab)}\n </Button>\n ))}\n </div>\n <div className=\"flex gap-2\">\n {(['all', 'individual', 'community', 'global'] as const).map((category) => (\n <Button\n key={category}\n variant={selectedCategory === category ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setSelectedCategory(category)}\n >\n {getCategoryLabel(category)}\n </Button>\n ))}\n </div>\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {filteredChallenges.map((challenge) => (\n <Card key={challenge.id} className=\"overflow-hidden transition-shadow hover:shadow-lg\">\n <CardContent className=\"space-y-4 p-6\">\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"text-2xl\">{challenge.icon}</div>\n <div>\n <h3 className=\"text-lg font-semibold\">{challenge.title}</h3>\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n {getCategoryIcon(challenge.category)}\n <span>{getCategoryLabel(challenge.category)}</span>\n </div>\n </div>\n </div>\n <Badge className={getDifficultyColor(challenge.difficulty)}>\n {getDifficultyLabel(challenge.difficulty)}\n </Badge>\n </div>\n\n <p className=\"line-clamp-3 text-sm text-muted-foreground\">\n {challenge.description}\n </p>\n\n {challenge.progress !== undefined && (\n <div className=\"space-y-2\">\n <div className=\"flex justify-between text-sm\">\n <span>{translate('ecoimpacthub.challenges.progress.label', 'Progress')}</span>\n <span>{challenge.progress}%</span>\n </div>\n <div className=\"h-2 w-full rounded-full bg-muted\">\n <div\n className=\"h-2 rounded-full bg-primary transition-all\"\n style={{ width: `${challenge.progress}%` }}\n />\n </div>\n </div>\n )}\n\n <div className=\"flex items-center justify-between text-sm text-muted-foreground\">\n <div className=\"flex items-center gap-4\">\n <div className=\"flex items-center gap-1\">\n <Trophy className=\"h-4 w-4\" />\n <span>\n {translate('ecoimpacthub.challenges.card.points', '{{points}} pts', {\n points: challenge.points,\n })}\n </span>\n </div>\n <div className=\"flex items-center gap-1\">\n <Users className=\"h-4 w-4\" />\n <span>{challenge.participants.toLocaleString()}</span>\n </div>\n </div>\n <div className=\"flex items-center gap-1\">\n <Calendar className=\"h-4 w-4\" />\n <span>{new Date(challenge.endDate).toLocaleDateString()}</span>\n </div>\n </div>\n\n <Button\n className=\"w-full\"\n variant={challenge.status === 'active' ? 'default' : 'outline'}\n >\n {getActionLabel(challenge.status)}\n </Button>\n </CardContent>\n </Card>\n ))}\n </div>\n\n {filteredChallenges.length === 0 && (\n <div className=\"py-12 text-center\">\n <Trophy className=\"mx-auto mb-4 h-16 w-16 text-muted-foreground\" />\n <h3 className=\"mb-2 text-xl font-semibold\">\n {translate('ecoimpacthub.challenges.empty.title', 'No challenges found')}\n </h3>\n <p className=\"text-muted-foreground\">\n {translate(\n 'ecoimpacthub.challenges.empty.description',\n 'Try adjusting your filters or check back later for new challenges!'\n )}\n </p>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function CitizenSciencePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=CitizenSciencePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CitizenSciencePage.d.ts","sourceRoot":"","sources":["../../../src/ecoimpacthub/pages/CitizenSciencePage.tsx"],"names":[],"mappings":"AAkCA,wBAAgB,kBAAkB,4CAkfjC"}