From 439b62b8b9ea80f5fcc79f591bc8b57011ce5ff3 Mon Sep 17 00:00:00 2001 From: Njeriiii Date: Thu, 20 Feb 2025 12:52:23 -0800 Subject: [PATCH 01/22] about-us page --- Frontend/src/App.js | 2 + Frontend/src/components/Header.js | 2 +- Frontend/src/pages/AboutUsPage.js | 139 ++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 Frontend/src/pages/AboutUsPage.js diff --git a/Frontend/src/App.js b/Frontend/src/App.js index 8bca853..113b5a7 100644 --- a/Frontend/src/App.js +++ b/Frontend/src/App.js @@ -19,6 +19,7 @@ import EstablishmentGuide from './pages/EstablishmentGuide'; import EditProfile from './pages/EditProfilePage'; import ProfileImages from "./components/OrgProfileFormComponents/ProfileImages"; import ProposalBuilderPage from './pages/ProposalBuilderPage'; +import AboutUsPage from './pages/AboutUsPage'; function App() { @@ -38,6 +39,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/Frontend/src/components/Header.js b/Frontend/src/components/Header.js index d36b6fc..56f623a 100644 --- a/Frontend/src/components/Header.js +++ b/Frontend/src/components/Header.js @@ -17,7 +17,7 @@ const navigation = [ { name: "Establishment Guide", href: "/establishment-guide" }, { name: "Proposal Builder", href: "/proposal-builder" }, { name: "Volunteer", href: "/volunteer" }, - { name: "About", href: "/about" }, + { name: "About Us", href: "/about-us" }, ]; // Logo component diff --git a/Frontend/src/pages/AboutUsPage.js b/Frontend/src/pages/AboutUsPage.js new file mode 100644 index 0000000..fdf48b4 --- /dev/null +++ b/Frontend/src/pages/AboutUsPage.js @@ -0,0 +1,139 @@ +import React from "react"; +import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card"; +import { + Users, + HandHeart, + HomeIcon, + Trees} from "lucide-react"; +import Header from "../components/Header"; + +export default function AboutUsPage() { + const impactAreas = [ + { + icon: , + area: "Community Support", + description: "Grassroots initiatives led by local communities", + }, + { + icon: , + area: "Local Development", + description: "Infrastructure and capacity building projects", + }, + { + icon: , + area: "Social Services", + description: "Health, education, and social welfare programs", + }, + { + icon: , + area: "Sustainable Growth", + description: "Environmental and economic sustainability initiatives", + }, + ]; + + return ( +
+
+ + {/* Main Content Container */} +
+ {/* Hero Section */} +
+
+

+ Empowering Kenyan Communities Through Connection +

+

+ Building digital bridges to strengthen Community Based + Organizations across Kenya +

+
+
+ + {/* CBO Definition Section */} +
+ + + + What is a Community-Based Organization (CBO)? + + + +

+ A Community-Based Organization (CBO) is a nonprofit group + formed and led by local community members to address specific social and economic needs. + CBOs play a key role in grassroots development, providing essential support and + services where they are needed most. +

+

+ These organizations operate at the community level, focusing on sustainable solutions + and meaningful impact. By working closely with the people they serve, CBOs help drive + long-term progress and positive change. +

+
+
+
+ + + {/* Mission Statement */} +
+

Our Mission

+

+ To empower Kenyan CBOs by providing a collaborative platform that + breaks down barriers between organizations, facilitates resource + sharing, and amplifies their collective impact. We believe that when + local communities connect and work together, they can create + sustainable, lasting change from the ground up. +

+
+ + {/* Focus Areas */} +
+

+ Supporting Key Community Initiatives +

+
+ {impactAreas.map((area, index) => ( + + +
+ {area.icon} +
+
+

+ {area.area} +

+

{area.description}

+
+
+
+ ))} +
+
+ + {/* Vision Section */} +
+ + + + Our Vision for Kenya + + + +

+ We envision a Kenya where every community has the tools and + connections they need to thrive. By strengthening the network of + CBOs, we're helping build a future where local solutions drive + national progress, and where every community can learn from and + support each other's success. +

+
+
+
+
+
+ ); +}; \ No newline at end of file From 541a9b9210906704ffd83ae060d933aa7fd8f83d Mon Sep 17 00:00:00 2001 From: Njeriiii Date: Thu, 20 Feb 2025 13:13:11 -0800 Subject: [PATCH 02/22] about us translations --- .../components/utils/translationConstants.js | 4 +- Frontend/src/contexts/TranslationProvider.js | 1 + Frontend/src/pages/AboutUsPage.js | 93 +++++++++++-------- 3 files changed, 56 insertions(+), 42 deletions(-) diff --git a/Frontend/src/components/utils/translationConstants.js b/Frontend/src/components/utils/translationConstants.js index aea7d62..cd70424 100644 --- a/Frontend/src/components/utils/translationConstants.js +++ b/Frontend/src/components/utils/translationConstants.js @@ -7,7 +7,7 @@ export const STATIC_PHRASES = { 'Find GOs': 'Find GOs', 'Establishment Guide': 'Establishment Guide', 'Volunteer': 'Volunteer', - 'About': 'About', + 'About Us': 'About Us', 'Welcome!': 'Welcome!', 'Log out': 'Log out', @@ -107,7 +107,7 @@ export const STATIC_PHRASES = { 'Find GOs': 'Tafuta Mashirika', 'Establishment Guide': 'Mwongozo wa Uanzishaji', 'Volunteer': 'Kujitolea', - 'About': 'Kuhusu', + 'About Us': 'Kutuhusu', 'Welcome!': 'Karibu!', 'Log out': 'Toka', 'View Profile': 'Tazama Profaili', diff --git a/Frontend/src/contexts/TranslationProvider.js b/Frontend/src/contexts/TranslationProvider.js index d8c470f..dbb7405 100644 --- a/Frontend/src/contexts/TranslationProvider.js +++ b/Frontend/src/contexts/TranslationProvider.js @@ -36,6 +36,7 @@ export function DynamicTranslate({ children }) { // Skip translation for non-string content if (!children || typeof children !== 'string') { + console.warn('DynamicTranslate component requires a string child', children); return; } diff --git a/Frontend/src/pages/AboutUsPage.js b/Frontend/src/pages/AboutUsPage.js index fdf48b4..488b675 100644 --- a/Frontend/src/pages/AboutUsPage.js +++ b/Frontend/src/pages/AboutUsPage.js @@ -6,28 +6,29 @@ import { HomeIcon, Trees} from "lucide-react"; import Header from "../components/Header"; +import { DynamicTranslate } from "../contexts/TranslationProvider"; export default function AboutUsPage() { const impactAreas = [ { icon: , - area: "Community Support", - description: "Grassroots initiatives led by local communities", + area: Community Support, + description:Grassroots initiatives led by local communities, }, { icon: , - area: "Local Development", - description: "Infrastructure and capacity building projects", + area:Local Development, + description:Infrastructure and capacity building projects, }, { icon: , - area: "Social Services", - description: "Health, education, and social welfare programs", + area:Social Services, + description:Health, education, and social welfare programs, }, { icon: , - area: "Sustainable Growth", - description: "Environmental and economic sustainability initiatives", + area:Sustainable Growth, + description:Environmental and economic sustainability initiatives, }, ]; @@ -41,11 +42,13 @@ export default function AboutUsPage() {

- Empowering Kenyan Communities Through Connection + Empowering Kenyan Communities Through Connection

- Building digital bridges to strengthen Community Based - Organizations across Kenya + + Building digital bridges to strengthen Community Based + Organizations across Kenya +

@@ -54,22 +57,26 @@ export default function AboutUsPage() {
- - What is a Community-Based Organization (CBO)? - + + What is a Community-Based Organization (CBO)? + -

- A Community-Based Organization (CBO) is a nonprofit group - formed and led by local community members to address specific social and economic needs. - CBOs play a key role in grassroots development, providing essential support and - services where they are needed most. -

-

- These organizations operate at the community level, focusing on sustainable solutions - and meaningful impact. By working closely with the people they serve, CBOs help drive - long-term progress and positive change. -

+

+ + A Community-Based Organization (CBO) is a non-profit group + formed and led by local community members to address specific social and economic needs. + CBOs play a key role in grassroots development, providing essential support and + services where they are needed most. + +

+

+ + These organizations operate at the community level, focusing on sustainable solutions + and meaningful impact. By working closely with the people they serve, CBOs help drive + long-term progress and positive change. + +

@@ -77,20 +84,24 @@ export default function AboutUsPage() { {/* Mission Statement */}
-

Our Mission

+

+ Our Mission +

- To empower Kenyan CBOs by providing a collaborative platform that - breaks down barriers between organizations, facilitates resource - sharing, and amplifies their collective impact. We believe that when - local communities connect and work together, they can create - sustainable, lasting change from the ground up. + + To empower Kenyan CBOs by providing a collaborative platform that + breaks down barriers between organizations, facilitates resource + sharing, and amplifies their collective impact. We believe that when + local communities connect and work together, they can create + sustainable, lasting change from the ground up. +

{/* Focus Areas */}

- Supporting Key Community Initiatives + Supporting Key Community Initiatives

{impactAreas.map((area, index) => ( @@ -118,17 +129,19 @@ export default function AboutUsPage() {
- - Our Vision for Kenya - + + Our Vision for Kenya +

- We envision a Kenya where every community has the tools and - connections they need to thrive. By strengthening the network of - CBOs, we're helping build a future where local solutions drive - national progress, and where every community can learn from and - support each other's success. + + We envision a Kenya where every community has the tools and + connections they need to thrive. By strengthening the network of + CBOs, we're helping build a future where local solutions drive + national progress, and where every community can learn from and + support each other's success. +

From f8e0340e3dc5e5b4b59456d30f8775ef7731a7a8 Mon Sep 17 00:00:00 2001 From: Njeriiii Date: Thu, 20 Feb 2025 14:40:15 -0800 Subject: [PATCH 03/22] home page implementation --- Frontend/src/App.js | 3 +- Frontend/src/components/ui/button.js | 113 +++++++++++++++ Frontend/src/pages/HomePage.js | 196 +++++++++++++++++++++++++++ 3 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 Frontend/src/components/ui/button.js create mode 100644 Frontend/src/pages/HomePage.js diff --git a/Frontend/src/App.js b/Frontend/src/App.js index 113b5a7..a39a778 100644 --- a/Frontend/src/App.js +++ b/Frontend/src/App.js @@ -10,6 +10,7 @@ import OnboardingForm from './pages/OnboardingForm'; import OrgProfileForm from './pages/OrgProfileForm'; import OrgProfile from './pages/OrgProfile'; import DisplayPage from './pages/DisplayPage'; +import HomePage from './pages/HomePage'; import SignupPage from './pages/SignupPage'; import LoginPage from './pages/LoginPage'; import VolunteerForm from './pages/VolunteerForm'; @@ -38,7 +39,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/Frontend/src/components/ui/button.js b/Frontend/src/components/ui/button.js new file mode 100644 index 0000000..fdcafef --- /dev/null +++ b/Frontend/src/components/ui/button.js @@ -0,0 +1,113 @@ +// components/ui/button.jsx +import { Link } from 'react-router-dom'; + +export function Button({ + className = '', + variant = 'default', + size = 'default', + isLoading = false, + to = null, // for React Router navigation + href = null, // for external links + disabled = false, + children, + ...props +}) { + const baseStyles = 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-teal-500 disabled:pointer-events-none disabled:opacity-50'; + + const variants = { + default: 'bg-teal-600 text-white hover:bg-teal-700', + destructive: 'bg-red-500 text-white hover:bg-red-600', + outline: 'border border-gray-200 bg-white hover:bg-gray-50 text-gray-900', + secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200', + ghost: 'hover:bg-gray-100 text-gray-600 hover:text-gray-900', + link: 'text-teal-600 hover:text-teal-700 p-0 h-auto underline-offset-4 hover:underline bg-transparent', + info: "bg-teal-950/20 text-white text-xl hover:bg-teal-950/20 cursor-default" // New variant + + }; + + const sizes = { + default: 'h-9 px-4 py-2 text-sm', + sm: 'h-8 px-3 text-xs', + lg: 'h-10 px-8 text-base', + icon: 'h-9 w-9' + }; + + const variantStyles = variants[variant] || variants.default; + const sizeStyles = variant === 'link' ? '' : (sizes[size] || sizes.default); + const loadingStyles = isLoading ? 'cursor-not-allowed' : ''; + const combinedClassName = `${baseStyles} ${variantStyles} ${sizeStyles} ${loadingStyles} ${className}`; + + // If 'to' prop is provided, use React Router's Link + if (to) { + return ( + + {children} + + ); + } + + // If 'href' prop is provided, use regular anchor tag + if (href) { + return ( + + {children} + + ); + } + + // Default to button + return ( + + ); +} + +export function IconButton({ + className = '', + variant = 'default', + children, + ...props +}) { + return ( + + ); +} \ No newline at end of file diff --git a/Frontend/src/pages/HomePage.js b/Frontend/src/pages/HomePage.js new file mode 100644 index 0000000..5430537 --- /dev/null +++ b/Frontend/src/pages/HomePage.js @@ -0,0 +1,196 @@ +import React, { useEffect, useState } from 'react'; +import { useApi } from '../contexts/ApiProvider'; +import OrgDisplayCard from '../components/OrgDisplayCard'; +import Header from '../components/Header'; +import KenyaIcon from '../components/icons/KenyaIcon'; +import { DynamicTranslate } from '../contexts/TranslationProvider'; +import { Loader2, Users, Lightbulb, ArrowRight, Search } from "lucide-react"; +import { Button } from "../components/ui/button"; +import { Card, CardContent } from "../components/ui/card"; + +export default function HomePage() { + const apiClient = useApi(); + const [orgsData, setOrgsData] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchOrgs = async () => { + try { + const response = await apiClient.get("/main/orgs"); + if (response.ok) { + setOrgsData(response.body); + } + } catch (error) { + console.error("Error fetching data: ", error); + } finally { + setLoading(false); + } + }; + + fetchOrgs(); + }, [apiClient]); + + const renderFeaturedOrgs = (orgs) => { + if (!orgs?.length) return null; + + // Only show first 2 organizations + const featuredOrgs = orgs.slice(0, 2); + + return ( +
+ {featuredOrgs.map((org) => ( +
+ +
+ ))} +
+ ); + }; + + return ( +
+
+ +
+ {/* Hero Section */} +
+
+
+
+ +
+

+ Uniting Communities Across Kenya +

+

+ Connect with community-based organizations making real change happen! +

+
+ + +
+
+
+
+ + {/* Quick Links Section */} +
+
+ + + +

+ Founder's Corner +

+

+ Resources, guides, and support for CBO founders and leaders +

+ +
+
+ + + + +

+ Volunteer Platform +

+

+ Make a difference by volunteering with local organizations +

+ +
+
+ + + + +

+ Find Organizations +

+

+ Discover and connect with CBOs making an impact +

+ +
+
+
+
+ + {/* Featured Organizations */} +
+
+

+ Featured Organizations +

+ +
+ + {loading ? ( +
+
+
+ +

+ Loading organizations... +

+
+
+
+ ) : ( +
+ {renderFeaturedOrgs(orgsData)} +
+ )} +
+ + {/* Call to Action */} +
+
+
+

+ Ready to Make an Impact? +

+

+ + Whether you're a CBO founder, volunteer, or supporter, + join our platform to connect and create positive change. + +

+ +
+
+
+
+
+ ); +} \ No newline at end of file From c00ab39a4302ea2e73da12c752023c67ab1e6f52 Mon Sep 17 00:00:00 2001 From: Njeriiii Date: Thu, 20 Feb 2025 14:47:47 -0800 Subject: [PATCH 04/22] admins only for proposal builder --- Frontend/src/pages/ProposalBuilderPage.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Frontend/src/pages/ProposalBuilderPage.js b/Frontend/src/pages/ProposalBuilderPage.js index d77cd06..2b487ed 100644 --- a/Frontend/src/pages/ProposalBuilderPage.js +++ b/Frontend/src/pages/ProposalBuilderPage.js @@ -37,6 +37,7 @@ export default function ProposalBuilder() { const [activeSection, setActiveSection] = useState('organizationInfo'); const [showTip, setShowTip] = useState(true); const { user } = useAuth(); + console.log(user); const userId = user ? user.id : null; const [completedSections, setCompletedSections] = useState(() => { // Initialize from localStorage @@ -147,10 +148,10 @@ export default function ProposalBuilder() {
- {!userId ? ( + {!(userId && user && user.is_admin) ? (

- Please log in to access organization information. + Please log in to access your organization's information. This tool is only available to registered CBO founders.

) : ( From 8dfa1732212b4ffab3dca8ca40e6dc0d070bf4b2 Mon Sep 17 00:00:00 2001 From: Njeriiii Date: Thu, 20 Feb 2025 14:59:49 -0800 Subject: [PATCH 05/22] founder's resource page --- Frontend/src/App.js | 2 + Frontend/src/components/Header.js | 5 +- Frontend/src/components/ui/card.js | 4 ++ Frontend/src/pages/FoundersResourcesPage.js | 78 +++++++++++++++++++++ 4 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 Frontend/src/pages/FoundersResourcesPage.js diff --git a/Frontend/src/App.js b/Frontend/src/App.js index a39a778..16eb427 100644 --- a/Frontend/src/App.js +++ b/Frontend/src/App.js @@ -21,6 +21,7 @@ import EditProfile from './pages/EditProfilePage'; import ProfileImages from "./components/OrgProfileFormComponents/ProfileImages"; import ProposalBuilderPage from './pages/ProposalBuilderPage'; import AboutUsPage from './pages/AboutUsPage'; +import FoundersResourcesPage from './pages/FoundersResourcesPage'; function App() { @@ -41,6 +42,7 @@ function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/Frontend/src/components/Header.js b/Frontend/src/components/Header.js index 56f623a..db5f8f7 100644 --- a/Frontend/src/components/Header.js +++ b/Frontend/src/components/Header.js @@ -13,9 +13,8 @@ import { Translate, LanguageSwitch } from '../contexts/TranslationProvider'; // Navigation links const navigation = [ { name: "Home", href: "/" }, - { name: "Find GOs", href: "/find-gos" }, - { name: "Establishment Guide", href: "/establishment-guide" }, - { name: "Proposal Builder", href: "/proposal-builder" }, + { name: "Find CBOs", href: "/find-gos" }, + { name: "Founder Resources", href: "/founder-resources" }, { name: "Volunteer", href: "/volunteer" }, { name: "About Us", href: "/about-us" }, ]; diff --git a/Frontend/src/components/ui/card.js b/Frontend/src/components/ui/card.js index 5e72e91..71a2075 100644 --- a/Frontend/src/components/ui/card.js +++ b/Frontend/src/components/ui/card.js @@ -13,3 +13,7 @@ export function CardTitle({ className, children }) { export function CardContent({ className, children }) { return
{children}
; } + +export function CardDescription({ className, children }) { + return

{children}

; +} diff --git a/Frontend/src/pages/FoundersResourcesPage.js b/Frontend/src/pages/FoundersResourcesPage.js new file mode 100644 index 0000000..94197a5 --- /dev/null +++ b/Frontend/src/pages/FoundersResourcesPage.js @@ -0,0 +1,78 @@ +import React from "react"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, +} from "../components/ui/card"; +import { BookOpen, FileText, ArrowRight } from "lucide-react"; +import Header from "../components/Header"; + +export default function FoundersResourcesPage () { + // Define resources with their details + const resources = [ + { + name: "Establishment Guide", + description: + "Step-by-step guidance for establishing and registering your non-profit organization. Learn about legal requirements, documentation, and best practices.", + href: "/establishment-guide", + icon: BookOpen, + }, + { + name: "Proposal Builder", + description: + "Interactive tool to help you create compelling grant proposals. Includes templates, examples, and tips for successful fundraising.", + href: "/proposal-builder", + icon: FileText, + }, + ]; + + return ( +
+
+ {/* Header Section */} +
+

Founder's Resources

+

+ Access our comprehensive collection of tools and guides designed to + help you establish and grow your non-profit organization. +

+
+ + {/* Resources Grid */} +
+ {resources.map((resource) => { + const Icon = resource.icon; + return ( + + + +
+
+ +
+ {resource.name} +
+
+ + + {resource.description} + +
+ Learn More + +
+
+
+
+ ); + })} +
+
+ ); +}; \ No newline at end of file From 2c065dd6433eaae67d63bb0ff32dc2c5af5fb3f6 Mon Sep 17 00:00:00 2001 From: Njeriiii Date: Thu, 20 Feb 2025 15:22:51 -0800 Subject: [PATCH 06/22] improve find CBO page --- Frontend/src/components/KeyWordSearch.js | 14 +++++++------- Frontend/src/pages/DisplayPage.js | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Frontend/src/components/KeyWordSearch.js b/Frontend/src/components/KeyWordSearch.js index c1c02d1..97c6eee 100644 --- a/Frontend/src/components/KeyWordSearch.js +++ b/Frontend/src/components/KeyWordSearch.js @@ -198,11 +198,11 @@ export default function KeyWordSearch({ orgData = [], onSearchResults }) { }; return ( -
+
{/* Header */}
-

+

Find Organizations

{searchResults.length > 0 && ( @@ -241,13 +241,13 @@ export default function KeyWordSearch({ orgData = [], onSearchResults }) {
@@ -259,7 +259,7 @@ export default function KeyWordSearch({ orgData = [], onSearchResults }) { >
-