├── README.md ├── .bolt ├── config.json └── prompt ├── postcss.config.js ├── src ├── index.css ├── vite-env.d.ts ├── main.tsx ├── pages │ ├── Profile.tsx │ ├── Login.tsx │ ├── Signup.tsx │ ├── Notices.tsx │ ├── GovernmentSchemes.tsx │ ├── CommunityIssues.tsx │ ├── Home.tsx │ └── Index.tsx ├── types.ts ├── types │ └── index.ts ├── components │ ├── Input.tsx │ ├── Profile │ │ ├── ProfileHeader.tsx │ │ ├── PersonalInfo.tsx │ │ └── EditProfileModel.tsx │ ├── AuthLayout.tsx │ ├── Navbar.tsx │ ├── Button.tsx │ ├── Map.tsx │ ├── IssueCategoryModal.tsx │ ├── DashboardLayout.tsx │ ├── reportIssuemodel.tsx │ └── Footer.tsx └── App.tsx ├── tsconfig.json ├── tailwind.config.js ├── CoFix-backend ├── README.md ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── cofix │ │ │ │ └── cofixBackend │ │ │ │ ├── Models │ │ │ │ ├── BenefitTypes.java │ │ │ │ ├── Location.java │ │ │ │ ├── PostPk.java │ │ │ │ ├── MyReview.java │ │ │ │ ├── MyUser.java │ │ │ │ └── MyPost.java │ │ │ │ ├── Repos │ │ │ │ ├── ReviewsRepo.java │ │ │ │ ├── UsersRepo.java │ │ │ │ └── PostsRepo.java │ │ │ │ ├── CofixBackendApplication.java │ │ │ │ ├── Configurations │ │ │ │ ├── AppConfig.java │ │ │ │ ├── WebConfig.java.bkp │ │ │ │ ├── HikariCPConfig.java │ │ │ │ ├── SecurityConfig.java.bkp │ │ │ │ └── DynamicPhysicalNamingStrategy.java │ │ │ │ ├── Services │ │ │ │ ├── AuthService.java │ │ │ │ └── CofixService.java │ │ │ │ └── Controllers │ │ │ │ └── CofixLoginController.java │ │ └── resources │ │ │ └── application.properties │ └── test │ │ └── java │ │ └── com │ │ └── cofix │ │ └── cofixBackend │ │ └── CofixBackendApplicationTests.java ├── .gitignore ├── artifacts │ ├── application.properties │ └── create_db_script.sql ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── pom.xml ├── mvnw.cmd └── mvnw ├── vite.config.ts ├── .gitignore ├── index.html ├── tsconfig.node.json ├── tsconfig.app.json ├── eslint.config.js ├── package.json └── LICENSE /README.md: -------------------------------------------------------------------------------- 1 | # Communitfx 2 | 3 | AKA cofix 4 | new 5 | -------------------------------------------------------------------------------- /.bolt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "template": "bolt-vite-react-ts" 3 | } 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .leaflet-container { 6 | width: 100%; 7 | height: 100%; 8 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module 'leaflet/dist/images/marker-icon-2x.png'; 4 | declare module 'leaflet/dist/images/marker-icon.png'; 5 | declare module 'leaflet/dist/images/marker-shadow.png'; -------------------------------------------------------------------------------- /CoFix-backend/README.md: -------------------------------------------------------------------------------- 1 | # Community FX Backend 2 | * Requirements : Java-17, Spring boot-3.0, Postgres SQL 3 | 4 | ## Version Log: 5 | 6 | ## cofixBackend-0.0.1-SNAPSHOT 7 | * User registration, Sign-in 8 | 9 | 10 | ## cofixBackend-0.0.2-SNAPSHOT 11 | * -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Models/BenefitTypes.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Models; 2 | 3 | import lombok.ToString; 4 | 5 | @ToString 6 | public enum BenefitTypes { 7 | COMMUNITY_ISSUE, 8 | GOVERNMENT_SCHEME 9 | } 10 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | optimizeDeps: { 8 | exclude: ['lucide-react'], 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App.tsx'; 4 | import './index.css'; 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Repos/ReviewsRepo.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Repos; 2 | 3 | import com.cofix.cofixBackend.Models.MyReview; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface ReviewsRepo extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /CoFix-backend/src/test/java/com/cofix/cofixBackend/CofixBackendApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class CofixBackendApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Models/Location.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Models; 2 | 3 | 4 | import jakarta.persistence.Embeddable; 5 | import lombok.*; 6 | 7 | @Embeddable 8 | @ToString 9 | @Getter 10 | @Setter 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | public class Location { 14 | private Double lat; 15 | private Double lng; 16 | } 17 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/CofixBackendApplication.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class CofixBackendApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(CofixBackendApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Models/PostPk.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Models; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.EqualsAndHashCode; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @NoArgsConstructor 10 | @AllArgsConstructor 11 | @EqualsAndHashCode 12 | public class PostPk implements Serializable { 13 | private String email; 14 | private Long postId; 15 | } 16 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Repos/UsersRepo.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Repos; 2 | 3 | import com.cofix.cofixBackend.Models.MyUser; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | import java.util.List; 8 | 9 | @Repository 10 | public interface UsersRepo extends JpaRepository { 11 | MyUser findByEmail(String email); 12 | } 13 | -------------------------------------------------------------------------------- /src/pages/Profile.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ProfileHeader from '../components/Profile/ProfileHeader'; 3 | import PersonalInfo from '../components/Profile/PersonalInfo'; 4 | 5 | export default function Profile() { 6 | return ( 7 |
8 | 9 | 10 | {/* Profile Info */} 11 |
12 | 13 |
14 |
15 | ); 16 | } -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Issue { 2 | id: string; 3 | title: string; 4 | description: string; 5 | type: 'community' | 'government'; 6 | status: 'pending' | 'solved'; 7 | urgency: 'low' | 'medium' | 'high'; 8 | location: { 9 | lat: number; 10 | lng: number; 11 | }; 12 | createdAt: Date; 13 | updatedAt: Date; 14 | userId: string; 15 | photo?: string; 16 | category: string; 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface Issue { 2 | id: string; 3 | title: string; 4 | description: string; 5 | type: 'community' | 'government'; 6 | status: 'pending' | 'solved'; 7 | urgency: 'low' | 'medium' | 'high'; 8 | location: { 9 | lat: number; 10 | lng: number; 11 | }; 12 | imageUrl?: string; 13 | createdAt: Date; 14 | updatedAt: Date; 15 | userId: string; 16 | } 17 | 18 | export interface User { 19 | id: string; 20 | fullName: string; 21 | email: string; 22 | role: 'user' | 'admin'; 23 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Communitifx - Community Issue Reporting Platform 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /CoFix-backend/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /.bolt/prompt: -------------------------------------------------------------------------------- 1 | For all designs I ask you to make, have them be beautiful, not cookie cutter. Make webpages that are fully featured and worthy for production. 2 | 3 | By default, this template supports JSX syntax with Tailwind CSS classes, React hooks, and Lucide React for icons. Do not install other packages for UI themes, icons, etc unless absolutely necessary or I request them. 4 | 5 | Use icons from lucide-react for logos. 6 | 7 | Use stock photos from unsplash where appropriate, only valid URLs you know exist. Do not download the images, only link to them in image tags. 8 | 9 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "lib": ["ES2023"], 5 | "module": "ESNext", 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "moduleResolution": "bundler", 10 | "allowImportingTsExtensions": true, 11 | "isolatedModules": true, 12 | "moduleDetection": "force", 13 | "noEmit": true, 14 | 15 | /* Linting */ 16 | "strict": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["vite.config.ts"] 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Configurations/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Configurations; 2 | 3 | import com.cofix.cofixBackend.Services.AuthService; 4 | import com.cofix.cofixBackend.Services.CofixService; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.annotation.Order; 8 | 9 | @Configuration 10 | public class AppConfig { 11 | // 12 | // @Bean 13 | // @Order(1) 14 | // public AuthService authService() { 15 | // return new AuthService(); 16 | // } 17 | // 18 | // @Bean 19 | // @Order(2) 20 | // public CofixService cofixService() { 21 | // return new CofixService(); 22 | // } 23 | } -------------------------------------------------------------------------------- /CoFix-backend/artifacts/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.show-sql=true 2 | spring.postgres.datasource.type=com.zaxxer.hikari.HikariDataSource 3 | spring.postgres.datasource.default-auto-commit=false 4 | spring.postgres.datasource.connection-pool-name=SpringBootJPAHikariCP 5 | spring.postgres.datasource.initial-pool-size=5 6 | spring.postgres.datasource.min-pool-size=5 7 | spring.postgres.datasource.max-pool-size=10 8 | spring.postgres.datasource.Query-Time-Out=5 9 | spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/cofixdb 10 | spring.postgres.datasource.username=postgres 11 | spring.postgres.datasource.password=Nani2005 12 | cofix.schema.name=public 13 | spring.application.name=cofixBackend 14 | server.port=8000 15 | spring.postgres.datasource.idle-timeout=600000 16 | spring.postgres.datasource.max-lifetime=1800000 -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Repos/PostsRepo.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Repos; 2 | 3 | import com.cofix.cofixBackend.Models.BenefitTypes; 4 | import com.cofix.cofixBackend.Models.MyPost; 5 | import com.cofix.cofixBackend.Models.PostPk; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | @Repository 12 | public interface PostsRepo extends JpaRepository { 13 | List findByEmail(String email); 14 | List findByEmailAndBenefitType(String email, BenefitTypes benefitType); 15 | List findByBenefitType(BenefitTypes benefitTypes); 16 | void deleteByPostId(Long postId); 17 | 18 | // MyPost findByEmailAndPostId(String email,String postId); 19 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.jpa.show-sql=true 2 | spring.postgres.datasource.type=com.zaxxer.hikari.HikariDataSource 3 | spring.postgres.datasource.default-auto-commit=false 4 | spring.postgres.datasource.connection-pool-name=SpringBootJPAHikariCP 5 | spring.postgres.datasource.initial-pool-size=5 6 | spring.postgres.datasource.min-pool-size=5 7 | spring.postgres.datasource.max-pool-size=10 8 | spring.postgres.datasource.Query-Time-Out=5 9 | spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/cofixdb 10 | spring.postgres.datasource.username=postgres 11 | spring.postgres.datasource.password=Nani2005 12 | cofix.schema.name=public 13 | spring.application.name=cofixBackend 14 | server.port=8000 15 | spring.postgres.datasource.idle-timeout=600000 16 | spring.postgres.datasource.max-lifetime=1800000 -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Models/MyReview.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Models; 2 | 3 | import jakarta.persistence.*; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | 8 | import java.time.LocalDateTime; 9 | 10 | @Entity 11 | @Setter 12 | @Getter 13 | @ToString 14 | @Table(schema = "${cofix.schema.name}", name = "reviews") 15 | public class MyReview { 16 | 17 | @Id 18 | @Column(name = "review_id") 19 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_sequence_generator") 20 | @SequenceGenerator(name = "my_sequence_generator", sequenceName = "public.reviews_review_id_seq", allocationSize = 1) 21 | Long reviewId; 22 | String name; 23 | String email; 24 | String message; 25 | @Column(name="create_date") 26 | LocalDateTime createDate; 27 | } 28 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js'; 2 | import globals from 'globals'; 3 | import reactHooks from 'eslint-plugin-react-hooks'; 4 | import reactRefresh from 'eslint-plugin-react-refresh'; 5 | import tseslint from 'typescript-eslint'; 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | } 28 | ); 29 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Configurations/WebConfig.java.bkp: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Configurations; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | @Configuration 9 | public class WebConfig implements WebMvcConfigurer { 10 | 11 | // @Override 12 | // public void addCorsMappings(CorsRegistry registry) { 13 | // registry.addMapping("/api/**") 14 | // .allowedOrigins("http://localhost:8000") 15 | // .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") 16 | // .allowedHeaders("*") 17 | // .allowCredentials(true) 18 | // .maxAge(3600); 19 | // } 20 | } -------------------------------------------------------------------------------- /src/components/Input.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | interface InputProps extends React.InputHTMLAttributes { 4 | label?: string; 5 | error?: string; 6 | } 7 | 8 | export default function Input({ label, error, className = '', ...props }: InputProps) { 9 | return ( 10 |
11 | {label && ( 12 | 15 | )} 16 | 25 | {error && ( 26 |

{error}

27 | )} 28 |
29 | ); 30 | } -------------------------------------------------------------------------------- /CoFix-backend/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | wrapperVersion=3.3.2 18 | distributionType=only-script 19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip 20 | -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Models/MyUser.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Models; 2 | 3 | 4 | import jakarta.persistence.Column; 5 | import jakarta.persistence.Entity; 6 | import jakarta.persistence.Id; 7 | import jakarta.persistence.Table; 8 | import lombok.*; 9 | 10 | import java.time.LocalDateTime; 11 | 12 | @Entity 13 | @Table(schema = "${cofix.schema.name}", name = "users") 14 | @ToString 15 | @Getter 16 | @Setter 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class MyUser { 20 | 21 | @Id 22 | String email; 23 | String name; 24 | String password; 25 | @Column(name = "nick_name") 26 | String nickName; 27 | @Column(name = "phone_number") 28 | String phoneNumber; 29 | String country; 30 | String gender; 31 | String address; 32 | @Column(name = "create_date") 33 | LocalDateTime createDate; 34 | 35 | public MyUser(String name, String email, String password){ 36 | this.name = name; 37 | this.email = email; 38 | this.password = password; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/components/Profile/ProfileHeader.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Camera } from 'lucide-react'; 3 | 4 | export default function ProfileHeader() { 5 | return ( 6 |
7 | Profile Background 12 |
13 |
14 | Profile 19 | 22 |
23 |
24 |
25 | ); 26 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "communitifx", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint .", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "framer-motion": "^11.0.8", 14 | "leaflet": "^1.9.4", 15 | "lucide-react": "^0.344.0", 16 | "mapbox-gl": "^3.2.0", 17 | "react": "^18.3.1", 18 | "react-dom": "^18.3.1", 19 | "react-leaflet": "^4.2.1", 20 | "react-map-gl": "^7.1.7", 21 | "react-router-dom": "^6.22.3" 22 | }, 23 | "devDependencies": { 24 | "@eslint/js": "^9.9.1", 25 | "@types/react": "^18.3.5", 26 | "@types/react-dom": "^18.3.0", 27 | "@vitejs/plugin-react": "^4.3.1", 28 | "autoprefixer": "^10.4.20", 29 | "eslint": "^9.9.1", 30 | "eslint-plugin-react-hooks": "^5.1.0-rc.0", 31 | "eslint-plugin-react-refresh": "^0.4.11", 32 | "globals": "^15.9.0", 33 | "postcss": "^8.4.47", 34 | "tailwindcss": "^3.4.14", 35 | "typescript": "^5.5.3", 36 | "typescript-eslint": "^8.3.0", 37 | "vite": "^5.4.2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/components/AuthLayout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { MapPin } from 'lucide-react'; 4 | import Footer from './Footer'; 5 | 6 | interface AuthLayoutProps { 7 | children: React.ReactNode; 8 | title: string; 9 | subtitle: string; 10 | } 11 | 12 | export default function AuthLayout({ children, title, subtitle }: AuthLayoutProps) { 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 | Communitifx 21 | 22 |

23 | {title} 24 |

25 |

26 | {subtitle} 27 |

28 |
29 | {children} 30 |
31 |
32 |
33 |
34 | ); 35 | } -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; 3 | import Navbar from './components/Navbar'; 4 | import Index from './pages/Index'; 5 | import Login from './pages/Login'; 6 | import Signup from './pages/Signup'; 7 | import Home from './pages/Home'; 8 | import CommunityIssues from './pages/CommunityIssues'; 9 | import GovernmentSchemes from './pages/GovernmentSchemes'; 10 | import Notices from './pages/Notices'; 11 | import Profile from './pages/Profile'; 12 | // import AdminDashboard from './pages/AdminDashboard'; 13 | 14 | function App() { 15 | return ( 16 | 17 | 18 | {/* Public routes */} 19 | } /> 20 | } /> 21 | } /> 22 | 23 | {/* Protected routes */} 24 | } /> 25 | } /> 26 | } /> 27 | } /> 28 | } /> 29 | 30 | 31 | 32 | ); 33 | } 34 | 35 | export default App; -------------------------------------------------------------------------------- /src/components/Navbar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { MapPin, AlertCircle, LogIn } from 'lucide-react'; 4 | 5 | export default function Navbar() { 6 | return ( 7 | 35 | ); 36 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Configurations/HikariCPConfig.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Configurations; 2 | 3 | 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.core.env.Environment; 12 | import com.zaxxer.hikari.HikariDataSource; 13 | 14 | import java.util.Base64; 15 | 16 | @Configuration 17 | @Slf4j 18 | public class HikariCPConfig { 19 | 20 | 21 | @Autowired 22 | Environment env; 23 | 24 | 25 | @Bean 26 | public HikariDataSource postgresdbDataSource() { 27 | log.info("Initializing Postgres Database connection pool"); 28 | String pgUser; 29 | String pgPassword; 30 | pgUser = env.getProperty("spring.postgres.datasource.username"); 31 | pgPassword = env.getProperty("spring.postgres.datasource.password"); 32 | 33 | //log.info("user:" + pgUser+"| pw:"+pgPassword +"|"); 34 | HikariDataSource dataSource = new HikariDataSource(); 35 | try { 36 | dataSource.setJdbcUrl(env.getProperty("spring.datasource.url")); 37 | dataSource.setAutoCommit(false); 38 | dataSource.setConnectionTimeout(30000); 39 | dataSource.setIdleTimeout(30000); 40 | dataSource.setPoolName(env.getProperty("spring.postgres.datasource.connection-pool-name")); 41 | dataSource.setMaximumPoolSize(25); 42 | dataSource.setUsername(pgUser); 43 | dataSource.setPassword(pgPassword); 44 | } 45 | catch (Exception e) { 46 | log.error("Failed to Init Postgres Database pool : ",e); 47 | } 48 | return dataSource; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/components/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { LucideIcon } from 'lucide-react'; 3 | 4 | interface ButtonProps extends React.ButtonHTMLAttributes { 5 | variant?: 'primary' | 'secondary' | 'outline' | 'danger'; 6 | size?: 'sm' | 'md' | 'lg'; 7 | icon?: LucideIcon; 8 | loading?: boolean; 9 | fullWidth?: boolean; 10 | } 11 | 12 | export default function Button({ 13 | children, 14 | variant = 'primary', 15 | size = 'md', 16 | icon: Icon, 17 | loading, 18 | fullWidth, 19 | className = '', 20 | ...props 21 | }: ButtonProps) { 22 | const baseStyles = 'inline-flex items-center justify-center font-medium rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2'; 23 | 24 | const variants = { 25 | primary: 'bg-indigo-600 text-white hover:bg-indigo-700 focus:ring-indigo-500', 26 | secondary: 'bg-gray-100 text-gray-700 hover:bg-gray-200 focus:ring-gray-500', 27 | outline: 'border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 focus:ring-indigo-500', 28 | danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500', 29 | }; 30 | 31 | const sizes = { 32 | sm: 'px-3 py-1.5 text-sm', 33 | md: 'px-4 py-2 text-base', 34 | lg: 'px-6 py-3 text-lg', 35 | }; 36 | 37 | return ( 38 | 60 | ); 61 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Models/MyPost.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Models; 2 | 3 | 4 | import jakarta.persistence.*; 5 | import lombok.*; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @Entity 10 | @Table(schema = "${cofix.schema.name}", name = "posts") 11 | @IdClass(PostPk.class) 12 | @ToString 13 | @Getter 14 | @Setter 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class MyPost{ 18 | 19 | @Id 20 | @Column(name = "email") 21 | String email; 22 | 23 | @Id 24 | @Column(name = "post_id") 25 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_sequence_generator") 26 | @SequenceGenerator(name = "my_sequence_generator", sequenceName = "public.posts_post_id_seq", allocationSize = 1) 27 | Long postId; 28 | 29 | @Column(name = "benefit_type") 30 | @Enumerated(EnumType.STRING) 31 | BenefitTypes benefitType; 32 | 33 | @Column(name = "scheme_name") 34 | String schemeName; 35 | 36 | @Column(name = "description") 37 | String description; 38 | 39 | @Column(name = "image") 40 | String image; 41 | 42 | @Column(name = "issue_name") 43 | String issueName; 44 | 45 | @Column(name = "activity_description") 46 | String activityDescription; 47 | 48 | @Embedded 49 | @AttributeOverrides({ 50 | @AttributeOverride(name = "lat", column = @Column(name = "latitude")), 51 | @AttributeOverride(name = "lng", column = @Column(name = "longitude")) 52 | }) 53 | Location location; 54 | 55 | @Column(name = "comment") 56 | String comment; 57 | 58 | @Column(name = "create_date") 59 | LocalDateTime createDate; 60 | 61 | public MyPost(String email, BenefitTypes benefitType, String schemeName, String description, String image, String issueName, String activityDescription, Location location, String comment) { 62 | this.email = email; 63 | this.benefitType = benefitType; 64 | this.schemeName = schemeName; 65 | this.description = description; 66 | this.image = image; 67 | this.issueName = issueName; 68 | this.activityDescription = activityDescription; 69 | this.location = location; 70 | this.comment = comment; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/components/Map.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'; 3 | import { Icon } from 'leaflet'; 4 | import 'leaflet/dist/leaflet.css'; 5 | 6 | // Fix for default marker icon 7 | import markerIcon2x from 'leaflet/dist/images/marker-icon-2x.png'; 8 | import markerIcon from 'leaflet/dist/images/marker-icon.png'; 9 | import markerShadow from 'leaflet/dist/images/marker-shadow.png'; 10 | 11 | delete (Icon.Default.prototype as any)._getIconUrl; 12 | Icon.Default.mergeOptions({ 13 | iconUrl: markerIcon, 14 | iconRetinaUrl: markerIcon2x, 15 | shadowUrl: markerShadow, 16 | }); 17 | 18 | interface Location { 19 | lat: number; 20 | lng: number; 21 | } 22 | 23 | interface Issue { 24 | id: string; 25 | title: string; 26 | description: string; 27 | location: Location; 28 | status: string; 29 | } 30 | 31 | interface IssueMapProps { 32 | issues: Issue[]; 33 | } 34 | 35 | export default function IssueMap({ issues }: IssueMapProps) { 36 | const center: Location = issues[0]?.location || { lat: 37.7749, lng: -122.4194 }; // Default to San Francisco 37 | 38 | return ( 39 | 44 | 48 | {issues.map((issue) => ( 49 | 53 | 54 |
55 |

{issue.title}

56 |

{issue.description}

57 | 62 | {issue.status} 63 | 64 |
65 |
66 |
67 | ))} 68 |
69 | ); 70 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Services/AuthService.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Services; 2 | 3 | import com.cofix.cofixBackend.Models.MyUser; 4 | import com.cofix.cofixBackend.Repos.UsersRepo; 5 | import jakarta.annotation.PostConstruct; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.core.Ordered; 9 | import org.springframework.core.annotation.Order; 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.time.LocalDateTime; 14 | 15 | @Service 16 | @Slf4j 17 | //@Order(2) 18 | public class AuthService implements Ordered { 19 | 20 | @Autowired 21 | private UsersRepo userRepository; 22 | private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 23 | 24 | @PostConstruct 25 | public void initCofix(){ 26 | 27 | // Add admin data 28 | if(userRepository.findByEmail("admin@email.com")==null) { 29 | log.info("++++++++++++++ CREATING ADMIN USER ++++++++++++++"); 30 | userRepository.save(new MyUser("admin", "admin@email.com", passwordEncoder.encode("admin"))); 31 | } 32 | // Add test user data 33 | if(userRepository.findByEmail("test@user.com") == null) { 34 | log.info("++++++++++++++ CREATING TEST USER ++++++++++++++++"); 35 | userRepository.save(new MyUser("test@user.com", "Test User", passwordEncoder.encode("password"), "testy", "1234567890", "India", "Male", "Telangana", LocalDateTime.now())); 36 | } 37 | log.info("======================= AuthService initialized ======================="); 38 | } 39 | 40 | public boolean loginUser(String email, String rawPassword) { 41 | MyUser user = userRepository.findByEmail(email); 42 | if (user != null) { 43 | return passwordEncoder.matches(rawPassword, user.getPassword()); 44 | } 45 | return false; 46 | } 47 | 48 | public MyUser registerUser(MyUser user) { 49 | user.setPassword(passwordEncoder.encode(user.getPassword())); 50 | user.setCreateDate(LocalDateTime.now()); 51 | return userRepository.save(user); 52 | } 53 | 54 | @Override 55 | public int getOrder(){ 56 | return 1; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/components/IssueCategoryModal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { X } from 'lucide-react'; 3 | import Button from './Button'; 4 | 5 | interface IssueCategoryModalProps { 6 | isOpen: boolean; 7 | onClose: () => void; 8 | onSelectCategory: (category: string) => void; 9 | } 10 | 11 | const issueCategories = [ 12 | { id: 'drainage', name: 'Drainage Issues', icon: '🌊' }, 13 | { id: 'roads', name: 'Road Problems', icon: '🛣️' }, 14 | { id: 'streetlights', name: 'Street Lights', icon: '💡' }, 15 | { id: 'electricity', name: 'Electricity Issues', icon: '⚡' }, 16 | { id: 'waste', name: 'Waste Management', icon: '🗑️' }, 17 | { id: 'water', name: 'Water Supply', icon: '💧' }, 18 | { id: 'parks', name: 'Parks & Recreation', icon: '🌳' }, 19 | { id: 'public-safety', name: 'Public Safety', icon: '🚨' } 20 | ]; 21 | 22 | export default function IssueCategoryModal({ isOpen, onClose, onSelectCategory }: IssueCategoryModalProps) { 23 | if (!isOpen) return null; 24 | 25 | return ( 26 |
27 |
28 |
29 |
30 |

Select Issue Category

31 | 34 |
35 | 36 |
37 | {issueCategories.map((category) => ( 38 | 46 | ))} 47 |
48 | 49 |
50 | 53 |
54 |
55 |
56 |
57 | ); 58 | } -------------------------------------------------------------------------------- /CoFix-backend/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.3.1 9 | 10 | 11 | com.cofix 12 | cofixBackend 13 | 0.0.2-SNAPSHOT 14 | cofixBackend 15 | Demo project for Spring Boot 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 17 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-web 36 | 37 | 38 | org.springframework.security 39 | spring-security-core 40 | 41 | 42 | org.projectlombok 43 | lombok 44 | true 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | org.postgresql 53 | postgresql 54 | runtime 55 | 42.3.1 56 | 57 | 58 | org.springframework.boot 59 | spring-boot-starter-data-jpa 60 | 61 | 62 | com.zaxxer 63 | HikariCP 64 | 4.0.3 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-maven-plugin 78 | 79 | 80 | 81 | org.projectlombok 82 | lombok 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/components/DashboardLayout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link, useLocation } from 'react-router-dom'; 3 | import { MapPin, Home, AlertCircle, Bell, User, Settings, LogOut } from 'lucide-react'; 4 | import Footer from './Footer'; 5 | 6 | interface DashboardLayoutProps { 7 | children: React.ReactNode; 8 | } 9 | 10 | export default function DashboardLayout({ children }: DashboardLayoutProps) { 11 | const location = useLocation(); 12 | 13 | const navigation = [ 14 | { name: 'Home', href: '/home', icon: Home }, 15 | { name: 'Issues', href: '/issues', icon: AlertCircle }, 16 | { name: 'Notices', href: '/notices', icon: Bell }, 17 | { name: 'Profile', href: '/profile', icon: User }, 18 | ]; 19 | 20 | return ( 21 |
22 | {/* Sidebar */} 23 |
24 |
25 | 26 | 27 | Communitifx 28 | 29 |
30 | 49 |
50 | 54 | 55 | Settings 56 | 57 | 64 |
65 |
66 | 67 | {/* Main content */} 68 |
69 |
70 |
71 | {children} 72 |
73 |
74 |
75 |
76 |
77 | ); 78 | } -------------------------------------------------------------------------------- /src/components/Profile/PersonalInfo.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { User, AtSign, Phone, MapPin, Home, Users } from 'lucide-react'; 3 | import EditProfileModal, { UserInfo } from './EditProfileModel'; 4 | 5 | interface InfoItemProps { 6 | icon: React.ReactNode; 7 | label: string; 8 | value: string; 9 | } 10 | 11 | function InfoItem({ icon, label, value }: InfoItemProps) { 12 | return ( 13 |
14 |
{icon}
15 |
16 |

{label}

17 |

{value}

18 |
19 |
20 | ); 21 | } 22 | 23 | export default function PersonalInfo() { 24 | const [isEditModalOpen, setIsEditModalOpen] = React.useState(false); 25 | const [userInfo, setUserInfo] = React.useState({ 26 | fullName: "Alexander Mitchell", 27 | nickname: "Alex", 28 | phone: "+1 (555) 123-4567", 29 | country: "United States", 30 | gender: "Male", 31 | address: "123 Tech Street, San Francisco, CA 94105" 32 | }); 33 | 34 | const handleSave = (updatedInfo: UserInfo) => { 35 | setUserInfo(updatedInfo); 36 | // Here you would typically make an API call to update the user info 37 | }; 38 | 39 | return ( 40 | <> 41 |
42 |
43 |
44 |

{userInfo.fullName}

45 |

@{userInfo.nickname}

46 |
47 | 53 |
54 | 55 |
56 | } 58 | label="Full Name" 59 | value={userInfo.fullName} 60 | /> 61 | } 63 | label="Nickname" 64 | value={userInfo.nickname} 65 | /> 66 | } 68 | label="Phone Number" 69 | value={userInfo.phone} 70 | /> 71 | } 73 | label="Country" 74 | value={userInfo.country} 75 | /> 76 | } 78 | label="Gender" 79 | value={userInfo.gender} 80 | /> 81 | } 83 | label="Address" 84 | value={userInfo.address} 85 | /> 86 |
87 |
88 | 89 | setIsEditModalOpen(false)} 92 | userInfo={userInfo} 93 | onSave={handleSave} 94 | /> 95 | 96 | ); 97 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Services/CofixService.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Services; 2 | 3 | import com.cofix.cofixBackend.Models.*; 4 | import com.cofix.cofixBackend.Repos.PostsRepo; 5 | import com.cofix.cofixBackend.Repos.ReviewsRepo; 6 | import com.cofix.cofixBackend.Repos.UsersRepo; 7 | import jakarta.annotation.PostConstruct; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | import lombok.extern.slf4j.Slf4j; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.core.Ordered; 13 | import org.springframework.core.annotation.Order; 14 | import org.springframework.stereotype.Service; 15 | import org.springframework.transaction.annotation.Transactional; 16 | 17 | import java.time.LocalDateTime; 18 | import java.util.List; 19 | import java.util.Optional; 20 | 21 | @Service 22 | @Getter 23 | @Setter 24 | @Slf4j 25 | //@Order(1) 26 | public class CofixService implements Ordered { 27 | 28 | @Autowired 29 | PostsRepo postsRepo; 30 | @Autowired 31 | UsersRepo usersRepo; 32 | @Autowired 33 | ReviewsRepo reviewsRepo; 34 | 35 | public CofixService(){ 36 | } 37 | 38 | @PostConstruct 39 | public void initCofix(){ 40 | 41 | if(postsRepo.findByEmailAndBenefitType("test@user.com",BenefitTypes.COMMUNITY_ISSUE).isEmpty()){ 42 | log.info("Adding test@user Community Problem data"); 43 | postsRepo.save(new MyPost("test@user.com",null, BenefitTypes.COMMUNITY_ISSUE,null,null,null,"electricity/streetlights","Fix power supply at a this location", new Location(2D,1D), "Need new street light", LocalDateTime.now())); 44 | } 45 | if( postsRepo.findByEmailAndBenefitType("test@user.com",BenefitTypes.GOVERNMENT_SCHEME).isEmpty()){ 46 | log.info("Adding test@user Government Schemes data"); 47 | postsRepo.save(new MyPost("test@user.com",null,BenefitTypes.GOVERNMENT_SCHEME,"Rythu Bandhu","Rythu Bandhu description",null,null,null, null, "Rythu Bandhu Description",LocalDateTime.now())); 48 | } 49 | log.info("======================= CofixService initialized ======================="); 50 | } 51 | 52 | @Override 53 | public int getOrder(){ 54 | return 2; 55 | } 56 | 57 | public MyPost addIssuePost(MyPost myPost){ 58 | myPost.setCreateDate(LocalDateTime.now()); 59 | return postsRepo.save(myPost); 60 | } 61 | public MyPost addSchemePost(MyPost myPost){ 62 | myPost.setCreateDate(LocalDateTime.now()); 63 | return postsRepo.save(myPost); 64 | } 65 | 66 | public List getProfilePosts(String email) { 67 | log.info("Show all posts for email: " + email); 68 | List posts = postsRepo.findByEmail(email); 69 | return posts; 70 | } 71 | 72 | public List getProfileIssues(String email) { 73 | log.info("Show all issues for email: " + email); 74 | List posts = postsRepo.findByEmailAndBenefitType(email,BenefitTypes.COMMUNITY_ISSUE); 75 | return posts; 76 | } 77 | 78 | public List getProfileSchemes(String email) { 79 | log.info("Show all schemes for email: " + email); 80 | List posts = postsRepo.findByEmailAndBenefitType(email,BenefitTypes.GOVERNMENT_SCHEME); 81 | return posts; 82 | } 83 | 84 | @Transactional 85 | public void deletePost(Long postId) { 86 | postsRepo.deleteByPostId(postId); 87 | } 88 | 89 | public MyReview addReview(MyReview review){ 90 | review.setCreateDate(LocalDateTime.now()); 91 | return reviewsRepo.save(review); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/pages/Login.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { LogIn } from 'lucide-react'; 4 | import AuthLayout from '../components/AuthLayout'; 5 | import Input from '../components/Input'; 6 | import Button from '../components/Button'; 7 | 8 | export default function Login() { 9 | const [email, setEmail] = React.useState(''); 10 | const [password, setPassword] = React.useState(''); 11 | 12 | const handleSubmit = async (e: React.FormEvent) => { 13 | e.preventDefault(); 14 | // Add login logic here 15 | console.log('Form Submitted!'); 16 | console.log('Email:', email); 17 | console.log('Password:', password); 18 | const response = await fetch("http://localhost:8000/api/login", { 19 | method: "POST", 20 | headers: { 21 | "Content-Type": "application/x-www-form-urlencoded", 22 | }, 23 | body: new URLSearchParams({ 24 | email: email, 25 | password: password, 26 | }), 27 | }); 28 | console.log('Recieved response successfully', response.status); 29 | localStorage.setItem('userEmail', email); 30 | console.log('Email stored in localStorage'); 31 | if (response.ok) { 32 | const responseData = await response.text(); 33 | console.log('Response ok: ', responseData); 34 | alert('login successful'); 35 | localStorage.setItem('accountData', JSON.stringify(responseData)); 36 | window.location.href = 'home'; 37 | } else { 38 | const responseData = await response.text(); 39 | console.log("Response not ok: ", responseData); 40 | alert("Login failed"); 41 | } 42 | }; 43 | 44 | return ( 45 | 49 |
50 |
51 | setEmail(e.target.value)} 56 | required 57 | /> 58 | setPassword(e.target.value)} 63 | required 64 | /> 65 |
66 | 67 |
68 |
69 | 75 | 78 |
79 | 80 |
81 | 82 | Forgot your password? 83 | 84 |
85 |
86 | 87 | 94 | 95 |
96 | 97 | Don't have an account?{' '} 98 | 99 | Sign up 100 | 101 | 102 |
103 |
104 |
105 | ); 106 | } -------------------------------------------------------------------------------- /src/pages/Signup.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { UserPlus } from 'lucide-react'; 4 | import AuthLayout from '../components/AuthLayout'; 5 | import Input from '../components/Input'; 6 | import Button from '../components/Button'; 7 | 8 | export default function Signup() { 9 | const [formData, setFormData] = React.useState({ 10 | fullName: '', 11 | email: '', 12 | password: '', 13 | confirmPassword: '', 14 | }); 15 | 16 | const handleSubmit = async (e: React.FormEvent) => { 17 | e.preventDefault(); 18 | // Add signup logic here 19 | // const form = e.target as HTMLFormElement; 20 | // const formData = new FormData(form); 21 | 22 | // // Using type assertions to ensure values are strings 23 | // const name = formData.get("fullName") as string; 24 | // const email = formData.get("email") as string; 25 | // const password = formData.get("password") as string; 26 | // const confirmPassword = formData.get("confirmPassword") as string; 27 | // console.log('name=', name, 'pass:', password, 'email:', email); 28 | // // Check for null values before making the request 29 | // if (!name || !email || !password || !(password === confirmPassword)) { 30 | // alert("Please fill out all fields."); 31 | // return; 32 | // } 33 | console.log('Form Submitted!'); 34 | console.log('Email:', formData.email); 35 | console.log('Password:', formData.password); 36 | alert('pause'); 37 | try { 38 | const response = await fetch("http://localhost:8000/api/signup", { 39 | method: "POST", 40 | headers: { 41 | "Content-Type": "application/x-www-form-urlencoded", 42 | }, 43 | body: new URLSearchParams({ 44 | name: 'name', 45 | email: 'email', 46 | password: 'rahul', 47 | }), 48 | }); 49 | 50 | if (response.ok) { 51 | alert("Sign-up successful"); 52 | window.location.href = 'index'; 53 | } else { 54 | alert("Sign-up failed"); 55 | } 56 | } catch (error) { 57 | console.error("Error:", error); 58 | alert("Sign-up failed"); 59 | } 60 | }; 61 | 62 | return ( 63 | 67 |
handleSubmit}> 68 |
69 | setFormData({ ...formData, fullName: e.target.value })} 74 | required 75 | /> 76 | setFormData({ ...formData, email: e.target.value })} 81 | required 82 | /> 83 | setFormData({ ...formData, password: e.target.value })} 88 | required 89 | /> 90 | setFormData({ ...formData, confirmPassword: e.target.value })} 95 | required 96 | /> 97 |
98 | 99 | 106 | 107 |
108 | 109 | Already have an account?{' '} 110 | 111 | Sign in 112 | 113 | 114 |
115 |
116 |
117 | ); 118 | } -------------------------------------------------------------------------------- /src/pages/Notices.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | import { Bell, CheckCircle, Clock, AlertTriangle } from 'lucide-react'; 4 | import DashboardLayout from '../components/DashboardLayout'; 5 | 6 | interface Notice { 7 | id: string; 8 | title: string; 9 | message: string; 10 | type: 'update' | 'resolution' | 'alert'; 11 | timestamp: Date; 12 | read: boolean; 13 | } 14 | 15 | const mockNotices: Notice[] = [ 16 | { 17 | id: '1', 18 | title: 'Street Light Issue Resolved', 19 | message: 'The broken street light on Main St. has been fixed.', 20 | type: 'resolution', 21 | timestamp: new Date(), 22 | read: false 23 | }, 24 | { 25 | id: '2', 26 | title: 'Update on Pothole Repair', 27 | message: 'Maintenance crew scheduled for next week.', 28 | type: 'update', 29 | timestamp: new Date(Date.now() - 86400000), 30 | read: true 31 | }, 32 | { 33 | id: '3', 34 | title: 'Urgent: Water Main Break', 35 | message: 'Emergency repairs needed on Oak Street.', 36 | type: 'alert', 37 | timestamp: new Date(Date.now() - 172800000), 38 | read: false 39 | } 40 | ]; 41 | 42 | export default function Notices() { 43 | return ( 44 | 45 |
46 | {/* Header */} 47 |
48 |

Notices

49 |

50 | Stay updated on your reported issues and community announcements 51 |

52 |
53 | 54 | {/* Filters */} 55 |
56 |
57 | 60 | 63 | 66 | 69 |
70 |
71 | 72 | {/* Notices List */} 73 |
74 |
    75 | {mockNotices.map((notice, index) => ( 76 | 83 |
    84 |
    85 | {notice.type === 'resolution' && ( 86 | 87 | )} 88 | {notice.type === 'update' && ( 89 | 90 | )} 91 | {notice.type === 'alert' && ( 92 | 93 | )} 94 |
    95 |
    96 |
    97 |

    98 | {notice.title} 99 |

    100 |
    101 |

    102 | {new Date(notice.timestamp).toLocaleDateString()} 103 |

    104 |
    105 |
    106 |
    107 |

    108 | {notice.message} 109 |

    110 |
    111 |
    112 |
    113 |
    114 | ))} 115 |
116 |
117 |
118 |
119 | ); 120 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Configurations/SecurityConfig.java.bkp: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Configurations; 2 | import org.springframework.context.annotation.Bean; 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; 7 | import org.springframework.security.config.http.SessionCreationPolicy; 8 | import org.springframework.security.core.userdetails.User; 9 | import org.springframework.security.core.userdetails.UserDetails; 10 | import org.springframework.security.core.userdetails.UserDetailsService; 11 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 12 | import org.springframework.security.crypto.password.PasswordEncoder; 13 | import org.springframework.security.provisioning.InMemoryUserDetailsManager; 14 | import org.springframework.security.web.SecurityFilterChain; 15 | 16 | @Configuration 17 | @EnableWebSecurity 18 | public class SecurityConfig { 19 | 20 | // @Bean 21 | // public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { 22 | // http 23 | // .csrf().disable() 24 | // .authorizeRequests() 25 | // //.antMatchers("/api/login").permitAll() 26 | // .anyRequest().authenticated() 27 | // .and() 28 | // .sessionManagement() 29 | // .sessionCreationPolicy(SessionCreationPolicy.STATELESS); 30 | // 31 | // return http.build(); 32 | // } 33 | 34 | 35 | @Bean 36 | public UserDetailsService inMemoryUserDetailsManager() { 37 | UserDetails user = User.builder() 38 | .username("user") 39 | .password(passwordEncoder().encode("password")) 40 | .roles("USER") 41 | .build(); 42 | UserDetails admin = User.builder() 43 | .username("admin") 44 | .password(passwordEncoder().encode("password")) 45 | .roles("USER", "ADMIN") 46 | .build(); 47 | return new InMemoryUserDetailsManager(user, admin); 48 | } 49 | 50 | /*@Bean 51 | public UserDetailsService jdbcUserDetailsService(DataSource dataSource) { 52 | return new JdbcUserDetailsManager(dataSource); 53 | }*/ 54 | 55 | @Bean 56 | public PasswordEncoder passwordEncoder() { 57 | return new BCryptPasswordEncoder(); 58 | } 59 | 60 | @Bean 61 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 62 | 63 | http.authorizeRequests() 64 | .requestMatchers("/login").permitAll() 65 | .requestMatchers("/**").authenticated() 66 | .and() 67 | .formLogin().permitAll(); 68 | 69 | //@formatter:off 70 | http.authorizeRequests() 71 | .requestMatchers("/login").permitAll() 72 | .requestMatchers("/**").hasAnyRole("USER", "ADMIN") 73 | .requestMatchers("/admin/**").hasAnyRole("ADMIN") 74 | .and() 75 | .formLogin() 76 | .loginPage("/login") 77 | .loginProcessingUrl("/process-login") 78 | .defaultSuccessUrl("/home") 79 | .failureUrl("/login?error=true") 80 | .permitAll() 81 | .and() 82 | .logout() 83 | .logoutSuccessUrl("/login?logout=true") 84 | .invalidateHttpSession(true) 85 | .deleteCookies("JSESSIONID") 86 | .permitAll() 87 | .and() 88 | .csrf() 89 | .disable(); 90 | //@formatter:on 91 | 92 | return http.build(); 93 | } 94 | 95 | @Bean 96 | public WebSecurityCustomizer webSecurityCustomizer() { 97 | return (web) -> web.ignoring().requestMatchers("/resources/**", "/static/**"); 98 | } 99 | 100 | /*@Bean 101 | AuthenticationSuccessHandler authenticationSuccessHandler() { 102 | return new CustomAuthenticationSuccessHandler(); 103 | } 104 | 105 | @Bean 106 | AuthenticationFailureHandler authenticationFailureHandler() { 107 | return new CustomAuthenticationFailureHandler(); 108 | }*/ 109 | } -------------------------------------------------------------------------------- /CoFix-backend/src/main/java/com/cofix/cofixBackend/Configurations/DynamicPhysicalNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.cofix.cofixBackend.Configurations; 2 | 3 | import org.hibernate.boot.model.naming.Identifier; 4 | import org.hibernate.boot.model.naming.PhysicalNamingStrategy; 5 | import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; 6 | import org.springframework.beans.BeansException; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.ApplicationContextAware; 9 | import org.springframework.core.env.Environment; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.util.Assert; 12 | 13 | import java.util.Locale; 14 | import java.util.regex.Matcher; 15 | import java.util.regex.Pattern; 16 | 17 | 18 | /** 19 | * It is copied from {@link org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl} 20 | */ 21 | @Component 22 | public class DynamicPhysicalNamingStrategy implements PhysicalNamingStrategy, ApplicationContextAware { 23 | private final Pattern VALUE_PATTERN = Pattern.compile("^\\$\\{([\\w.]+)}$"); 24 | private Environment environment; 25 | 26 | @Override 27 | public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) { 28 | return apply(name, jdbcEnvironment); 29 | } 30 | 31 | @Override 32 | public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) { 33 | return apply(name, jdbcEnvironment); 34 | } 35 | 36 | @Override 37 | public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) { 38 | return apply(name, jdbcEnvironment); 39 | } 40 | 41 | @Override 42 | public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) { 43 | return apply(name, jdbcEnvironment); 44 | } 45 | 46 | @Override 47 | public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) { 48 | return apply(name, jdbcEnvironment); 49 | } 50 | 51 | private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) { 52 | if (name == null) { 53 | return null; 54 | } 55 | 56 | // Custom Implementation Start 57 | String text = name.getText(); 58 | Matcher matcher = VALUE_PATTERN.matcher(text); 59 | if (matcher.matches()) { 60 | String propertyKey = matcher.group(1); 61 | text = environment.getProperty(propertyKey); 62 | Assert.notNull(text, "Property is not found '" + propertyKey + "'"); 63 | 64 | // extract catalog selection part 65 | // Example: 66 | // Current Catalog: TESTDB 67 | // Property: TESTDB:TestUser, TESTDB2:TestUser 68 | // Text will be TestUser 69 | Pattern catalogPattern = Pattern.compile(jdbcEnvironment.getCurrentCatalog().getText() + ":([^,]+)"); 70 | Matcher catalogMatcher = catalogPattern.matcher(text); 71 | if (catalogMatcher.find()) { 72 | text = catalogMatcher.group(1); 73 | } 74 | 75 | // Caution: You can remove below return function, if so text will be transformed with spring advice 76 | return getIdentifier(text, name.isQuoted(), jdbcEnvironment); 77 | } 78 | // Custom Implementation End 79 | 80 | 81 | StringBuilder builder = new StringBuilder(text.replace('.', '_')); 82 | for (int i = 1; i < builder.length() - 1; i++) { 83 | if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) { 84 | builder.insert(i++, '_'); 85 | } 86 | } 87 | return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment); 88 | } 89 | 90 | /** 91 | * Get an identifier for the specified details. By default this method will return an 92 | * identifier with the name adapted based on the result of 93 | * {@link #isCaseInsensitive(JdbcEnvironment)} 94 | * 95 | * @param name the name of the identifier 96 | * @param quoted if the identifier is quoted 97 | * @param jdbcEnvironment the JDBC environment 98 | * @return an identifier instance 99 | */ 100 | protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) { 101 | if (isCaseInsensitive(jdbcEnvironment)) { 102 | name = name.toLowerCase(Locale.ROOT); 103 | } 104 | return new Identifier(name, quoted); 105 | } 106 | 107 | /** 108 | * Specify whether the database is case sensitive. 109 | * 110 | * @param jdbcEnvironment the JDBC environment which can be used to determine case 111 | * @return true if the database is case insensitive sensitivity 112 | */ 113 | protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) { 114 | return true; 115 | } 116 | 117 | private boolean isUnderscoreRequired(char before, char current, char after) { 118 | return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after); 119 | } 120 | 121 | @Override 122 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 123 | environment = applicationContext.getBean(Environment.class); 124 | } 125 | } -------------------------------------------------------------------------------- /src/components/Profile/EditProfileModel.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { X } from 'lucide-react'; 3 | 4 | interface EditProfileModalProps { 5 | isOpen: boolean; 6 | onClose: () => void; 7 | userInfo: UserInfo; 8 | onSave: (data: UserInfo) => void; 9 | } 10 | 11 | export interface UserInfo { 12 | fullName: string; 13 | nickname: string; 14 | phone: string; 15 | country: string; 16 | gender: string; 17 | address: string; 18 | } 19 | 20 | export default function EditProfileModal({ isOpen, onClose, userInfo, onSave }: EditProfileModalProps) { 21 | const [formData, setFormData] = React.useState(userInfo); 22 | 23 | if (!isOpen) return null; 24 | 25 | const handleSubmit = (e: React.FormEvent) => { 26 | e.preventDefault(); 27 | onSave(formData); 28 | onClose(); 29 | }; 30 | 31 | const handleChange = (e: React.ChangeEvent) => { 32 | setFormData(prev => ({ 33 | ...prev, 34 | [e.target.name]: e.target.value 35 | })); 36 | }; 37 | 38 | return ( 39 |
40 |
41 |
42 | 43 |
44 |
45 |

Edit Profile

46 | 49 |
50 | 51 |
52 |
53 | 54 | 61 |
62 | 63 |
64 | 65 | 72 |
73 | 74 |
75 | 76 | 83 |
84 | 85 |
86 | 87 | 94 |
95 | 96 |
97 | 98 | 109 |
110 | 111 |
112 | 113 |