forked from Abdulbari/sgeUpdated
Compare commits
211 Commits
multi-emis
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 47f06688e0 | |||
| a0ec570147 | |||
| 7696d0f133 | |||
| e67dcea72e | |||
| 7a948f3b7e | |||
| 49ce97d394 | |||
| a7ba6fe3e4 | |||
| 7976d56552 | |||
| e3536ea6a3 | |||
| 66aeed7fda | |||
| fcc5edcbe2 | |||
| 8f41ce3d51 | |||
|
|
4ea1cfa9b4 | ||
| 68835f5919 | |||
| ee29ecd766 | |||
| f4dd4a9dce | |||
| 853230e742 | |||
| 0a4462923e | |||
| 7f56158c02 | |||
| 1174707918 | |||
| 93cad886d6 | |||
| a15f249016 | |||
| 5c1f255c3f | |||
| 453d35702c | |||
| cf08be1ddc | |||
| 4a9b65cc30 | |||
| 472a5daf09 | |||
| dcdc1bf43a | |||
| c9b5ebf80e | |||
| caa0549983 | |||
| 4400572a45 | |||
| 04ee05a96b | |||
| 7580bf7cdb | |||
| 0d017c0a4b | |||
| 1eeb91c91c | |||
| cd18444b08 | |||
| 1354d01878 | |||
| 9856c1f9aa | |||
| b1ea7bf736 | |||
| 8b82b44591 | |||
| 5c534314df | |||
| dde5fece3b | |||
| f3b893f05c | |||
| 08e8badae2 | |||
| dd1083db82 | |||
| fad8037371 | |||
| 61faf1bf46 | |||
| 230c4bcb6e | |||
| cbe2660080 | |||
| cf38f431a8 | |||
| f585763563 | |||
| 7bee15a901 | |||
| 1ae3d76781 | |||
| 53d5bf2e77 | |||
| 60e50dc9e8 | |||
| aaf116ca71 | |||
| 061c0cb376 | |||
| bd155fadb2 | |||
| 11541714f5 | |||
| 91559134cd | |||
| d26ca12e0c | |||
| 18c8c49a3d | |||
| 97253a54eb | |||
| f411f44006 | |||
| f4f4fb976b | |||
| 385eda2132 | |||
| 23a3d8252e | |||
| eeda227698 | |||
| 871bcf9651 | |||
| 614cbe8b04 | |||
| ce19adb1a0 | |||
| 5471db463f | |||
| 845417ee49 | |||
| 1c12ac1e16 | |||
| eb2ec01d28 | |||
| 4d40015fd1 | |||
| c55f5ce7d1 | |||
| 07a8973b92 | |||
| 54b47eee05 | |||
| 3f0550f9f2 | |||
| 6499c9471e | |||
| 71e507c21b | |||
| 737fd6da53 | |||
| 490f3b539e | |||
| 9c0c4c4828 | |||
| b28a73b4ff | |||
| f087b6eb88 | |||
| d07932cc1e | |||
| 76d37d6038 | |||
| 50abcab358 | |||
| 445f9256a1 | |||
| 4d1a82fe92 | |||
| 6d6e935b52 | |||
| a51a81ce7c | |||
| 3b6000bc40 | |||
| 78ed73acc6 | |||
| 7f8a7b1bf8 | |||
| 8c6e37ad72 | |||
| 85151e536d | |||
| 573db7fee9 | |||
| a11f9614ed | |||
| 02bd570573 | |||
| 5da26152a9 | |||
| 4f4c2e2ce5 | |||
| 79ddbf2207 | |||
| 23d9e65a7f | |||
| c8f9abe5e9 | |||
| fa96969bc7 | |||
| dc67f75027 | |||
| e22c880673 | |||
| b37ed8797b | |||
| 04ed88e45e | |||
| 5f8de8105b | |||
| 8fb923a4db | |||
| a088889a67 | |||
| b3de688265 | |||
| 080924f788 | |||
| e43199f086 | |||
| 49e2020455 | |||
| 876227286c | |||
| af518cef20 | |||
| 2e5bf41ed9 | |||
| f61199cedb | |||
| 5001a44406 | |||
| 87487510ce | |||
| 547ade53ae | |||
| 95afe7b877 | |||
| ae0e112572 | |||
| b35eac74a1 | |||
| 20aabd605c | |||
| 517d4d499b | |||
| 1aa745ebf5 | |||
| 88a312d37c | |||
| b1019b21cf | |||
| 57c28e4a90 | |||
| b1cf711420 | |||
| 1d6b026710 | |||
| 02e4993c2c | |||
| be71b59a3e | |||
| 7e5761993b | |||
| 66bd7b5a68 | |||
| 206d8a2bbf | |||
| 6fbca1c29a | |||
| 1f6b06260c | |||
| b00a8e1bf1 | |||
| 0f01ddefe9 | |||
| 2116b0f28a | |||
| 5161286279 | |||
| 29963d5388 | |||
| 990b98c171 | |||
| f2d5182215 | |||
| e9a361489e | |||
| 37873ad091 | |||
| cac67b815c | |||
| 28fc21e9f2 | |||
| 98a2515735 | |||
| 4503d7c319 | |||
| e2a1b6f940 | |||
| d25a7975c7 | |||
| 926c6b0b66 | |||
| 986bec559b | |||
| 77d5c94cf7 | |||
| 75c2f7ff19 | |||
| 55577469de | |||
| f50803f469 | |||
| adce8cddd8 | |||
| c2ddc08802 | |||
| 2c79300663 | |||
| a6bb799caa | |||
| a4791d6a57 | |||
| 168cfaa8a7 | |||
| 710655c1fd | |||
| 6f445f205a | |||
| 32b9533a33 | |||
| 62829194e2 | |||
| 87a80f63ed | |||
| f12c5cb8d4 | |||
| 7148bdf834 | |||
| 9eb903a450 | |||
| 991aef0417 | |||
| a1c0f71fbf | |||
| 64c36cb617 | |||
| 0f2bf5a800 | |||
| d6375c320a | |||
| 3d440798e3 | |||
| 8cdc00f921 | |||
| 593e5ceb6a | |||
| b2eebfce64 | |||
| c3ed359103 | |||
| 7b4143ba52 | |||
| 0322235404 | |||
| 95a344a7a6 | |||
| c477143b30 | |||
| 6202f7ec26 | |||
| 8eb9835e13 | |||
| 08941cc7d5 | |||
| 994e81b1fb | |||
| 0c03a110e5 | |||
| 7c5eb3a210 | |||
| a943925325 | |||
| 5bd98fb09d | |||
| cdb6d98ae7 | |||
| 243f89457f | |||
| 03875dde53 | |||
| e695d06f5b | |||
| 837353bc45 | |||
| 2459ba092b | |||
| 4bfd2ee1f8 | |||
| 95fbbc340e | |||
| 78ffa4fe7e | |||
| 3245040274 |
29
.gitea/workflows/sgeupdated.yml
Normal file
29
.gitea/workflows/sgeupdated.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
name: sgeUpdated CI/CD
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed # Fires when a PR is closed (either merged or manually closed)
|
||||
branches:
|
||||
- main # Only when PR targets main
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.event.pull_request.merged == true # Run only if the PR was merged (not just closed)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Setup SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh/
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
|
||||
|
||||
- name: Run deploy script on server
|
||||
run: |
|
||||
ssh ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << 'EOF'
|
||||
echo "✅ PR merged into main — running deploy script..."
|
||||
cd /home/ubuntu/Bgreen/sgeUpdated
|
||||
./deploy.sh
|
||||
EOF
|
||||
24
config.conf
Normal file
24
config.conf
Normal file
@@ -0,0 +1,24 @@
|
||||
# SGE Application Configuration
|
||||
# This file contains configuration for both backend and frontend
|
||||
|
||||
# Database Configuration
|
||||
SPRING_DATASOURCE_URL=jdbc:postgresql://bgreen-database:5432/sge
|
||||
SPRING_DATASOURCE_USERNAME=sge
|
||||
SPRING_DATASOURCE_PASSWORD=147
|
||||
|
||||
# Server Configuration
|
||||
SERVER_PORT=8080
|
||||
|
||||
# Mail Configuration
|
||||
MAIL_HOSTNAME=mail.spacemail.com
|
||||
MAIL_SMTP_PORT=465
|
||||
MAIL_ADDRESS=info@blc-css.com
|
||||
MAIL_PASSWORD=123456Bb@
|
||||
|
||||
# React Application Configuration
|
||||
# API Configuration
|
||||
API_PROTOCOL=http
|
||||
API_HOST=bgreen-backend
|
||||
|
||||
# Application URLs
|
||||
APP_SURVEY_BASE_URL=https://bgreen.blc-css.com
|
||||
110
deploy.sh
Executable file
110
deploy.sh
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
cd /home/ubuntu/Bgreen/sgeUpdated
|
||||
|
||||
# -----------------------
|
||||
# Harbor settings
|
||||
# -----------------------
|
||||
HARBOR_REGISTRY="10.150.1.166"
|
||||
HARBOR_PROJECT="bgreen"
|
||||
|
||||
BACKEND_IMAGE_REPO="${HARBOR_REGISTRY}/${HARBOR_PROJECT}/bgreen-backend"
|
||||
FRONTEND_IMAGE_REPO="${HARBOR_REGISTRY}/${HARBOR_PROJECT}/bgreen-frontend"
|
||||
|
||||
# Tag images with git commit (better than latest; enables rollback)
|
||||
VERSION="$(git rev-parse --short HEAD)"
|
||||
|
||||
echo "📦 Fetching latest changes from origin/main..."
|
||||
git fetch myfork main
|
||||
|
||||
# Detect which files changed between local HEAD and the latest remote version
|
||||
CHANGED_FILES=$(git diff --name-only HEAD myfork/main || true)
|
||||
|
||||
if [ -z "$CHANGED_FILES" ]; then
|
||||
echo "✅ No file changes detected between HEAD and origin/main."
|
||||
else
|
||||
echo "🪶 Changed files:"
|
||||
echo "$CHANGED_FILES"
|
||||
fi
|
||||
|
||||
# Update to the latest version
|
||||
git reset --hard myfork/main
|
||||
|
||||
BACKEND_CHANGED=false
|
||||
FRONTEND_CHANGED=false
|
||||
|
||||
# Check if backend folder changed (excluding README.md)
|
||||
if echo "$CHANGED_FILES" | grep "^sge-backend/" | grep -qv "README.md$"; then
|
||||
BACKEND_CHANGED=true
|
||||
fi
|
||||
|
||||
# Check if frontend folder changed (excluding README.md)
|
||||
if echo "$CHANGED_FILES" | grep "^sge-frontend/" | grep -qv "README.md$"; then
|
||||
FRONTEND_CHANGED=true
|
||||
fi
|
||||
|
||||
# -----------------------
|
||||
# Backend section
|
||||
# -----------------------
|
||||
if [ "$BACKEND_CHANGED" = true ]; then
|
||||
echo "⚡ Backend changes detected."
|
||||
|
||||
cd sge-backend
|
||||
echo "Running Maven build..."
|
||||
/opt/apache-maven-3.9.11/bin/mvn clean install -DskipTests
|
||||
|
||||
echo "🐳 Building backend Docker image..."
|
||||
docker build -t "${BACKEND_IMAGE_REPO}:${VERSION}" .
|
||||
|
||||
echo "📤 Pushing backend image to Harbor..."
|
||||
docker push "${BACKEND_IMAGE_REPO}:${VERSION}"
|
||||
|
||||
echo "📥 Pulling backend image from Harbor (to ensure registry is source of truth)..."
|
||||
docker pull "${BACKEND_IMAGE_REPO}:${VERSION}"
|
||||
|
||||
cd ..
|
||||
|
||||
echo "🚀 Recreating backend container using Harbor image..."
|
||||
VERSION="$VERSION" docker compose up -d bgreen-backend
|
||||
|
||||
else
|
||||
echo "✅ No backend changes."
|
||||
fi
|
||||
|
||||
# -----------------------
|
||||
# Frontend section
|
||||
# -----------------------
|
||||
if [ "$FRONTEND_CHANGED" = true ]; then
|
||||
echo "⚡ Frontend changes detected."
|
||||
cd sge-frontend
|
||||
|
||||
# Check if package.json or package-lock.json changed
|
||||
if echo "$CHANGED_FILES" | grep -qE "^sge-frontend/(package\.json|package-lock\.json)$"; then
|
||||
echo "📦 package.json changed. Running 'npm install' and 'npm run build'..."
|
||||
npm install
|
||||
npm run build
|
||||
else
|
||||
echo "📦 only code changes. Running 'npm run build'..."
|
||||
npm run build
|
||||
fi
|
||||
|
||||
echo "🐳 Building frontend Docker image..."
|
||||
docker build -t "${FRONTEND_IMAGE_REPO}:${VERSION}" .
|
||||
|
||||
echo "📤 Pushing frontend image to Harbor..."
|
||||
docker push "${FRONTEND_IMAGE_REPO}:${VERSION}"
|
||||
|
||||
echo "📥 Pulling frontend image from Harbor (to ensure registry is source of truth)..."
|
||||
docker pull "${FRONTEND_IMAGE_REPO}:${VERSION}"
|
||||
|
||||
cd ..
|
||||
|
||||
echo "🚀 Recreating frontend container using Harbor image..."
|
||||
VERSION="$VERSION" docker compose up -d bgreen-frontend
|
||||
|
||||
else
|
||||
echo "✅ No frontend changes."
|
||||
fi
|
||||
|
||||
echo "✅ Deployment complete."
|
||||
69
deploy.sh.save
Executable file
69
deploy.sh.save
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
export GIT_SSH_COMMAND="ssh -i ~/.ssh/deploy_id_rsa -o StrictHostKeyC
|
||||
|
||||
cd /home/ubuntu/Bgreen/sgeUpdated
|
||||
|
||||
echo "📦 Fetching latest changes from origin/main..."
|
||||
git fetch origin main
|
||||
|
||||
# Detect which files changed between local HEAD and the latest remote version
|
||||
CHANGED_FILES=$(git diff --name-only HEAD origin/main || true)
|
||||
|
||||
if [ -z "$CHANGED_FILES" ]; then
|
||||
echo "✅ No file changes detected between HEAD and origin/main."
|
||||
else
|
||||
echo "🪶 Changed files:"
|
||||
echo "$CHANGED_FILES"
|
||||
fi
|
||||
|
||||
# Update to the latest version
|
||||
git reset --hard origin/main
|
||||
|
||||
BACKEND_CHANGED=false
|
||||
FRONTEND_CHANGED=false
|
||||
|
||||
# Check if backend folder changed
|
||||
if echo "$CHANGED_FILES" | grep -q "^sge-backend/"; then
|
||||
BACKEND_CHANGED=true
|
||||
fi
|
||||
|
||||
# Check if frontend folder changed
|
||||
if echo "$CHANGED_FILES" | grep -q "^sge-frontend/"; then
|
||||
FRONTEND_CHANGED=true
|
||||
fi
|
||||
|
||||
# -----------------------
|
||||
# Backend section
|
||||
# -----------------------
|
||||
if [ "$BACKEND_CHANGED" = true ]; then
|
||||
echo "⚡ Backend changes detected."
|
||||
cd sge-backend
|
||||
echo "Running Maven build..."
|
||||
/opt/apache-maven-3.9.11/bin/mvn clean install -DskipTests
|
||||
cd ..
|
||||
echo "Rebuilding backend Docker container..."
|
||||
docker compose up -d --build bgreen-backend
|
||||
else
|
||||
echo "✅ No backend changes."
|
||||
fi
|
||||
|
||||
# -----------------------
|
||||
# Frontend section
|
||||
# -----------------------
|
||||
if [ "$FRONTEND_CHANGED" = true ]; then
|
||||
echo "⚡ Frontend changes detected."
|
||||
cd sge-frontend
|
||||
echo "Running npm build..."
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
echo "Rebuilding frontend Docker container..."
|
||||
docker compose up -d --build bgreen-frontend
|
||||
else
|
||||
echo "✅ No frontend changes."
|
||||
fi
|
||||
|
||||
echo "✅ Deployment complete."
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./sge-backend
|
||||
dockerfile: Dockerfile
|
||||
bgreen-backend:
|
||||
image: 10.150.1.166/bgreen/bgreen-backend:${VERSION}
|
||||
ports:
|
||||
- "8080:8080"
|
||||
env_file:
|
||||
@@ -13,10 +11,8 @@ services:
|
||||
- database
|
||||
restart: unless-stopped
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./sge-frontend
|
||||
dockerfile: Dockerfile
|
||||
bgreen-frontend:
|
||||
image: 10.150.1.166/bgreen/bgreen-frontend:${VERSION}
|
||||
ports:
|
||||
- "80:80"
|
||||
env_file:
|
||||
|
||||
1
sge-backend/README.md
Normal file
1
sge-backend/README.md
Normal file
@@ -0,0 +1 @@
|
||||
## CI/CD Pipeline Check v23
|
||||
@@ -6,12 +6,12 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.5.4</version>
|
||||
<version>2.5.5</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<groupId>com.sgs</groupId>
|
||||
<artifactId>sgs</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>0.0.4-SNAPSHOT</version>
|
||||
<name>sgs</name>
|
||||
<description>SGS project for Spring Boot</description>
|
||||
<properties>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,104 +1,108 @@
|
||||
# SGE System Frontend
|
||||
|
||||
## Overview
|
||||
|
||||
The frontend of the SGE System is a modern web application built with **React**, providing an interactive and user-friendly interface. It communicates with the backend API to deliver a seamless experience for users.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **React** – UI library
|
||||
- **React Router** – Routing
|
||||
- **i18n** – Internationalization
|
||||
- **Docker** – Containerization
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
SGE/
|
||||
├── sge-backend/ # Backend source code
|
||||
├── sge-frontend/ # Frontend source code
|
||||
├── config.conf # Centralized configuration file (see below)
|
||||
├── docker-compose.yml # Docker Compose file (see below)
|
||||
```
|
||||
|
||||
## Setup and Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** (v14.0.0 required) and npm
|
||||
- **Docker** (for containerized deployment)
|
||||
|
||||
#### Node.js Version Management
|
||||
|
||||
If you need to switch Node versions, use nvm:
|
||||
|
||||
```sh
|
||||
nvm install v14.0.0
|
||||
nvm use v14.0.0
|
||||
unset NODE_OPTIONS
|
||||
```
|
||||
|
||||
### Frontend Setup
|
||||
|
||||
#### Local Development
|
||||
|
||||
1. Clone the repository and navigate to the frontend directory:
|
||||
|
||||
```sh
|
||||
git clone <repository-url>
|
||||
cd SGE/sge-frontend
|
||||
```
|
||||
|
||||
2. Ensure `config.conf` is in the project root (`SGE/`).
|
||||
You can either:
|
||||
|
||||
- Manually set environment variables from `config.conf`
|
||||
- Or configure your IDE to load variables from `config.conf`
|
||||
|
||||
3. Install dependencies:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
4. Start the development server:
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
||||
#### Docker Deployment
|
||||
|
||||
1. Ensure both `config.conf` and `docker-compose.yml` are in the project root (`SGE/`).
|
||||
2. From the root directory, build and run the frontend (and backend) using Docker:
|
||||
```sh
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
## Configuration Management
|
||||
|
||||
The SGE System uses a centralized `config.conf` file for all environment variables.
|
||||
**Location:** Place `config.conf` in the root directory of your project, alongside `docker-compose.yml`.
|
||||
|
||||
This file contains environment variables for both backend and frontend components, including:
|
||||
|
||||
- API connection settings
|
||||
- Mail configuration
|
||||
- Application URLs
|
||||
|
||||
When running with Docker, environment variables are automatically loaded from `config.conf` via the `env_file` directive in `docker-compose.yml`.
|
||||
|
||||
For local development, you can either:
|
||||
|
||||
- Use the same `config.conf` file and manually set the environment variables
|
||||
- Configure your IDE to load these variables from the file
|
||||
|
||||
Refer to the backend README for more details on configuration options and structure.
|
||||
|
||||
## Integration with Backend
|
||||
|
||||
The frontend expects the backend API to be available at the host and port specified in `config.conf` (`API_PROTOCOL`, `API_HOST`, `SERVER_PORT`).
|
||||
Ensure both services are configured consistently.
|
||||
|
||||
## License
|
||||
|
||||
[Insert your license information here]
|
||||
# SGE System Frontend
|
||||
|
||||
## Overview
|
||||
|
||||
The frontend of the SGE System is a modern web application built with **React**, providing an interactive and user-friendly interface. It communicates with the backend API to deliver a seamless experience for users.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **React** – UI library
|
||||
- **React Router** – Routing
|
||||
- **i18n** – Internationalization
|
||||
- **Docker** – Containerization
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
SGE/
|
||||
├── sge-backend/ # Backend source code
|
||||
├── sge-frontend/ # Frontend source code
|
||||
├── config.conf # Centralized configuration file (see below)
|
||||
├── docker-compose.yml # Docker Compose file (see below)
|
||||
```
|
||||
|
||||
## Setup and Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** (v14.0.0 required) and npm
|
||||
- **Docker** (for containerized deployment)
|
||||
|
||||
#### Node.js Version Management
|
||||
|
||||
If you need to switch Node versions, use nvm:
|
||||
|
||||
```sh
|
||||
nvm install v14.0.0
|
||||
nvm use v14.0.0
|
||||
unset NODE_OPTIONS
|
||||
```
|
||||
|
||||
### Frontend Setup
|
||||
|
||||
#### Local Development
|
||||
|
||||
1. Clone the repository and navigate to the frontend directory:
|
||||
|
||||
```sh
|
||||
git clone <repository-url>
|
||||
cd SGE/sge-frontend
|
||||
```
|
||||
|
||||
2. Ensure `config.conf` is in the project root (`SGE/`).
|
||||
You can either:
|
||||
|
||||
- Manually set environment variables from `config.conf`
|
||||
- Or configure your IDE to load variables from `config.conf`
|
||||
|
||||
3. Install dependencies:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
4. Start the development server:
|
||||
```sh
|
||||
npm start
|
||||
```
|
||||
|
||||
#### Docker Deployment
|
||||
|
||||
1. Ensure both `config.conf` and `docker-compose.yml` are in the project root (`SGE/`).
|
||||
2. From the root directory, build and run the frontend (and backend) using Docker:
|
||||
```sh
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
## Configuration Management
|
||||
|
||||
The SGE System uses a centralized `config.conf` file for all environment variables.
|
||||
**Location:** Place `config.conf` in the root directory of your project, alongside `docker-compose.yml`.
|
||||
|
||||
This file contains environment variables for both backend and frontend components, including:
|
||||
|
||||
- API connection settings
|
||||
- Mail configuration
|
||||
- Application URLs
|
||||
|
||||
When running with Docker, environment variables are automatically loaded from `config.conf` via the `env_file` directive in `docker-compose.yml`.
|
||||
|
||||
For local development, you can either:
|
||||
|
||||
- Use the same `config.conf` file and manually set the environment variables
|
||||
- Configure your IDE to load these variables from the file
|
||||
|
||||
Refer to the backend README for more details on configuration options and structure.
|
||||
|
||||
## Integration with Backend
|
||||
|
||||
The frontend expects the backend API to be available at the host and port specified in `config.conf` (`API_PROTOCOL`, `API_HOST`, `SERVER_PORT`).
|
||||
Ensure both services are configured consistently.
|
||||
|
||||
## License
|
||||
|
||||
[Insert your license information here]
|
||||
|
||||
## CI/CD Testing v20
|
||||
|
||||
|
||||
|
||||
@@ -1,39 +1,32 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name bgreen.blc-css.com;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
location /api/v1/graphql {
|
||||
proxy_pass http://bgreen-backend:8080/api/v1/graphql;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
location /api/v1/upload {
|
||||
proxy_pass http://bgreen-backend:8080/upload;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# location /api/v1/datacenter {
|
||||
# proxy_pass http://backend:8080/api/v1/datacenter;
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_set_header X-Real-IP $remote_addr;
|
||||
# }
|
||||
|
||||
# Hata durumlarında da index.html'i sun
|
||||
error_page 404 /index.html;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 10240;
|
||||
gzip_proxied any;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml application/rss+xml application/atom+xml image/svg+xml;
|
||||
gzip_comp_level 5;
|
||||
}
|
||||
}
|
||||
@@ -1,131 +1,131 @@
|
||||
{
|
||||
"name": "sgs-web",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.13.8",
|
||||
"@casl/react": "4.0.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.10.6",
|
||||
"@mui/icons-material": "^5.2.4",
|
||||
"@mui/material": "^5.2.4",
|
||||
"animate.css": "4.1.1",
|
||||
"axios": "^0.21.1",
|
||||
"bootstrap": "4.5.2",
|
||||
"chart.js": "^4.3.0",
|
||||
"chartjs-plugin-datalabels": "^2.2.0",
|
||||
"classnames": "2.2.6",
|
||||
"dotenv": "^14.3.2",
|
||||
"file-saver": "^2.0.5",
|
||||
"graphql": "^16.11.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"i18next": "^22.4.14",
|
||||
"i18next-browser-languagedetector": "^7.0.1",
|
||||
"i18next-http-backend": "^2.2.0",
|
||||
"jquery": "^3.7.1",
|
||||
"jspdf": "^2.5.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"leaflet": "^1.6.0",
|
||||
"material-react-table": "^1.14.0",
|
||||
"moment": "2.29.1",
|
||||
"notistack": "^2.0.8",
|
||||
"postcss-rtl": "1.5.0",
|
||||
"prop-types": "15.7.2",
|
||||
"react": "17.0.1",
|
||||
"react-bootstrap": "^2.10.6",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-color": "^2.19.3",
|
||||
"react-data-table-component": "^7.5.0",
|
||||
"react-datepicker": "^4.16.0",
|
||||
"react-dom": "17.0.1",
|
||||
"react-feather": "~2.0.3",
|
||||
"react-i18next": "^12.2.0",
|
||||
"react-intl": "6.0.5",
|
||||
"react-leaflet": "^3.2.5",
|
||||
"react-paginate": "8.2.0",
|
||||
"react-perfect-scrollbar": "^1.5.5",
|
||||
"react-redux": "7.2.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scroll-up": "1.3.7",
|
||||
"react-select": "4.0.2",
|
||||
"react-toastify": "^7.0.3",
|
||||
"reactstrap": "9.2.3",
|
||||
"redux": "4.0.5",
|
||||
"redux-debounced": "0.5.0",
|
||||
"redux-thunk": "2.3.0",
|
||||
"styled-components": "^5.3.6",
|
||||
"sweetalert2": "11.0.0",
|
||||
"sweetalert2-react-content": "4.2.0",
|
||||
"swiper": "6.0.4",
|
||||
"uuid": "^9.0.0",
|
||||
"web-vitals": "^1.0.1",
|
||||
"websocket": "^1.0.34",
|
||||
"wnumb": "1.2.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"yarn": "1.21.1",
|
||||
"yup": "0.32.8"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-app-rewired start",
|
||||
"build:dev": "react-app-rewired build --mode development",
|
||||
"build:prod": "react-app-rewired build --mode production",
|
||||
"build": "react-app-rewired build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"lint": "eslint src/**/*.js src/**/*.jsx",
|
||||
"lint:fix": "eslint src/**/*.js --fix"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.27.1",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/preset-env": "^7.27.1",
|
||||
"@babel/preset-react": "^7.27.1",
|
||||
"@craco/craco": "^7.1.0",
|
||||
"@swc/core": "^1.11.24",
|
||||
"@types/leaflet": "^1.7.5",
|
||||
"@types/sortablejs": "^1.10.6",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-styled-components": "^2.1.4",
|
||||
"core-js": "^3.42.0",
|
||||
"eslint": "^8.48.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-react": "^7.33.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"react-app-rewire-postcss": "^3.0.2",
|
||||
"react-app-rewired": "^2.2.1",
|
||||
"react-error-overlay": "^6.0.9",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"sass": "^1.81.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"swc-loader": "^0.2.6",
|
||||
"typescript": "^4.9.5",
|
||||
"webpack": "^5.96.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"react-error-overlay": "6.0.9"
|
||||
},
|
||||
"homepage": ""
|
||||
}
|
||||
{
|
||||
"name": "sgs-web",
|
||||
"version": "1.0.2",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.13.8",
|
||||
"@casl/react": "4.0.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.10.6",
|
||||
"@mui/icons-material": "^5.2.4",
|
||||
"@mui/material": "^5.2.4",
|
||||
"animate.css": "4.1.1",
|
||||
"axios": "^0.21.1",
|
||||
"bootstrap": "4.5.2",
|
||||
"chart.js": "^4.3.0",
|
||||
"chartjs-plugin-datalabels": "^2.2.0",
|
||||
"classnames": "2.2.6",
|
||||
"dotenv": "^14.3.2",
|
||||
"file-saver": "^2.0.5",
|
||||
"graphql": "^16.11.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"i18next": "^22.4.14",
|
||||
"i18next-browser-languagedetector": "^7.0.1",
|
||||
"i18next-http-backend": "^2.2.0",
|
||||
"jquery": "^3.7.1",
|
||||
"jspdf": "^2.5.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"leaflet": "^1.6.0",
|
||||
"material-react-table": "^1.14.0",
|
||||
"moment": "2.29.1",
|
||||
"notistack": "^2.0.8",
|
||||
"postcss-rtl": "1.5.0",
|
||||
"prop-types": "15.7.2",
|
||||
"react": "17.0.1",
|
||||
"react-bootstrap": "^2.10.6",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-color": "^2.19.3",
|
||||
"react-data-table-component": "^7.5.0",
|
||||
"react-datepicker": "^4.16.0",
|
||||
"react-dom": "17.0.1",
|
||||
"react-feather": "~2.0.3",
|
||||
"react-i18next": "^12.2.0",
|
||||
"react-intl": "6.0.5",
|
||||
"react-leaflet": "^3.2.5",
|
||||
"react-paginate": "8.2.0",
|
||||
"react-perfect-scrollbar": "^1.5.5",
|
||||
"react-redux": "7.2.2",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scroll-up": "1.3.7",
|
||||
"react-select": "4.0.2",
|
||||
"react-toastify": "^7.0.3",
|
||||
"reactstrap": "9.2.3",
|
||||
"redux": "4.0.5",
|
||||
"redux-debounced": "0.5.0",
|
||||
"redux-thunk": "2.3.0",
|
||||
"styled-components": "^5.3.6",
|
||||
"sweetalert2": "11.0.0",
|
||||
"sweetalert2-react-content": "4.2.0",
|
||||
"swiper": "6.0.4",
|
||||
"uuid": "^9.0.0",
|
||||
"web-vitals": "^1.0.1",
|
||||
"websocket": "^1.0.34",
|
||||
"wnumb": "1.2.0",
|
||||
"xlsx": "^0.18.5",
|
||||
"yarn": "1.21.1",
|
||||
"yup": "0.32.8"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-app-rewired start",
|
||||
"build:dev": "react-app-rewired build --mode development",
|
||||
"build:prod": "react-app-rewired build --mode production",
|
||||
"build": "react-app-rewired build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"lint": "eslint src/**/*.js src/**/*.jsx",
|
||||
"lint:fix": "eslint src/**/*.js --fix"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.27.1",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/preset-env": "^7.27.1",
|
||||
"@babel/preset-react": "^7.27.1",
|
||||
"@craco/craco": "^7.1.0",
|
||||
"@swc/core": "^1.11.24",
|
||||
"@types/leaflet": "^1.7.5",
|
||||
"@types/sortablejs": "^1.10.6",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-styled-components": "^2.1.4",
|
||||
"core-js": "^3.42.0",
|
||||
"eslint": "^8.48.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||
"eslint-plugin-react": "^7.33.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"react-app-rewire-postcss": "^3.0.2",
|
||||
"react-app-rewired": "^2.2.1",
|
||||
"react-error-overlay": "^6.0.9",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"sass": "^1.81.0",
|
||||
"sass-loader": "^8.0.2",
|
||||
"swc-loader": "^0.2.6",
|
||||
"typescript": "^4.9.5",
|
||||
"webpack": "^5.96.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"react-error-overlay": "6.0.9"
|
||||
},
|
||||
"homepage": ""
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,218 +1,218 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
Col,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalHeader,
|
||||
Row,
|
||||
UncontrolledTooltip, // Add UncontrolledTooltip import
|
||||
} from "reactstrap";
|
||||
import { Edit, Mail, Phone, MapPin } from "react-feather"; // Import Mail, Phone, MapPin
|
||||
|
||||
import { useSnackbar } from "notistack";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { permissionCheck } from "../components/permission-check";
|
||||
import {
|
||||
getMailSettings,
|
||||
clearMailSuccess,
|
||||
clearMailError,
|
||||
} from "../redux/actions/mailSettings";
|
||||
import MailSettings from "./MailSettings";
|
||||
import SpinnerComponent from "../@core/components/spinner/Fallback-spinner";
|
||||
|
||||
// Import custom styles for the communication page
|
||||
import "../assets/scss/pages/communication.scss";
|
||||
|
||||
function Communication() {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const { currentSettings, loading, success, error } = useSelector(
|
||||
// Add loading to useSelector
|
||||
(state) => state.mailSettings
|
||||
);
|
||||
const [showMailModal, setShowMailModal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Load mail settings once when component mounts
|
||||
dispatch(getMailSettings());
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (success) {
|
||||
enqueueSnackbar(t("Warnings.updatedSuccessfully"), {
|
||||
variant: "success",
|
||||
});
|
||||
dispatch(clearMailSuccess());
|
||||
}
|
||||
}, [success, enqueueSnackbar, t, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
const errorMessage =
|
||||
error?.graphQLErrors?.[0]?.message ||
|
||||
error?.message ||
|
||||
t("Warnings.genericUpdateFailed");
|
||||
|
||||
enqueueSnackbar(errorMessage, {
|
||||
variant: "error",
|
||||
});
|
||||
dispatch(clearMailError());
|
||||
}
|
||||
}, [error, enqueueSnackbar, t, dispatch]);
|
||||
|
||||
// Get email address from settings or use default from environment variable
|
||||
const defaultEmail = process.env.REACT_APP_DEFAULT_EMAIL || "";
|
||||
// Use default email if currentSettings is null or emailAddress is null
|
||||
const emailAddress = currentSettings?.emailAddress || defaultEmail;
|
||||
const handleEmailClick = () => {
|
||||
if (emailAddress) {
|
||||
window.location.href = `mailto:${emailAddress}`;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setShowMailModal(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ marginTop: "2%" }}>
|
||||
{loading && !currentSettings ? (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
minHeight: 200,
|
||||
}}
|
||||
>
|
||||
<SpinnerComponent />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{permissionCheck("settings_access") && (
|
||||
<>
|
||||
<Modal
|
||||
isOpen={showMailModal}
|
||||
toggle={handleCloseModal}
|
||||
className="modal-dialog-centered"
|
||||
size="lg"
|
||||
>
|
||||
<ModalHeader toggle={handleCloseModal}>
|
||||
{t("MailSettings.editMailInfo")}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<MailSettings closeModal={handleCloseModal} />
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
</>
|
||||
)}
|
||||
<Card className="border-bottom">
|
||||
<CardHeader className="border-bottom">
|
||||
<CardTitle tag="h2" className="row ml-md-2 align-items-center">
|
||||
{t("Contact.contactInfo")}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<Row>
|
||||
<Col className="pl-md-5 pl-2 col-md-6 col-12">
|
||||
<Row className="mx-0 mt-1">
|
||||
<Col sm="6" md="5" className="mr-2">
|
||||
<div className="email-container d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h4>
|
||||
<Mail size={16} className="mr-1" />{" "}
|
||||
{t("Contact.contactEmail")}
|
||||
</h4>{" "}
|
||||
{/* Add Mail icon */}
|
||||
<p
|
||||
style={{
|
||||
color: emailAddress ? "blue" : "inherit",
|
||||
textDecoration: emailAddress ? "underline" : "none",
|
||||
cursor: emailAddress ? "pointer" : "default",
|
||||
}}
|
||||
onClick={handleEmailClick}
|
||||
>
|
||||
{emailAddress ||
|
||||
defaultEmail ||
|
||||
t("MailSettings.notConfigured")}
|
||||
</p>
|
||||
</div>
|
||||
{permissionCheck("settings_access") && (
|
||||
<>
|
||||
{" "}
|
||||
{/* Wrap button and tooltip in fragment */}
|
||||
<Button
|
||||
color="flat-primary"
|
||||
className="btn-icon"
|
||||
onClick={() => setShowMailModal(true)}
|
||||
id="edit-email-btn" // Add id for tooltip
|
||||
>
|
||||
<Edit size={18} />
|
||||
</Button>
|
||||
<UncontrolledTooltip
|
||||
placement="top"
|
||||
target="edit-email-btn" // Target the button id
|
||||
timeout={150} // Add timeout prop to fix the warning
|
||||
>
|
||||
{t("MailSettings.editMailInfo")}{" "}
|
||||
{/* Tooltip text */}
|
||||
</UncontrolledTooltip>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Col>
|
||||
<Col sm="6" md="5" className="mr-2">
|
||||
<div className="telephone-container">
|
||||
<h4>
|
||||
<Phone size={16} className="mr-1" />{" "}
|
||||
{t("Contact.contactPhoneNumber")}
|
||||
</h4>{" "}
|
||||
{/* Add Phone icon */}
|
||||
<p>+90 507 750 00 41</p>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="mx-0 mt-4">
|
||||
<Col sm="6" md="5" className="mr-2">
|
||||
<div className="address-container">
|
||||
<h4>
|
||||
<MapPin size={16} className="mr-1" />{" "}
|
||||
{t("Contact.contactAddress")}
|
||||
</h4>{" "}
|
||||
{/* Add MapPin icon */}
|
||||
<address>
|
||||
Central Office: 4995 sokak no:3, Alacaatlı Mahallesi,
|
||||
Daire No: A2 06810 Çankaya/Ankara
|
||||
</address>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col className="pl-md-5 pl-2 col-md-6 col-12 pb-2 border-left">
|
||||
<Row className="mx-0 mt-1">
|
||||
<div className="address-map w-100">
|
||||
<div className="responsive-map-container">
|
||||
<iframe
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3063.1752741150003!2d32.658217075858445!3d39.847904971536735!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x14d33eef6ee44755%3A0x77faea5f08f32c60!2zTUVBIEfDnFpFTEJBSMOHRU0!5e0!3m2!1sen!2str!4v1741165773414!5m2!1sen!2str"
|
||||
allowFullScreen=""
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Communication;
|
||||
import React, { useEffect, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
Col,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalHeader,
|
||||
Row,
|
||||
UncontrolledTooltip, // Add UncontrolledTooltip import
|
||||
} from "reactstrap";
|
||||
import { Edit, Mail, Phone, MapPin } from "react-feather"; // Import Mail, Phone, MapPin
|
||||
|
||||
import { useSnackbar } from "notistack";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { permissionCheck } from "../components/permission-check";
|
||||
import {
|
||||
getMailSettings,
|
||||
clearMailSuccess,
|
||||
clearMailError,
|
||||
} from "../redux/actions/mailSettings";
|
||||
import MailSettings from "./MailSettings";
|
||||
import SpinnerComponent from "../@core/components/spinner/Fallback-spinner";
|
||||
|
||||
// Import custom styles for the communication page
|
||||
import "../assets/scss/pages/communication.scss";
|
||||
|
||||
function Communication() {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useDispatch();
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const { currentSettings, loading, success, error } = useSelector(
|
||||
// Add loading to useSelector
|
||||
(state) => state.mailSettings
|
||||
);
|
||||
const [showMailModal, setShowMailModal] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Load mail settings once when component mounts
|
||||
dispatch(getMailSettings());
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (success) {
|
||||
enqueueSnackbar(t("Warnings.updatedSuccessfully"), {
|
||||
variant: "success",
|
||||
});
|
||||
dispatch(clearMailSuccess());
|
||||
}
|
||||
}, [success, enqueueSnackbar, t, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
const errorMessage =
|
||||
error?.graphQLErrors?.[0]?.message ||
|
||||
error?.message ||
|
||||
t("Warnings.genericUpdateFailed");
|
||||
|
||||
enqueueSnackbar(errorMessage, {
|
||||
variant: "error",
|
||||
});
|
||||
dispatch(clearMailError());
|
||||
}
|
||||
}, [error, enqueueSnackbar, t, dispatch]);
|
||||
|
||||
// Get email address from settings or use default from environment variable
|
||||
const defaultEmail = process.env.REACT_APP_DEFAULT_EMAIL || "";
|
||||
// Use default email if currentSettings is null or emailAddress is null
|
||||
const emailAddress = currentSettings?.emailAddress || defaultEmail;
|
||||
const handleEmailClick = () => {
|
||||
if (emailAddress) {
|
||||
window.location.href = `mailto:${emailAddress}`;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setShowMailModal(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ marginTop: "2%" }}>
|
||||
{loading && !currentSettings ? (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
minHeight: 200,
|
||||
}}
|
||||
>
|
||||
<SpinnerComponent />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{permissionCheck("settings_access") && (
|
||||
<>
|
||||
<Modal
|
||||
isOpen={showMailModal}
|
||||
toggle={handleCloseModal}
|
||||
className="modal-dialog-centered"
|
||||
size="lg"
|
||||
>
|
||||
<ModalHeader toggle={handleCloseModal}>
|
||||
{t("MailSettings.editMailInfo")}
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<MailSettings closeModal={handleCloseModal} />
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
</>
|
||||
)}
|
||||
<Card className="border-bottom">
|
||||
<CardHeader className="border-bottom">
|
||||
<CardTitle tag="h2" className="row ml-md-2 align-items-center">
|
||||
{t("Contact.contactInfo")}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<Row>
|
||||
<Col className="pl-md-5 pl-2 col-md-6 col-12">
|
||||
<Row className="mx-0 mt-1">
|
||||
<Col sm="6" md="5" className="mr-2">
|
||||
<div className="email-container d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<h4>
|
||||
<Mail size={16} className="mr-1" />{" "}
|
||||
{t("Contact.contactEmail")}
|
||||
</h4>{" "}
|
||||
{/* Add Mail icon */}
|
||||
<p
|
||||
style={{
|
||||
color: emailAddress ? "blue" : "inherit",
|
||||
textDecoration: emailAddress ? "underline" : "none",
|
||||
cursor: emailAddress ? "pointer" : "default",
|
||||
}}
|
||||
onClick={handleEmailClick}
|
||||
>
|
||||
{emailAddress ||
|
||||
defaultEmail ||
|
||||
t("MailSettings.notConfigured")}
|
||||
</p>
|
||||
</div>
|
||||
{permissionCheck("settings_access") && (
|
||||
<>
|
||||
{" "}
|
||||
{/* Wrap button and tooltip in fragment */}
|
||||
<Button
|
||||
color="flat-primary"
|
||||
className="btn-icon"
|
||||
onClick={() => setShowMailModal(true)}
|
||||
id="edit-email-btn" // Add id for tooltip
|
||||
>
|
||||
<Edit size={18} />
|
||||
</Button>
|
||||
<UncontrolledTooltip
|
||||
placement="top"
|
||||
target="edit-email-btn" // Target the button id
|
||||
timeout={150} // Add timeout prop to fix the warning
|
||||
>
|
||||
{t("MailSettings.editMailInfo")}{" "}
|
||||
{/* Tooltip text */}
|
||||
</UncontrolledTooltip>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Col>
|
||||
<Col sm="6" md="5" className="mr-2">
|
||||
<div className="telephone-container">
|
||||
<h4>
|
||||
<Phone size={16} className="mr-1" />{" "}
|
||||
{t("Contact.contactPhoneNumber")}
|
||||
</h4>{" "}
|
||||
{/* Add Phone icon */}
|
||||
<p>+90 507 750 00 41</p>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="mx-0 mt-4">
|
||||
<Col sm="6" md="5" className="mr-2">
|
||||
<div className="address-container">
|
||||
<h4>
|
||||
<MapPin size={16} className="mr-1" />{" "}
|
||||
{t("Contact.contactAddress")}
|
||||
</h4>{" "}
|
||||
{/* Add MapPin icon */}
|
||||
<address>
|
||||
Central Office: 4995 sokak no:3, Alacaatlı Mahallesi,
|
||||
Daire No: A2 06820 Çankaya/Ankara
|
||||
</address>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col className="pl-md-5 pl-2 col-md-6 col-12 pb-2 border-left">
|
||||
<Row className="mx-0 mt-1">
|
||||
<div className="address-map w-100">
|
||||
<div className="responsive-map-container">
|
||||
<iframe
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3063.1752741150003!2d32.658217075858445!3d39.847904971536735!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x14d33eef6ee44755%3A0x77faea5f08f32c60!2zTUVBIEfDnFpFTEJBSMOHRU0!5e0!3m2!1sen!2str!4v1741165773414!5m2!1sen!2str"
|
||||
allowFullScreen=""
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Communication;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user