diff --git a/mappafront/.gitignore b/mappafront/.gitignore index e7ff2bb..e3e25c7 100644 --- a/mappafront/.gitignore +++ b/mappafront/.gitignore @@ -27,3 +27,5 @@ src/assets/images src/assets/icons .netlify +.env.local +.env.prod.local diff --git a/mappafront/package-lock.json b/mappafront/package-lock.json index e9026a9..a6f8952 100644 --- a/mappafront/package-lock.json +++ b/mappafront/package-lock.json @@ -11,6 +11,7 @@ "@react-hook/window-size": "^3.1.1", "@types/node": "^22.10.7", "@types/react-modal": "^3.16.3", + "axios": "^1.7.9", "leaflet": "^1.9.4", "react": "19.0.0", "react-dom": "19.0.0", @@ -2147,6 +2148,23 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2221,6 +2239,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2317,6 +2348,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2602,6 +2645,15 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -2616,6 +2668,20 @@ "node": ">=0.10" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.102", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz", @@ -2623,6 +2689,24 @@ "dev": true, "license": "ISC" }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", @@ -2630,6 +2714,33 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", @@ -3017,6 +3128,26 @@ "node": ">=12" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/force-graph": { "version": "1.49.0", "resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.49.0.tgz", @@ -3043,6 +3174,21 @@ "node": ">=12" } }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3058,6 +3204,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -3068,6 +3223,43 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3094,6 +3286,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3111,6 +3315,45 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3391,6 +3634,15 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3415,6 +3667,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3648,6 +3921,12 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/mappafront/package.json b/mappafront/package.json index 2724306..03a32a8 100644 --- a/mappafront/package.json +++ b/mappafront/package.json @@ -6,6 +6,7 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", + "buildprod": "tsc -b && vite build --mode prod", "lint": "eslint .", "preview": "vite preview" }, @@ -13,6 +14,7 @@ "@react-hook/window-size": "^3.1.1", "@types/node": "^22.10.7", "@types/react-modal": "^3.16.3", + "axios": "^1.7.9", "leaflet": "^1.9.4", "react": "19.0.0", "react-dom": "19.0.0", diff --git a/mappafront/public/_redirects b/mappafront/public/_redirects new file mode 100644 index 0000000..7797f7c --- /dev/null +++ b/mappafront/public/_redirects @@ -0,0 +1 @@ +/* /index.html 200 diff --git a/mappafront/src/actions/api.ts b/mappafront/src/actions/api.ts new file mode 100644 index 0000000..ab7a336 --- /dev/null +++ b/mappafront/src/actions/api.ts @@ -0,0 +1,11 @@ +import axios from "axios"; + +// Dynamically set backend URL +const backendUrl = import.meta.env.VITE_BACKEND_URL ?? "__VITE_BACKEND_URL__"; +console.log(backendUrl); +console.log("backend url"); + +axios.defaults.baseURL = `${backendUrl}/`; + +const api = axios; +export default api; diff --git a/mappafront/src/actions/map.ts b/mappafront/src/actions/map.ts new file mode 100644 index 0000000..80e00ef --- /dev/null +++ b/mappafront/src/actions/map.ts @@ -0,0 +1,16 @@ +import { AxiosResponse } from "axios"; +import api from "./api"; +import { CityMapResponseDataItem } from "@/models/map"; + +const mapApi = api.create({ + baseURL: api.defaults.baseURL + "city/", +}); + +export const getCityMap = async () => { + const response = await mapApi({ + url: "map/", + method: "get", + }); + + return response as AxiosResponse; +}; diff --git a/mappafront/src/actions/ordinary-people.ts b/mappafront/src/actions/ordinary-people.ts new file mode 100644 index 0000000..4499706 --- /dev/null +++ b/mappafront/src/actions/ordinary-people.ts @@ -0,0 +1,20 @@ +import { + OrdinaryPageRequestBody, + OrdinaryPageResponseData, +} from "@/models/ordinary-people"; +import api from "./api"; +import { AxiosResponse } from "axios"; + +const ordinaryApi = api.create({ + baseURL: api.defaults.baseURL + "ordinaryperson/", +}); + +export const getOrdinaryPage = async (data: OrdinaryPageRequestBody) => { + const response = await ordinaryApi({ + url: "page/", + method: "post", + data: data, + }); + + return response as AxiosResponse; +}; diff --git a/mappafront/src/models/map-filters.ts b/mappafront/src/models/map-filters.ts new file mode 100644 index 0000000..bac624f --- /dev/null +++ b/mappafront/src/models/map-filters.ts @@ -0,0 +1,5 @@ +export interface FilterGroup { + group: string; + key: string; + options: string[]; +} diff --git a/mappafront/src/models/map.ts b/mappafront/src/models/map.ts new file mode 100644 index 0000000..f13add1 --- /dev/null +++ b/mappafront/src/models/map.ts @@ -0,0 +1,13 @@ +export type CityMapResponseDataItem = { + id: number; + name: string; + asciiName?: string; + latitude: number; + longitude: number; + numberOfLocationOf: number; + numberOfSourcesWrittenInTheCity: number; + numberOfSourcesMentioningTheCity: number; + numberOfBackgroundCityOf: number; + numberOfBirthPlaceOf: number; + numberOfDeathPlaceOf: number; +}; diff --git a/mappafront/src/models/ordinary-people.ts b/mappafront/src/models/ordinary-people.ts new file mode 100644 index 0000000..b26a550 --- /dev/null +++ b/mappafront/src/models/ordinary-people.ts @@ -0,0 +1,40 @@ +export type OrdinaryPageRequestBody = { + pageSize: number; + pageNumber: number; + filter?: { + name?: string; + religion?: number[]; + ethnicity?: number[]; + profession?: number[]; + location?: number[]; + sources?: number[]; + gender?: number[]; + interactionsWithUnordinary?: number[]; + }; +}; + +export type SubObjectPair = { + id: number; + name: string; +}; + +export type OrdinaryPageResponseDataItem = { + id: number; + name: string; + alternateName?: string; + ethnicity?: SubObjectPair; + gender?: SubObjectPair; + location?: SubObjectPair; + profession?: SubObjectPair; + religion?: SubObjectPair; + sources: SubObjectPair[]; + interactionsWithUnordinary: SubObjectPair[]; +}; + +export type OrdinaryPageResponseData = { + pageSize: number; + pageNumber: number; + totalCount: number; + totalPages: number; + data: OrdinaryPageResponseDataItem[]; +}; diff --git a/mappafront/src/views/components/modal/index.tsx b/mappafront/src/views/components/modal/index.tsx new file mode 100644 index 0000000..ca11406 --- /dev/null +++ b/mappafront/src/views/components/modal/index.tsx @@ -0,0 +1,66 @@ +import ReactModal from "react-modal"; + +import "./style.scss"; +import Text from "../text"; +import Button from "../button"; + +interface MappaModalProps { + isOpen: boolean; + closeModal: () => void; + data?: { [key: string]: any }; +} + +const MappaModal = ({ isOpen, closeModal, data }: MappaModalProps) => { + return ( + +
+ {/* Kapatma Butonu */} + + + {/* Başlık */} + + Overview + + +
+ + {data?.name || "No Name Provided"} + + +
+ {data && Object.keys(data).length > 0 ? ( + Object.keys(data).map((key, index) => ( +
+ + {key} + + + {typeof data[key] === "object" + ? JSON.stringify(data[key]) + : data[key]?.toString() || "-"}{" "} + +
+ )) + ) : ( + + No data available + + )} +
+
+
+
+ ); +}; + +export default MappaModal; diff --git a/mappafront/src/views/components/modal/style.scss b/mappafront/src/views/components/modal/style.scss new file mode 100644 index 0000000..e43362a --- /dev/null +++ b/mappafront/src/views/components/modal/style.scss @@ -0,0 +1,57 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +.custom-mappa-modal { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: white; + width: 9.5rem; + max-width: 100%; + height: 75%; + max-height: 90vh; + overflow-y: auto; + border-radius: 0px !important; + box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2); + border: 8px solid $color-primary; + z-index: 10001 !important; + background-color: $color-secondary; +} +div.modal-content { + display: flex; + flex-direction: column; + + .modal-close-button { + position: fixed; + right: 0.2rem; + top: 0.2rem; + background-color: transparent; + border: none; + } + + div.content { + padding: 0.6rem 1rem; + + .content-info { + .info-row { + padding-top: 0.32rem; + gap: 0.64rem; + + .data-field { + width: 50%; + text-transform: capitalize; + } + .data { + width: 50%; + } + + width: 100%; + display: flex; + flex-direction: row; + + align-items: center; + } + } + } +} diff --git a/mappafront/src/views/components/table/index.tsx b/mappafront/src/views/components/table/index.tsx index 7f0d866..491f403 100644 --- a/mappafront/src/views/components/table/index.tsx +++ b/mappafront/src/views/components/table/index.tsx @@ -1,44 +1,17 @@ -import Text from "../text"; +import TableData, { TableDataProps } from "./table-data"; +import TablePagination, { TablePaginationProps } from "./table-pagination"; import "./style.scss"; -interface TableData { - [key: string]: any; -} - interface TableProps { - headers: string[]; - data: TableData[]; + tableData: TableDataProps; + paginationData?: TablePaginationProps; } -const Table = ({ headers, data }: TableProps) => { +const Table = ({ tableData, paginationData }: TableProps) => { return (
- - - - {headers.map((item: string) => ( - - ))} - - - - {data.map((item, index) => ( - - {Object.keys(item).map((itemKey, subIndex) => ( - - ))} - - ))} - -
- - {item} - -
- - {item[itemKey]} - -
+ + {paginationData && }
); }; diff --git a/mappafront/src/views/components/table/style.scss b/mappafront/src/views/components/table/style.scss index 95c1848..862dcbd 100644 --- a/mappafront/src/views/components/table/style.scss +++ b/mappafront/src/views/components/table/style.scss @@ -2,54 +2,8 @@ @use "@/assets/variables.scss" as *; .table-container { - width: 100%; - height: 100%; - overflow-x: auto; - - table.table { - width: 100%; - border-collapse: collapse; - border-style: hidden; - - thead { - overflow: hidden; - - tr.table-header { - height: 0.3rem; - - th.header-item { - text-align: start; - padding: 0.2rem; - } - - th.header-item:first-child { - border-top-left-radius: 15px; - } - - th.header-item:last-child { - border-top-right-radius: 15px; - } - } - } - - tbody { - tr.table-row { - td.row-item { - padding: 0.2rem; - text-align: start; - border-bottom: 1px solid #ddd; - } - &:nth-child(odd) { - background-color: white; - } - &:nth-child(even) { - background-color: whitesmoke; - } - - &:last-child td { - border-bottom: none; - } - } - } - } + padding: 0.84rem 1.92rem; + display: flex; + flex-direction: column; + align-items: center; } diff --git a/mappafront/src/views/components/table/table-data/index.tsx b/mappafront/src/views/components/table/table-data/index.tsx new file mode 100644 index 0000000..2bab84a --- /dev/null +++ b/mappafront/src/views/components/table/table-data/index.tsx @@ -0,0 +1,60 @@ +import { ReactNode } from "react"; +import Text from "../../text"; +import "./style.scss"; + +export type TableDataProps = { + headers: ReactNode[]; + rows?: { cells: ReactNode[]; onClick?: () => void }[]; + hasRowHover?: boolean; +}; + +const TableData = ({ headers, rows, hasRowHover }: TableDataProps) => { + return ( + + + + {headers.map((header, index) => ( + + ))} + + + + + {rows && rows.length > 0 ? ( + rows.map((row, rowIndex) => ( + + {row.cells.map((cell, index) => ( + + ))} + + )) + ) : ( + + + + )} + +
+ {/* */} + {header} + {/* */} +
+ {cell} + {/* + {typeof row[key] === "object" && row[key] !== null + ? JSON.stringify(row[key]) + : row[key]?.toString() || "-"}{" "} + */} +
+ + There is no such data + +
+ ); +}; + +export default TableData; diff --git a/mappafront/src/views/components/table/table-data/style.scss b/mappafront/src/views/components/table/table-data/style.scss new file mode 100644 index 0000000..daf00e2 --- /dev/null +++ b/mappafront/src/views/components/table/table-data/style.scss @@ -0,0 +1,46 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +table.table { + width: 100%; + border: 3px solid $color-primary; + margin-bottom: 0.28rem; + border-collapse: collapse; + + .table-header { + width: 100%; + + .table-columns { + display: flex; + flex-direction: row; + align-items: center; + padding: 0.14rem 0.32rem; + gap: 0.32rem; + border-bottom: 1px solid $color-primary; + + .table-column { + width: 0.62rem; + display: table-cell; + text-align: center; + } + } + } + + .table-body { + .data-row { + display: flex; + flex-direction: row; + border-bottom: 1px solid $color-primary; + padding: 0.32rem; + gap: 0.32rem; + + .data-row-item { + width: 0.62rem; + white-space: nowrap; + text-align: center; + text-overflow: ellipsis; + overflow: hidden; + } + } + } +} diff --git a/mappafront/src/views/components/table/table-pagination/index.tsx b/mappafront/src/views/components/table/table-pagination/index.tsx new file mode 100644 index 0000000..35d37bc --- /dev/null +++ b/mappafront/src/views/components/table/table-pagination/index.tsx @@ -0,0 +1,95 @@ +import arrowForward from "@/assets/icons/arrow-forward.svg"; +import "./style.scss"; + +export type TablePaginationProps = { + currentPage: number; + totalPage: number; + setPage: (page: number) => void; +}; + +const TablePagination = ({ + currentPage, + totalPage, + setPage, +}: TablePaginationProps) => { + const generatePageNumbers = (): (number | string)[] => { + const maxVisiblePages = 5; + let pages: (number | string)[] = []; + + if (totalPage <= maxVisiblePages) { + // Sayfa sayısı 5 veya daha azsa hepsini göster + return Array.from({ length: totalPage }, (_, i) => i + 1); + } + + if (currentPage < 4) { + // Kullanıcı ilk sayfalardaysa + pages = [1, 2, 3, 4, "...", totalPage]; + } else if (currentPage > totalPage - 3) { + // Kullanıcı son sayfalardaysa + pages = [ + 1, + "...", + totalPage - 3, + totalPage - 2, + totalPage - 1, + totalPage, + ]; + } else { + // Kullanıcı ortadaysa + pages = [ + 1, + "...", + currentPage - 1, + currentPage, + currentPage + 1, + "...", + totalPage, + ]; + } + + return pages; + }; + + const pageNumbers: (number | string)[] = generatePageNumbers(); + + return ( + + ); +}; + +export default TablePagination; diff --git a/mappafront/src/views/components/table/table-pagination/style.scss b/mappafront/src/views/components/table/table-pagination/style.scss new file mode 100644 index 0000000..ad24394 --- /dev/null +++ b/mappafront/src/views/components/table/table-pagination/style.scss @@ -0,0 +1,88 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +.pagination { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + background: #fdf9f2; + padding: 10px; + + button { + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + border: 2px solid #a33d30; + background: #fff8f0; + color: #a33d30; + font-size: 18px; + font-weight: bold; + cursor: pointer; + transition: all 0.3s; + + &:hover { + background: #f5e5d8; + } + + &.active { + background: #a33d30; + color: white; + } + + &.prev, + &.next { + background: #a33d30; + color: white; + border: none; + font-size: 22px; + } + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + } + } +} +.pagination { + button { + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 40px; + border: 1px solid $color-primary; + background: #fff8f0; + + &:hover { + background: #f5e5d8; + } + + &.active { + background: $color-primary; + color: white; + } + + &.prev { + background: $color-primary; + transform: rotate(180deg); + } + + &.next { + background: $color-primary; + border: none; + } + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + } + } + + .dots { + border: none; + pointer-events: none; + } +} diff --git a/mappafront/src/views/layout/header/index.tsx b/mappafront/src/views/layout/header/index.tsx index a6d9830..a5316e8 100644 --- a/mappafront/src/views/layout/header/index.tsx +++ b/mappafront/src/views/layout/header/index.tsx @@ -2,7 +2,6 @@ import MappaLogo from "@/assets/images/mappa-logo.png"; import searchIcon from "@/assets/icons/search.svg"; import { Urls } from "@/routers/routes"; import { NavLink } from "react-router-dom"; -import Button from "@/views/components/button"; import "./style.scss"; import Text from "@/views/components/text"; @@ -19,7 +18,7 @@ const Header = () => { - + {/* */}