Compare commits
136 Commits
mobile-api
...
mobile-api
| Author | SHA1 | Date | |
|---|---|---|---|
| bb79a68f44 | |||
| f103ae93ad | |||
| 1c9459dcf3 | |||
| 8b54f5ca65 | |||
| c94da645f3 | |||
| da0477102e | |||
| 70db97f5bb | |||
| 8ccf1f2b6e | |||
| 048b7b6094 | |||
| fc23e01275 | |||
| 20d05c1cc7 | |||
| 2c269db250 | |||
| fea94df7bb | |||
| 3c6dde6204 | |||
| cb0845e264 | |||
| d09e30c049 | |||
| c8bd928c33 | |||
| 3a558cec8e | |||
| b9354cb6bf | |||
| 7cdde6b5a9 | |||
| e77e5eb3ac | |||
| 8f3f27122a | |||
| d84a1d84ff | |||
| 40ba31edec | |||
| a54f8599b4 | |||
| 09825756f3 | |||
| 2086692897 | |||
| 87515ae19f | |||
| 44d6788f6e | |||
| ac634100b5 | |||
| 1b206102b0 | |||
| 94a545bd30 | |||
| 3552cf4f39 | |||
| d50fda90e0 | |||
| d3d4912a5f | |||
| b2e8bc3caf | |||
| d207b6feed | |||
| f05571caa4 | |||
| 6507bdcd35 | |||
| e2c8a1edbc | |||
| 02b25ffc84 | |||
| f1c8432fdc | |||
| 3e0d2743fb | |||
| fc3ee6724e | |||
| 1cd4c3713e | |||
| a72cf866fa | |||
| c50e0ceaf7 | |||
| 4307b383e3 | |||
| 563d95b928 | |||
| 0786d23336 | |||
| c0a9832c66 | |||
| cb3511f973 | |||
| f06482a159 | |||
| 7ab25655f2 | |||
| 9d17b442e2 | |||
| b4921c4e82 | |||
| b3410a5804 | |||
| 2cdc57d844 | |||
| 695046583f | |||
| a9325054eb | |||
| 6ee0b98f07 | |||
| cc78d82ca4 | |||
| 819812149f | |||
| 3c2a8b3543 | |||
| 75ba2b29ae | |||
| 276cf9e970 | |||
| 54a4d15bdd | |||
| 8ccf722c90 | |||
| 7ad7b3496a | |||
| 1321f33da9 | |||
| c9c39f319c | |||
| c976e6beaf | |||
| fad0c33b9a | |||
| 4b21084748 | |||
| 3277d8cb19 | |||
| 565bab4998 | |||
| b951c698c5 | |||
| ad91a48d82 | |||
| 7530a38c4d | |||
| a06036cab7 | |||
| c3d8ccd490 | |||
| ba6a83f61d | |||
| dc05c4ef7e | |||
| d56a00a92b | |||
| 43deddca43 | |||
| 1e647c0391 | |||
| 6f10ff7c3e | |||
| 09be7739d5 | |||
| 38734cda8c | |||
| 94dc780ead | |||
| fb9515dfe4 | |||
| 0b3d4830f9 | |||
| c710ca60b7 | |||
| 94e4b884a7 | |||
| 4164092100 | |||
| fcad857422 | |||
| 32619ee9b3 | |||
| b118a6425c | |||
| 45305e44cc | |||
| b6e5755942 | |||
| 09e1f702e1 | |||
| 14fbd1a6dd | |||
| a49b95ac8e | |||
| ba5620bcc5 | |||
| 40df3a5e5b | |||
| 134f1dceff | |||
| 24e6fcd0f7 | |||
| 9a3726cbcc | |||
| 10fb0449b4 | |||
| ac6c6217b5 | |||
| cf8d62531f | |||
| 04dd7e6c11 | |||
| 9a967f0965 | |||
| 5e07dfb749 | |||
| dbb71633d4 | |||
| 27259cd86c | |||
| b1a5e50b7b | |||
| a278470dbb | |||
| b209a12315 | |||
| 9aee4e52ed | |||
| 2e2a5c2566 | |||
| ccfb361564 | |||
| 0f11fa37a5 | |||
| 5553f451e8 | |||
| 027ec4f6c5 | |||
| 8485209a75 | |||
| 29677066ef | |||
| d9e2fdaf30 | |||
| 579444c002 | |||
| 7fe5826f5c | |||
| c47decf246 | |||
| 4ef93e0509 | |||
| 3052dabbce | |||
|
|
4fc0ebf7ee | ||
|
|
577ee38220 | ||
|
|
70849ba2a9 |
69
CHANGELOG.md
69
CHANGELOG.md
@@ -2,6 +2,75 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.5.39](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.38...v1.5.39) (2026-01-30)
|
||||||
|
|
||||||
|
## [1.5.38](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.37...v1.5.38) (2026-01-27)
|
||||||
|
|
||||||
|
## [1.5.37](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.36...v1.5.37) (2026-01-23)
|
||||||
|
|
||||||
|
## [1.5.36](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.35...v1.5.36) (2026-01-13)
|
||||||
|
|
||||||
|
## [1.5.35](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.34...v1.5.35) (2026-01-12)
|
||||||
|
|
||||||
|
## [1.5.34](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.33...v1.5.34) (2026-01-09)
|
||||||
|
|
||||||
|
## [1.5.33](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.32...v1.5.33) (2026-01-06)
|
||||||
|
|
||||||
|
## [1.5.32](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.31...v1.5.32) (2026-01-05)
|
||||||
|
|
||||||
|
## [1.5.31](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.30...v1.5.31) (2025-12-24)
|
||||||
|
|
||||||
|
## [1.5.30](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.29...v1.5.30) (2025-12-19)
|
||||||
|
|
||||||
|
## [1.5.29](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.28...v1.5.29) (2025-12-17)
|
||||||
|
|
||||||
|
## [1.5.28](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.27...v1.5.28) (2025-12-17)
|
||||||
|
|
||||||
|
## [1.5.27](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.26...v1.5.27) (2025-12-17)
|
||||||
|
|
||||||
|
## [1.5.26](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.25...v1.5.26) (2025-12-10)
|
||||||
|
|
||||||
|
## [1.5.25](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.24...v1.5.25) (2025-12-09)
|
||||||
|
|
||||||
|
## [1.5.24](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.22...v1.5.24) (2025-12-08)
|
||||||
|
|
||||||
|
## [1.5.22](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.21...v1.5.22) (2025-12-03)
|
||||||
|
|
||||||
|
## [1.5.21](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.20...v1.5.21) (2025-12-03)
|
||||||
|
|
||||||
|
## [1.5.20](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.19...v1.5.20) (2025-12-02)
|
||||||
|
|
||||||
|
## [1.5.19](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.18...v1.5.19) (2025-12-01)
|
||||||
|
|
||||||
|
## [1.5.18](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.17...v1.5.18) (2025-11-28)
|
||||||
|
|
||||||
|
## [1.5.17](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.16...v1.5.17) (2025-11-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* delete all data user ([fb9515d](https://wibugit.wibudev.com/wibu/hipmi/commit/fb9515dfe465ef07d43460ca4e9bb31705ec48b8))
|
||||||
|
|
||||||
|
## [1.5.16](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.15...v1.5.16) (2025-11-20)
|
||||||
|
|
||||||
|
## [1.5.15](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.14...v1.5.15) (2025-11-18)
|
||||||
|
|
||||||
|
## [1.5.14](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.13...v1.5.14) (2025-11-17)
|
||||||
|
|
||||||
|
## [1.5.13](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.12...v1.5.13) (2025-11-17)
|
||||||
|
|
||||||
|
## [1.5.12](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.10...v1.5.12) (2025-11-13)
|
||||||
|
|
||||||
|
## [1.5.11](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.4.45...v1.5.11) (2025-11-07)
|
||||||
|
|
||||||
|
## [1.5.10](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.9...v1.5.10) (2025-11-03)
|
||||||
|
|
||||||
|
## [1.5.9](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.8...v1.5.9) (2025-10-30)
|
||||||
|
|
||||||
|
## [1.5.8](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.7...v1.5.8) (2025-10-29)
|
||||||
|
|
||||||
|
## [1.5.7](https://wibugit.wibudev.com/wibu/hipmi/compare/v1.5.6...v1.5.7) (2025-10-28)
|
||||||
|
|
||||||
## [1.5.6](https://wibugit.wibudev.com/bip/hipmi/compare/v1.5.5...v1.5.6) (2025-10-21)
|
## [1.5.6](https://wibugit.wibudev.com/bip/hipmi/compare/v1.5.5...v1.5.6) (2025-10-21)
|
||||||
|
|
||||||
## [1.5.5](https://wibugit.wibudev.com/bip/hipmi/compare/v1.5.4...v1.5.5) (2025-10-20)
|
## [1.5.5](https://wibugit.wibudev.com/bip/hipmi/compare/v1.5.4...v1.5.5) (2025-10-20)
|
||||||
|
|||||||
16
PROMPT-AI.md
Normal file
16
PROMPT-AI.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
File utama: src/app/api/mobile/notification/[id]/route.ts
|
||||||
|
|
||||||
|
Terapkan pagination pada file "File utama" pada method GET
|
||||||
|
Analisa juga file "File utama", jika belum memiliki page dari seachParams maka terapkan. Juga pastikan take dan skip sudah sesuai dengan pagination. Buat default nya menjadi 10 untuk take data
|
||||||
|
|
||||||
|
Contoh:
|
||||||
|
const page = Number(searchParams.get("page"));
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = page * takeData - takeData;
|
||||||
|
|
||||||
|
dan penerapannya pada query
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
|
||||||
|
Gunakan bahasa indonesia pada cli agar saya mudah membacanya.
|
||||||
201
QWEN.md
Normal file
201
QWEN.md
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
# HIPMI Project - QWEN.md
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
HIPMI (Himpunan Pengusaha Muda Indonesia) is a comprehensive Next.js-based web application built for the Indonesian Young Entrepreneurs Association. The project is a sophisticated platform that provides multiple business functionalities including investment management, donations, events, job listings, forums, voting systems, and collaborative projects.
|
||||||
|
|
||||||
|
### Key Technologies
|
||||||
|
- **Framework**: Next.js 13+ (with App Router)
|
||||||
|
- **Language**: TypeScript
|
||||||
|
- **Database**: PostgreSQL with Prisma ORM
|
||||||
|
- **Styling**: Tailwind CSS with Mantine UI components
|
||||||
|
- **Authentication**: JWT-based with custom middleware
|
||||||
|
- **Runtime**: Bun (instead of Node.js)
|
||||||
|
- **Deployment**: Standalone output configuration
|
||||||
|
|
||||||
|
### Team Structure
|
||||||
|
- **bagas**: Frontend, DevOps
|
||||||
|
- **lukman**: Frontend, UI
|
||||||
|
- **lia**: Backend, Frontend, QC
|
||||||
|
- **malik**: Leader
|
||||||
|
|
||||||
|
## Architecture & Features
|
||||||
|
|
||||||
|
### Core Modules
|
||||||
|
The application is organized into several major functional areas:
|
||||||
|
|
||||||
|
1. **Authentication System** (`/auth`) - Login, registration, validation
|
||||||
|
2. **Investment Platform** (`/investasi`) - Investment creation, trading, portfolio management
|
||||||
|
3. **Donation System** (`/donasi`) - Fundraising campaigns, donation processing
|
||||||
|
4. **Event Management** (`/event`) - Event creation, participation, management
|
||||||
|
5. **Voting System** (`/vote`) - Voting creation and participation
|
||||||
|
6. **Job Board** (`/job`) - Job posting and application system
|
||||||
|
7. **Forum** (`/forum`) - Discussion platform with reporting features
|
||||||
|
8. **Collaboration Platform** (`/colab`) - Project collaboration tools
|
||||||
|
9. **User Profiles** (`/profile`) - User profile management
|
||||||
|
10. **Business Maps** (`/maps`) - Business location mapping
|
||||||
|
|
||||||
|
### Admin Panel
|
||||||
|
The application includes a comprehensive admin panel (`/admin`) with modules for managing:
|
||||||
|
- Investment approvals and transfers
|
||||||
|
- Donation campaign reviews
|
||||||
|
- Event management
|
||||||
|
- Forum moderation
|
||||||
|
- Job posting reviews
|
||||||
|
- User access management
|
||||||
|
- Voting oversight
|
||||||
|
|
||||||
|
### Technical Architecture
|
||||||
|
|
||||||
|
#### Routing & Authentication
|
||||||
|
- Custom middleware handles authentication and authorization
|
||||||
|
- Public routes are defined in the middleware configuration
|
||||||
|
- JWT tokens are stored in cookies with secure options
|
||||||
|
- Role-based access control (MasterUserRole model)
|
||||||
|
|
||||||
|
#### Database Schema
|
||||||
|
The Prisma schema defines a comprehensive data model with:
|
||||||
|
- User management with roles and profiles
|
||||||
|
- Investment and financial systems
|
||||||
|
- Donation and crowdfunding features
|
||||||
|
- Event management
|
||||||
|
- Forum and discussion systems
|
||||||
|
- Collaboration platforms
|
||||||
|
- Notification systems
|
||||||
|
- Business mapping features
|
||||||
|
|
||||||
|
#### Environment Configuration
|
||||||
|
The application uses multiple environment files for different deployment stages:
|
||||||
|
- Development: `run.env.dev`, `run.env.local.dev`
|
||||||
|
- Build: `run.env.build.dev`, `run.env.build.local`
|
||||||
|
- Runtime: `run.env.start.dev`, `run.env.start.local`
|
||||||
|
|
||||||
|
## Building and Running
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- Bun runtime installed
|
||||||
|
- PostgreSQL database
|
||||||
|
- Required environment variables configured
|
||||||
|
|
||||||
|
### Setup Commands
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Setup database (Prisma)
|
||||||
|
bun prisma generate
|
||||||
|
bun prisma db push
|
||||||
|
bun prisma db seed
|
||||||
|
|
||||||
|
# Development server
|
||||||
|
bun run dev
|
||||||
|
|
||||||
|
# Build for production
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
# Start production server
|
||||||
|
bun run start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Scripts
|
||||||
|
- `dev`: Starts development server with HTTPS
|
||||||
|
- `build`: Builds the application for production
|
||||||
|
- `start`: Starts the production server
|
||||||
|
- `lint`: Runs Next.js linting
|
||||||
|
- `ver`: Creates version tags
|
||||||
|
|
||||||
|
## Development Conventions
|
||||||
|
|
||||||
|
### Git Workflow
|
||||||
|
The team follows a structured Git workflow:
|
||||||
|
1. Check status with `git status`
|
||||||
|
2. Add specific files with `git add <file>` (avoid `git add -A`)
|
||||||
|
3. Commit with structured messages following conventional commits:
|
||||||
|
- `feat`: New features
|
||||||
|
- `fix`: Bug fixes
|
||||||
|
- `docs`: Documentation updates
|
||||||
|
- `chore`: Routine tasks
|
||||||
|
- `refactor`: Code restructuring
|
||||||
|
- `test`: Testing additions
|
||||||
|
- `style`: Styling changes
|
||||||
|
- `perf`: Performance improvements
|
||||||
|
|
||||||
|
### Code Standards
|
||||||
|
- TypeScript with strict mode enabled
|
||||||
|
- Component header comments with file description, creator, date
|
||||||
|
- Function comments with parameter and return value descriptions
|
||||||
|
- Custom type interface comments
|
||||||
|
- Error handling comments
|
||||||
|
- Complex logic comments
|
||||||
|
|
||||||
|
### Commit Message Format
|
||||||
|
```
|
||||||
|
type: Short description
|
||||||
|
|
||||||
|
Body:
|
||||||
|
- Detailed description of changes
|
||||||
|
- Motivation for changes
|
||||||
|
- Breaking changes if any
|
||||||
|
|
||||||
|
References: #issue-number
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
### Main Directories
|
||||||
|
- `src/app`: Next.js App Router pages and layouts
|
||||||
|
- `src/app_modules`: Reusable application modules
|
||||||
|
- `src/lib`: Shared libraries and utilities
|
||||||
|
- `src/util`: Utility functions
|
||||||
|
- `prisma`: Database schema and migrations
|
||||||
|
- `public`: Static assets
|
||||||
|
- `certificates`, `logs`: Application data directories
|
||||||
|
|
||||||
|
### Key Files
|
||||||
|
- `package.json`: Dependencies and scripts
|
||||||
|
- `next.config.js`: Next.js configuration
|
||||||
|
- `middleware.tsx`: Authentication and routing middleware
|
||||||
|
- `tsconfig.json`: TypeScript configuration
|
||||||
|
- `tailwind.config.js`: Styling configuration
|
||||||
|
- `gen_page.tsx`: Generated page routing utility
|
||||||
|
- `prisma/schema.prisma`: Database schema definition
|
||||||
|
|
||||||
|
## Special Features
|
||||||
|
|
||||||
|
### Real-time Capabilities
|
||||||
|
- WebSocket integration for real-time updates
|
||||||
|
- MQTT support for messaging
|
||||||
|
- Live notifications system
|
||||||
|
|
||||||
|
### Payment Integration
|
||||||
|
- Midtrans payment gateway for investments
|
||||||
|
- Multiple payment methods
|
||||||
|
- Invoice generation and tracking
|
||||||
|
|
||||||
|
### File Handling
|
||||||
|
- PDF generation and viewing
|
||||||
|
- Image processing and storage
|
||||||
|
- Document management for investments
|
||||||
|
|
||||||
|
### Mobile Support
|
||||||
|
- Responsive design
|
||||||
|
- Mobile-specific features
|
||||||
|
- Device token management
|
||||||
|
|
||||||
|
## Security Measures
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
- JWT-based authentication
|
||||||
|
- Session management
|
||||||
|
- Role-based access control
|
||||||
|
- Secure token storage in cookies
|
||||||
|
|
||||||
|
### Input Validation
|
||||||
|
- Prisma schema validations
|
||||||
|
- Server-side validation
|
||||||
|
- Sanitization of user inputs
|
||||||
|
|
||||||
|
### Data Protection
|
||||||
|
- Encrypted tokens
|
||||||
|
- Secure API routes
|
||||||
|
- Proper CORS configuration
|
||||||
286
bun.lock
286
bun.lock
@@ -18,6 +18,7 @@
|
|||||||
"@mantine/notifications": "^6.0.17",
|
"@mantine/notifications": "^6.0.17",
|
||||||
"@mantine/tiptap": "^7.5.3",
|
"@mantine/tiptap": "^7.5.3",
|
||||||
"@prisma/client": "^6.3.0",
|
"@prisma/client": "^6.3.0",
|
||||||
|
"@react-email/render": "^2.0.0",
|
||||||
"@react-pdf/renderer": "^3.4.4",
|
"@react-pdf/renderer": "^3.4.4",
|
||||||
"@tabler/icons-react": "^3.31.0",
|
"@tabler/icons-react": "^3.31.0",
|
||||||
"@tiptap/extension-highlight": "^2.2.3",
|
"@tiptap/extension-highlight": "^2.2.3",
|
||||||
@@ -40,6 +41,7 @@
|
|||||||
"autoprefixer": "10.4.14",
|
"autoprefixer": "10.4.14",
|
||||||
"bufferutil": "^4.0.8",
|
"bufferutil": "^4.0.8",
|
||||||
"bun": "^1.1.38",
|
"bun": "^1.1.38",
|
||||||
|
"caniuse-lite": "^1.0.30001757",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
@@ -48,6 +50,7 @@
|
|||||||
"echarts-for-react": "^3.0.2",
|
"echarts-for-react": "^3.0.2",
|
||||||
"embla-carousel-react": "^8.0.0-rc14",
|
"embla-carousel-react": "^8.0.0-rc14",
|
||||||
"eslint-config-next": "^13.5.4",
|
"eslint-config-next": "^13.5.4",
|
||||||
|
"firebase-admin": "^13.6.0",
|
||||||
"iron-session": "^6.3.1",
|
"iron-session": "^6.3.1",
|
||||||
"jose": "^5.9.2",
|
"jose": "^5.9.2",
|
||||||
"jotai": "^2.4.3",
|
"jotai": "^2.4.3",
|
||||||
@@ -79,6 +82,7 @@
|
|||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-responsive-carousel": "^3.2.23",
|
"react-responsive-carousel": "^3.2.23",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
|
"resend": "^6.4.2",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.2",
|
||||||
"swr": "^2.3.0",
|
"swr": "^2.3.0",
|
||||||
@@ -506,6 +510,26 @@
|
|||||||
|
|
||||||
"@expo/xcpretty": ["@expo/xcpretty@4.3.2", "", { "dependencies": { "@babel/code-frame": "7.10.4", "chalk": "^4.1.0", "find-up": "^5.0.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw=="],
|
"@expo/xcpretty": ["@expo/xcpretty@4.3.2", "", { "dependencies": { "@babel/code-frame": "7.10.4", "chalk": "^4.1.0", "find-up": "^5.0.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw=="],
|
||||||
|
|
||||||
|
"@fastify/busboy": ["@fastify/busboy@3.2.0", "", {}, "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA=="],
|
||||||
|
|
||||||
|
"@firebase/app-check-interop-types": ["@firebase/app-check-interop-types@0.3.3", "", {}, "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A=="],
|
||||||
|
|
||||||
|
"@firebase/app-types": ["@firebase/app-types@0.9.3", "", {}, "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw=="],
|
||||||
|
|
||||||
|
"@firebase/auth-interop-types": ["@firebase/auth-interop-types@0.2.4", "", {}, "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA=="],
|
||||||
|
|
||||||
|
"@firebase/component": ["@firebase/component@0.7.0", "", { "dependencies": { "@firebase/util": "1.13.0", "tslib": "^2.1.0" } }, "sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg=="],
|
||||||
|
|
||||||
|
"@firebase/database": ["@firebase/database@1.1.0", "", { "dependencies": { "@firebase/app-check-interop-types": "0.3.3", "@firebase/auth-interop-types": "0.2.4", "@firebase/component": "0.7.0", "@firebase/logger": "0.5.0", "@firebase/util": "1.13.0", "faye-websocket": "0.11.4", "tslib": "^2.1.0" } }, "sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg=="],
|
||||||
|
|
||||||
|
"@firebase/database-compat": ["@firebase/database-compat@2.1.0", "", { "dependencies": { "@firebase/component": "0.7.0", "@firebase/database": "1.1.0", "@firebase/database-types": "1.0.16", "@firebase/logger": "0.5.0", "@firebase/util": "1.13.0", "tslib": "^2.1.0" } }, "sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg=="],
|
||||||
|
|
||||||
|
"@firebase/database-types": ["@firebase/database-types@1.0.16", "", { "dependencies": { "@firebase/app-types": "0.9.3", "@firebase/util": "1.13.0" } }, "sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw=="],
|
||||||
|
|
||||||
|
"@firebase/logger": ["@firebase/logger@0.5.0", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g=="],
|
||||||
|
|
||||||
|
"@firebase/util": ["@firebase/util@1.13.0", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ=="],
|
||||||
|
|
||||||
"@floating-ui/core": ["@floating-ui/core@1.6.9", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw=="],
|
"@floating-ui/core": ["@floating-ui/core@1.6.9", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw=="],
|
||||||
|
|
||||||
"@floating-ui/dom": ["@floating-ui/dom@1.6.13", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.9" } }, "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w=="],
|
"@floating-ui/dom": ["@floating-ui/dom@1.6.13", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.9" } }, "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w=="],
|
||||||
@@ -516,8 +540,22 @@
|
|||||||
|
|
||||||
"@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="],
|
"@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="],
|
||||||
|
|
||||||
|
"@google-cloud/firestore": ["@google-cloud/firestore@7.11.6", "", { "dependencies": { "@opentelemetry/api": "^1.3.0", "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", "google-gax": "^4.3.3", "protobufjs": "^7.2.6" } }, "sha512-EW/O8ktzwLfyWBOsNuhRoMi8lrC3clHM5LVFhGvO1HCsLozCOOXRAlHrYBoE6HL42Sc8yYMuCb2XqcnJ4OOEpw=="],
|
||||||
|
|
||||||
|
"@google-cloud/paginator": ["@google-cloud/paginator@5.0.2", "", { "dependencies": { "arrify": "^2.0.0", "extend": "^3.0.2" } }, "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg=="],
|
||||||
|
|
||||||
|
"@google-cloud/projectify": ["@google-cloud/projectify@4.0.0", "", {}, "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA=="],
|
||||||
|
|
||||||
|
"@google-cloud/promisify": ["@google-cloud/promisify@4.0.0", "", {}, "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g=="],
|
||||||
|
|
||||||
|
"@google-cloud/storage": ["@google-cloud/storage@7.18.0", "", { "dependencies": { "@google-cloud/paginator": "^5.0.0", "@google-cloud/projectify": "^4.0.0", "@google-cloud/promisify": "<4.1.0", "abort-controller": "^3.0.0", "async-retry": "^1.3.3", "duplexify": "^4.1.3", "fast-xml-parser": "^4.4.1", "gaxios": "^6.0.2", "google-auth-library": "^9.6.3", "html-entities": "^2.5.2", "mime": "^3.0.0", "p-limit": "^3.0.1", "retry-request": "^7.0.0", "teeny-request": "^9.0.0", "uuid": "^8.0.0" } }, "sha512-r3ZwDMiz4nwW6R922Z1pwpePxyRwE5GdevYX63hRmAQUkUQJcBH/79EnQPDv5cOv1mFBgevdNWQfi3tie3dHrQ=="],
|
||||||
|
|
||||||
"@google/generative-ai": ["@google/generative-ai@0.19.0", "", {}, "sha512-iGf/62v3sTwtEJGJY6S5m7PfkglU8hi1URaxqIjiRg1OItV27xyc4aVeR0og8cDkZFkUlGZKv+23bJtT1QWFzQ=="],
|
"@google/generative-ai": ["@google/generative-ai@0.19.0", "", {}, "sha512-iGf/62v3sTwtEJGJY6S5m7PfkglU8hi1URaxqIjiRg1OItV27xyc4aVeR0og8cDkZFkUlGZKv+23bJtT1QWFzQ=="],
|
||||||
|
|
||||||
|
"@grpc/grpc-js": ["@grpc/grpc-js@1.14.3", "", { "dependencies": { "@grpc/proto-loader": "^0.8.0", "@js-sdsl/ordered-map": "^4.4.2" } }, "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA=="],
|
||||||
|
|
||||||
|
"@grpc/proto-loader": ["@grpc/proto-loader@0.7.15", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.2.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ=="],
|
||||||
|
|
||||||
"@hookstate/core": ["@hookstate/core@4.0.1", "", { "peerDependencies": { "react": "^16.8.6 || ^17.0.0 || ^18.0.0" } }, "sha512-Uh2D8Z0z/pqOJ7t+SfC+2sj13JQcB4yFhtL+T1choCaBxTSlgOS/CKRBohgJ4cjTKoxOmTT8uSQysu3gUjX+Gw=="],
|
"@hookstate/core": ["@hookstate/core@4.0.1", "", { "peerDependencies": { "react": "^16.8.6 || ^17.0.0 || ^18.0.0" } }, "sha512-Uh2D8Z0z/pqOJ7t+SfC+2sj13JQcB4yFhtL+T1choCaBxTSlgOS/CKRBohgJ4cjTKoxOmTT8uSQysu3gUjX+Gw=="],
|
||||||
|
|
||||||
"@huggingface/jinja": ["@huggingface/jinja@0.3.3", "", {}, "sha512-vQQr2JyWvVFba3Lj9es4q9vCl1sAc74fdgnEMoX8qHrXtswap9ge9uO3ONDzQB0cQ0PUyaKY2N6HaVbTBvSXvw=="],
|
"@huggingface/jinja": ["@huggingface/jinja@0.3.3", "", {}, "sha512-vQQr2JyWvVFba3Lj9es4q9vCl1sAc74fdgnEMoX8qHrXtswap9ge9uO3ONDzQB0cQ0PUyaKY2N6HaVbTBvSXvw=="],
|
||||||
@@ -602,6 +640,8 @@
|
|||||||
|
|
||||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
|
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
|
||||||
|
|
||||||
|
"@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="],
|
||||||
|
|
||||||
"@mantine/carousel": ["@mantine/carousel@7.17.0", "", { "peerDependencies": { "@mantine/core": "7.17.0", "@mantine/hooks": "7.17.0", "embla-carousel-react": ">=7.0.0", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-NrgfUBa7tbtDFem6TAntZjQknymqhzZ/d52szheRu+3GIfd9d8qEPHV1sMFRQ3DkzMxiJfzI6G61GvW6yLOaGg=="],
|
"@mantine/carousel": ["@mantine/carousel@7.17.0", "", { "peerDependencies": { "@mantine/core": "7.17.0", "@mantine/hooks": "7.17.0", "embla-carousel-react": ">=7.0.0", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "sha512-NrgfUBa7tbtDFem6TAntZjQknymqhzZ/d52szheRu+3GIfd9d8qEPHV1sMFRQ3DkzMxiJfzI6G61GvW6yLOaGg=="],
|
||||||
|
|
||||||
"@mantine/core": ["@mantine/core@6.0.22", "", { "dependencies": { "@floating-ui/react": "^0.19.1", "@mantine/styles": "6.0.22", "@mantine/utils": "6.0.22", "@radix-ui/react-scroll-area": "1.0.2", "react-remove-scroll": "^2.5.5", "react-textarea-autosize": "8.3.4" }, "peerDependencies": { "@mantine/hooks": "6.0.22", "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-6kv0eY7n565fyjgS20qUYeCSxg3f1TJ5vurzbP1HHtFXXKSY0bYoqqDoHipFCt6NxsPQGeiC6cC0c/IWIlxoKQ=="],
|
"@mantine/core": ["@mantine/core@6.0.22", "", { "dependencies": { "@floating-ui/react": "^0.19.1", "@mantine/styles": "6.0.22", "@mantine/utils": "6.0.22", "@radix-ui/react-scroll-area": "1.0.2", "react-remove-scroll": "^2.5.5", "react-textarea-autosize": "8.3.4" }, "peerDependencies": { "@mantine/hooks": "6.0.22", "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-6kv0eY7n565fyjgS20qUYeCSxg3f1TJ5vurzbP1HHtFXXKSY0bYoqqDoHipFCt6NxsPQGeiC6cC0c/IWIlxoKQ=="],
|
||||||
@@ -748,6 +788,8 @@
|
|||||||
|
|
||||||
"@octokit/webhooks-methods": ["@octokit/webhooks-methods@5.1.1", "", {}, "sha512-NGlEHZDseJTCj8TMMFehzwa9g7On4KJMPVHDSrHxCQumL6uSQR8wIkP/qesv52fXqV1BPf4pTxwtS31ldAt9Xg=="],
|
"@octokit/webhooks-methods": ["@octokit/webhooks-methods@5.1.1", "", {}, "sha512-NGlEHZDseJTCj8TMMFehzwa9g7On4KJMPVHDSrHxCQumL6uSQR8wIkP/qesv52fXqV1BPf4pTxwtS31ldAt9Xg=="],
|
||||||
|
|
||||||
|
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
|
||||||
|
|
||||||
"@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-xBz/Q7X6AFwMg7MXtBemjjt5uB+tvEYBmi9Zbm1r8qnI2V8m/Smuhma0EARhiVfLuIAYj2EM5qjzxeAFV4TBJA=="],
|
"@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-xBz/Q7X6AFwMg7MXtBemjjt5uB+tvEYBmi9Zbm1r8qnI2V8m/Smuhma0EARhiVfLuIAYj2EM5qjzxeAFV4TBJA=="],
|
||||||
|
|
||||||
"@oven/bun-darwin-x64": ["@oven/bun-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ufyty+2754QCFDhq447H39JiqabMlFRItLn1YFp+2hdpKak7KCYLGOUuHnlr1pmImKJzDHURjnvTTq1QRlUWAA=="],
|
"@oven/bun-darwin-x64": ["@oven/bun-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ufyty+2754QCFDhq447H39JiqabMlFRItLn1YFp+2hdpKak7KCYLGOUuHnlr1pmImKJzDHURjnvTTq1QRlUWAA=="],
|
||||||
@@ -838,6 +880,8 @@
|
|||||||
|
|
||||||
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
|
"@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.0.0", "", { "dependencies": { "@babel/runtime": "^7.13.10" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0" } }, "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ=="],
|
||||||
|
|
||||||
|
"@react-email/render": ["@react-email/render@2.0.0", "", { "dependencies": { "html-to-text": "^9.0.5", "prettier": "^3.5.3" }, "peerDependencies": { "react": "^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-rdjNj6iVzv8kRKDPFas+47nnoe6B40+nwukuXwY4FCwM7XBg6tmYr+chQryCuavUj2J65MMf6fztk1bxOUiSVA=="],
|
||||||
|
|
||||||
"@react-native/assets-registry": ["@react-native/assets-registry@0.78.0", "", {}, "sha512-PPHlTRuP9litTYkbFNkwveQFto3I94QRWPBBARU0cH/4ks4EkfCfb/Pdb3AHgtJi58QthSHKFvKTQnAWyHPs7w=="],
|
"@react-native/assets-registry": ["@react-native/assets-registry@0.78.0", "", {}, "sha512-PPHlTRuP9litTYkbFNkwveQFto3I94QRWPBBARU0cH/4ks4EkfCfb/Pdb3AHgtJi58QthSHKFvKTQnAWyHPs7w=="],
|
||||||
|
|
||||||
"@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.76.7", "", { "dependencies": { "@react-native/codegen": "0.76.7" } }, "sha512-+8H4DXJREM4l/pwLF/wSVMRzVhzhGDix5jLezNrMD9J1U1AMfV2aSkWA1XuqR7pjPs/Vqf6TaPL7vJMZ4LU05Q=="],
|
"@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.76.7", "", { "dependencies": { "@react-native/codegen": "0.76.7" } }, "sha512-+8H4DXJREM4l/pwLF/wSVMRzVhzhGDix5jLezNrMD9J1U1AMfV2aSkWA1XuqR7pjPs/Vqf6TaPL7vJMZ4LU05Q=="],
|
||||||
@@ -894,6 +938,8 @@
|
|||||||
|
|
||||||
"@segment/loosely-validate-event": ["@segment/loosely-validate-event@2.0.0", "", { "dependencies": { "component-type": "^1.2.1", "join-component": "^1.1.0" } }, "sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw=="],
|
"@segment/loosely-validate-event": ["@segment/loosely-validate-event@2.0.0", "", { "dependencies": { "component-type": "^1.2.1", "join-component": "^1.1.0" } }, "sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw=="],
|
||||||
|
|
||||||
|
"@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="],
|
||||||
|
|
||||||
"@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
|
"@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
|
||||||
|
|
||||||
"@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="],
|
"@sinonjs/commons": ["@sinonjs/commons@3.0.1", "", { "dependencies": { "type-detect": "4.0.8" } }, "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ=="],
|
||||||
@@ -902,6 +948,8 @@
|
|||||||
|
|
||||||
"@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="],
|
"@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="],
|
||||||
|
|
||||||
|
"@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="],
|
||||||
|
|
||||||
"@supabase/auth-js": ["@supabase/auth-js@2.68.0", "", { "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "sha512-odG7nb7aOmZPUXk6SwL2JchSsn36Ppx11i2yWMIc/meUO2B2HK9YwZHPK06utD9Ql9ke7JKDbwGin/8prHKxxQ=="],
|
"@supabase/auth-js": ["@supabase/auth-js@2.68.0", "", { "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "sha512-odG7nb7aOmZPUXk6SwL2JchSsn36Ppx11i2yWMIc/meUO2B2HK9YwZHPK06utD9Ql9ke7JKDbwGin/8prHKxxQ=="],
|
||||||
|
|
||||||
"@supabase/functions-js": ["@supabase/functions-js@2.4.4", "", { "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA=="],
|
"@supabase/functions-js": ["@supabase/functions-js@2.4.4", "", { "dependencies": { "@supabase/node-fetch": "^2.6.14" } }, "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA=="],
|
||||||
@@ -988,6 +1036,8 @@
|
|||||||
|
|
||||||
"@tiptap/starter-kit": ["@tiptap/starter-kit@2.11.5", "", { "dependencies": { "@tiptap/core": "^2.11.5", "@tiptap/extension-blockquote": "^2.11.5", "@tiptap/extension-bold": "^2.11.5", "@tiptap/extension-bullet-list": "^2.11.5", "@tiptap/extension-code": "^2.11.5", "@tiptap/extension-code-block": "^2.11.5", "@tiptap/extension-document": "^2.11.5", "@tiptap/extension-dropcursor": "^2.11.5", "@tiptap/extension-gapcursor": "^2.11.5", "@tiptap/extension-hard-break": "^2.11.5", "@tiptap/extension-heading": "^2.11.5", "@tiptap/extension-history": "^2.11.5", "@tiptap/extension-horizontal-rule": "^2.11.5", "@tiptap/extension-italic": "^2.11.5", "@tiptap/extension-list-item": "^2.11.5", "@tiptap/extension-ordered-list": "^2.11.5", "@tiptap/extension-paragraph": "^2.11.5", "@tiptap/extension-strike": "^2.11.5", "@tiptap/extension-text": "^2.11.5", "@tiptap/extension-text-style": "^2.11.5", "@tiptap/pm": "^2.11.5" } }, "sha512-SLI7Aj2ruU1t//6Mk8f+fqW+18uTqpdfLUJYgwu0CkqBckrkRZYZh6GVLk/02k3H2ki7QkFxiFbZrdbZdng0JA=="],
|
"@tiptap/starter-kit": ["@tiptap/starter-kit@2.11.5", "", { "dependencies": { "@tiptap/core": "^2.11.5", "@tiptap/extension-blockquote": "^2.11.5", "@tiptap/extension-bold": "^2.11.5", "@tiptap/extension-bullet-list": "^2.11.5", "@tiptap/extension-code": "^2.11.5", "@tiptap/extension-code-block": "^2.11.5", "@tiptap/extension-document": "^2.11.5", "@tiptap/extension-dropcursor": "^2.11.5", "@tiptap/extension-gapcursor": "^2.11.5", "@tiptap/extension-hard-break": "^2.11.5", "@tiptap/extension-heading": "^2.11.5", "@tiptap/extension-history": "^2.11.5", "@tiptap/extension-horizontal-rule": "^2.11.5", "@tiptap/extension-italic": "^2.11.5", "@tiptap/extension-list-item": "^2.11.5", "@tiptap/extension-ordered-list": "^2.11.5", "@tiptap/extension-paragraph": "^2.11.5", "@tiptap/extension-strike": "^2.11.5", "@tiptap/extension-text": "^2.11.5", "@tiptap/extension-text-style": "^2.11.5", "@tiptap/pm": "^2.11.5" } }, "sha512-SLI7Aj2ruU1t//6Mk8f+fqW+18uTqpdfLUJYgwu0CkqBckrkRZYZh6GVLk/02k3H2ki7QkFxiFbZrdbZdng0JA=="],
|
||||||
|
|
||||||
|
"@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="],
|
||||||
|
|
||||||
"@tsconfig/node10": ["@tsconfig/node10@1.0.11", "", {}, "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="],
|
"@tsconfig/node10": ["@tsconfig/node10@1.0.11", "", {}, "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="],
|
||||||
|
|
||||||
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
|
"@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="],
|
||||||
@@ -1016,6 +1066,8 @@
|
|||||||
|
|
||||||
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
||||||
|
|
||||||
|
"@types/caseless": ["@types/caseless@0.12.5", "", {}, "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg=="],
|
||||||
|
|
||||||
"@types/cli-progress": ["@types/cli-progress@3.11.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA=="],
|
"@types/cli-progress": ["@types/cli-progress@3.11.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA=="],
|
||||||
|
|
||||||
"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
|
"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
|
||||||
@@ -1050,6 +1102,8 @@
|
|||||||
|
|
||||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||||
|
|
||||||
|
"@types/jsonwebtoken": ["@types/jsonwebtoken@9.0.10", "", { "dependencies": { "@types/ms": "*", "@types/node": "*" } }, "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA=="],
|
||||||
|
|
||||||
"@types/keygrip": ["@types/keygrip@1.0.6", "", {}, "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ=="],
|
"@types/keygrip": ["@types/keygrip@1.0.6", "", {}, "sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ=="],
|
||||||
|
|
||||||
"@types/koa": ["@types/koa@2.15.0", "", { "dependencies": { "@types/accepts": "*", "@types/content-disposition": "*", "@types/cookies": "*", "@types/http-assert": "*", "@types/http-errors": "*", "@types/keygrip": "*", "@types/koa-compose": "*", "@types/node": "*" } }, "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g=="],
|
"@types/koa": ["@types/koa@2.15.0", "", { "dependencies": { "@types/accepts": "*", "@types/content-disposition": "*", "@types/cookies": "*", "@types/http-assert": "*", "@types/http-errors": "*", "@types/keygrip": "*", "@types/koa-compose": "*", "@types/node": "*" } }, "sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g=="],
|
||||||
@@ -1060,6 +1114,8 @@
|
|||||||
|
|
||||||
"@types/lodash": ["@types/lodash@4.17.15", "", {}, "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw=="],
|
"@types/lodash": ["@types/lodash@4.17.15", "", {}, "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw=="],
|
||||||
|
|
||||||
|
"@types/long": ["@types/long@4.0.2", "", {}, "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA=="],
|
||||||
|
|
||||||
"@types/mapbox-gl": ["@types/mapbox-gl@3.4.1", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg=="],
|
"@types/mapbox-gl": ["@types/mapbox-gl@3.4.1", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-NsGKKtgW93B+UaLPti6B7NwlxYlES5DpV5Gzj9F75rK5ALKsqSk15CiEHbOnTr09RGbr6ZYiCdI+59NNNcAImg=="],
|
||||||
|
|
||||||
"@types/mapbox__point-geometry": ["@types/mapbox__point-geometry@0.1.4", "", {}, "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA=="],
|
"@types/mapbox__point-geometry": ["@types/mapbox__point-geometry@0.1.4", "", {}, "sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA=="],
|
||||||
@@ -1072,6 +1128,8 @@
|
|||||||
|
|
||||||
"@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
|
"@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
|
||||||
|
|
||||||
|
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
||||||
|
|
||||||
"@types/mustache": ["@types/mustache@4.2.5", "", {}, "sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA=="],
|
"@types/mustache": ["@types/mustache@4.2.5", "", {}, "sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@20.4.5", "", {}, "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg=="],
|
"@types/node": ["@types/node@20.4.5", "", {}, "sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg=="],
|
||||||
@@ -1102,6 +1160,8 @@
|
|||||||
|
|
||||||
"@types/readable-stream": ["@types/readable-stream@4.0.18", "", { "dependencies": { "@types/node": "*", "safe-buffer": "~5.1.1" } }, "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA=="],
|
"@types/readable-stream": ["@types/readable-stream@4.0.18", "", { "dependencies": { "@types/node": "*", "safe-buffer": "~5.1.1" } }, "sha512-21jK/1j+Wg+7jVw1xnSwy/2Q1VgVjWuFssbYGTREPUBeZ+rqVFl2udq0IkxzPC0ZhOzVceUbyIACFZKLqKEBlA=="],
|
||||||
|
|
||||||
|
"@types/request": ["@types/request@2.48.13", "", { "dependencies": { "@types/caseless": "*", "@types/node": "*", "@types/tough-cookie": "*", "form-data": "^2.5.5" } }, "sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg=="],
|
||||||
|
|
||||||
"@types/scheduler": ["@types/scheduler@0.23.0", "", {}, "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw=="],
|
"@types/scheduler": ["@types/scheduler@0.23.0", "", {}, "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw=="],
|
||||||
|
|
||||||
"@types/send": ["@types/send@0.17.4", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA=="],
|
"@types/send": ["@types/send@0.17.4", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA=="],
|
||||||
@@ -1114,6 +1174,8 @@
|
|||||||
|
|
||||||
"@types/supercluster": ["@types/supercluster@7.1.3", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA=="],
|
"@types/supercluster": ["@types/supercluster@7.1.3", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA=="],
|
||||||
|
|
||||||
|
"@types/tough-cookie": ["@types/tough-cookie@4.0.5", "", {}, "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA=="],
|
||||||
|
|
||||||
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
|
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
|
||||||
|
|
||||||
"@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="],
|
"@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="],
|
||||||
@@ -1228,6 +1290,8 @@
|
|||||||
|
|
||||||
"arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="],
|
"arraybuffer.prototype.slice": ["arraybuffer.prototype.slice@1.0.4", "", { "dependencies": { "array-buffer-byte-length": "^1.0.1", "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "is-array-buffer": "^3.0.4" } }, "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ=="],
|
||||||
|
|
||||||
|
"arrify": ["arrify@2.0.1", "", {}, "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="],
|
||||||
|
|
||||||
"asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="],
|
"asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="],
|
||||||
|
|
||||||
"asn1.js": ["asn1.js@5.4.1", "", { "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "safer-buffer": "^2.1.0" } }, "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA=="],
|
"asn1.js": ["asn1.js@5.4.1", "", { "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0", "safer-buffer": "^2.1.0" } }, "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA=="],
|
||||||
@@ -1246,6 +1310,8 @@
|
|||||||
|
|
||||||
"async-limiter": ["async-limiter@1.0.1", "", {}, "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="],
|
"async-limiter": ["async-limiter@1.0.1", "", {}, "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="],
|
||||||
|
|
||||||
|
"async-retry": ["async-retry@1.3.3", "", { "dependencies": { "retry": "0.13.1" } }, "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw=="],
|
||||||
|
|
||||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||||
|
|
||||||
"at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="],
|
"at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="],
|
||||||
@@ -1302,6 +1368,8 @@
|
|||||||
|
|
||||||
"big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="],
|
"big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="],
|
||||||
|
|
||||||
|
"bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
|
||||||
|
|
||||||
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
||||||
|
|
||||||
"bl": ["bl@6.0.19", "", { "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "sha512-4Ay3A3oDfGg3GGirhl4s62ebtnk0pJZA5mLp672MPKOQXsWvXjEF4dqdXySjJIs7b9OVr/O8aOo0Lm+xdjo2JA=="],
|
"bl": ["bl@6.0.19", "", { "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "sha512-4Ay3A3oDfGg3GGirhl4s62ebtnk0pJZA5mLp672MPKOQXsWvXjEF4dqdXySjJIs7b9OVr/O8aOo0Lm+xdjo2JA=="],
|
||||||
@@ -1380,7 +1448,7 @@
|
|||||||
|
|
||||||
"camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="],
|
"camelize": ["camelize@1.0.1", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="],
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001757", "", {}, "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ=="],
|
||||||
|
|
||||||
"canvas": ["canvas@3.1.0", "", { "dependencies": { "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1" } }, "sha512-tTj3CqqukVJ9NgSahykNwtGda7V33VLObwrHfzT0vqJXu7J4d4C/7kQQW3fOEGDfZZoILPut5H00gOjyttPGyg=="],
|
"canvas": ["canvas@3.1.0", "", { "dependencies": { "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1" } }, "sha512-tTj3CqqukVJ9NgSahykNwtGda7V33VLObwrHfzT0vqJXu7J4d4C/7kQQW3fOEGDfZZoILPut5H00gOjyttPGyg=="],
|
||||||
|
|
||||||
@@ -1574,13 +1642,13 @@
|
|||||||
|
|
||||||
"dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="],
|
"dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="],
|
||||||
|
|
||||||
"dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
|
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||||
|
|
||||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||||
|
|
||||||
"domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="],
|
"domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="],
|
||||||
|
|
||||||
"domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="],
|
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||||
|
|
||||||
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
|
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
|
||||||
|
|
||||||
@@ -1594,6 +1662,8 @@
|
|||||||
|
|
||||||
"duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "^2.0.2" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="],
|
"duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "^2.0.2" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="],
|
||||||
|
|
||||||
|
"duplexify": ["duplexify@4.1.3", "", { "dependencies": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", "readable-stream": "^3.1.1", "stream-shift": "^1.0.2" } }, "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA=="],
|
||||||
|
|
||||||
"earcut": ["earcut@3.0.1", "", {}, "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw=="],
|
"earcut": ["earcut@3.0.1", "", {}, "sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw=="],
|
||||||
|
|
||||||
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
|
||||||
@@ -1656,6 +1726,8 @@
|
|||||||
|
|
||||||
"es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
|
"es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="],
|
||||||
|
|
||||||
|
"es6-promise": ["es6-promise@4.2.8", "", {}, "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="],
|
||||||
|
|
||||||
"es7-shim": ["es7-shim@6.0.0", "", { "dependencies": { "array-includes": "^3.0.2", "object.entries": "^1.0.3", "object.getownpropertydescriptors": "^2.0.2", "object.values": "^1.0.3", "string-at": "^1.0.1", "string.prototype.padend": "^3.0.0", "string.prototype.padstart": "^3.0.0", "string.prototype.trimleft": "^2.0.0", "string.prototype.trimright": "^2.0.0" } }, "sha512-aiQ/QyJBVJbabtsSediM1S4qI+P3p8F5J5YR5o/bH003BCnnclzxK9pi5Qd2Hg01ktAtZCaQBdejHrkOBGwf5Q=="],
|
"es7-shim": ["es7-shim@6.0.0", "", { "dependencies": { "array-includes": "^3.0.2", "object.entries": "^1.0.3", "object.getownpropertydescriptors": "^2.0.2", "object.values": "^1.0.3", "string-at": "^1.0.1", "string.prototype.padend": "^3.0.0", "string.prototype.padstart": "^3.0.0", "string.prototype.trimleft": "^2.0.0", "string.prototype.trimright": "^2.0.0" } }, "sha512-aiQ/QyJBVJbabtsSediM1S4qI+P3p8F5J5YR5o/bH003BCnnclzxK9pi5Qd2Hg01ktAtZCaQBdejHrkOBGwf5Q=="],
|
||||||
|
|
||||||
"esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="],
|
"esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="],
|
||||||
@@ -1740,6 +1812,8 @@
|
|||||||
|
|
||||||
"extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="],
|
"extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="],
|
||||||
|
|
||||||
|
"farmhash-modern": ["farmhash-modern@1.1.0", "", {}, "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA=="],
|
||||||
|
|
||||||
"fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="],
|
"fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="],
|
||||||
|
|
||||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
@@ -1754,10 +1828,16 @@
|
|||||||
|
|
||||||
"fast-loops": ["fast-loops@1.1.4", "", {}, "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg=="],
|
"fast-loops": ["fast-loops@1.1.4", "", {}, "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg=="],
|
||||||
|
|
||||||
|
"fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="],
|
||||||
|
|
||||||
"fast-unique-numbers": ["fast-unique-numbers@8.0.13", "", { "dependencies": { "@babel/runtime": "^7.23.8", "tslib": "^2.6.2" } }, "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g=="],
|
"fast-unique-numbers": ["fast-unique-numbers@8.0.13", "", { "dependencies": { "@babel/runtime": "^7.23.8", "tslib": "^2.6.2" } }, "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g=="],
|
||||||
|
|
||||||
|
"fast-xml-parser": ["fast-xml-parser@4.5.3", "", { "dependencies": { "strnum": "^1.1.1" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig=="],
|
||||||
|
|
||||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
||||||
|
|
||||||
|
"faye-websocket": ["faye-websocket@0.11.4", "", { "dependencies": { "websocket-driver": ">=0.5.1" } }, "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g=="],
|
||||||
|
|
||||||
"fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="],
|
"fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="],
|
||||||
|
|
||||||
"fbemitter": ["fbemitter@3.0.0", "", { "dependencies": { "fbjs": "^3.0.0" } }, "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw=="],
|
"fbemitter": ["fbemitter@3.0.0", "", { "dependencies": { "fbjs": "^3.0.0" } }, "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw=="],
|
||||||
@@ -1788,6 +1868,8 @@
|
|||||||
|
|
||||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||||
|
|
||||||
|
"firebase-admin": ["firebase-admin@13.6.0", "", { "dependencies": { "@fastify/busboy": "^3.0.0", "@firebase/database-compat": "^2.0.0", "@firebase/database-types": "^1.0.6", "@types/node": "^22.8.7", "farmhash-modern": "^1.1.0", "fast-deep-equal": "^3.1.1", "google-auth-library": "^9.14.2", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", "node-forge": "^1.3.1", "uuid": "^11.0.2" }, "optionalDependencies": { "@google-cloud/firestore": "^7.11.0", "@google-cloud/storage": "^7.14.0" } }, "sha512-GdPA/t0+Cq8p1JnjFRBmxRxAGvF/kl2yfdhALl38PrRp325YxyQ5aNaHui0XmaKcKiGRFIJ/EgBNWFoDP0onjw=="],
|
||||||
|
|
||||||
"flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="],
|
"flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="],
|
||||||
|
|
||||||
"flatbuffers": ["flatbuffers@25.2.10", "", {}, "sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw=="],
|
"flatbuffers": ["flatbuffers@25.2.10", "", {}, "sha512-7JlN9ZvLDG1McO3kbX0k4v+SUAg48L1rIwEvN6ZQl/eCtgJz9UylTMzE9wrmYrcorgxm3CX/3T/w5VAub99UUw=="],
|
||||||
@@ -1838,8 +1920,14 @@
|
|||||||
|
|
||||||
"function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
|
"function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
|
||||||
|
|
||||||
|
"functional-red-black-tree": ["functional-red-black-tree@1.0.1", "", {}, "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g=="],
|
||||||
|
|
||||||
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
|
"functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
|
||||||
|
|
||||||
|
"gaxios": ["gaxios@6.7.1", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", "uuid": "^9.0.1" } }, "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ=="],
|
||||||
|
|
||||||
|
"gcp-metadata": ["gcp-metadata@6.1.1", "", { "dependencies": { "gaxios": "^6.1.1", "google-logging-utils": "^0.0.2", "json-bigint": "^1.0.0" } }, "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A=="],
|
||||||
|
|
||||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||||
|
|
||||||
"geojson-vt": ["geojson-vt@4.0.2", "", {}, "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A=="],
|
"geojson-vt": ["geojson-vt@4.0.2", "", {}, "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A=="],
|
||||||
@@ -1884,6 +1972,12 @@
|
|||||||
|
|
||||||
"gm": ["gm@1.25.1", "", { "dependencies": { "array-parallel": "~0.1.3", "array-series": "~0.1.5", "cross-spawn": "^7.0.5", "debug": "^3.1.0" } }, "sha512-jgcs2vKir9hFogGhXIfs0ODhJTfIrbECCehg38tqFgHm8zqXx7kAJyCYAFK4jTjx71AxrkFtkJBawbAxYUPX9A=="],
|
"gm": ["gm@1.25.1", "", { "dependencies": { "array-parallel": "~0.1.3", "array-series": "~0.1.5", "cross-spawn": "^7.0.5", "debug": "^3.1.0" } }, "sha512-jgcs2vKir9hFogGhXIfs0ODhJTfIrbECCehg38tqFgHm8zqXx7kAJyCYAFK4jTjx71AxrkFtkJBawbAxYUPX9A=="],
|
||||||
|
|
||||||
|
"google-auth-library": ["google-auth-library@9.15.1", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^6.1.1", "gcp-metadata": "^6.1.0", "gtoken": "^7.0.0", "jws": "^4.0.0" } }, "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng=="],
|
||||||
|
|
||||||
|
"google-gax": ["google-gax@4.6.1", "", { "dependencies": { "@grpc/grpc-js": "^1.10.9", "@grpc/proto-loader": "^0.7.13", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", "duplexify": "^4.0.0", "google-auth-library": "^9.3.0", "node-fetch": "^2.7.0", "object-hash": "^3.0.0", "proto3-json-serializer": "^2.0.2", "protobufjs": "^7.3.2", "retry-request": "^7.0.0", "uuid": "^9.0.1" } }, "sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ=="],
|
||||||
|
|
||||||
|
"google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="],
|
||||||
|
|
||||||
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
||||||
|
|
||||||
"gpt-3-encoder": ["gpt-3-encoder@1.1.4", "", {}, "sha512-fSQRePV+HUAhCn7+7HL7lNIXNm6eaFWFbNLOOGtmSJ0qJycyQvj60OvRlH7mee8xAMjBDNRdMXlMwjAbMTDjkg=="],
|
"gpt-3-encoder": ["gpt-3-encoder@1.1.4", "", {}, "sha512-fSQRePV+HUAhCn7+7HL7lNIXNm6eaFWFbNLOOGtmSJ0qJycyQvj60OvRlH7mee8xAMjBDNRdMXlMwjAbMTDjkg=="],
|
||||||
@@ -1894,6 +1988,8 @@
|
|||||||
|
|
||||||
"grid-index": ["grid-index@1.1.0", "", {}, "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA=="],
|
"grid-index": ["grid-index@1.1.0", "", {}, "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA=="],
|
||||||
|
|
||||||
|
"gtoken": ["gtoken@7.1.0", "", { "dependencies": { "gaxios": "^6.0.0", "jws": "^4.0.0" } }, "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw=="],
|
||||||
|
|
||||||
"guid-typescript": ["guid-typescript@1.0.9", "", {}, "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="],
|
"guid-typescript": ["guid-typescript@1.0.9", "", {}, "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ=="],
|
||||||
|
|
||||||
"has-ansi": ["has-ansi@2.0.0", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg=="],
|
"has-ansi": ["has-ansi@2.0.0", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg=="],
|
||||||
@@ -1938,16 +2034,22 @@
|
|||||||
|
|
||||||
"html-dom-parser": ["html-dom-parser@1.2.0", "", { "dependencies": { "domhandler": "4.3.1", "htmlparser2": "7.2.0" } }, "sha512-2HIpFMvvffsXHFUFjso0M9LqM+1Lm22BF+Df2ba+7QHJXjk63pWChEnI6YG27eaWqUdfnh5/Vy+OXrNTtepRsg=="],
|
"html-dom-parser": ["html-dom-parser@1.2.0", "", { "dependencies": { "domhandler": "4.3.1", "htmlparser2": "7.2.0" } }, "sha512-2HIpFMvvffsXHFUFjso0M9LqM+1Lm22BF+Df2ba+7QHJXjk63pWChEnI6YG27eaWqUdfnh5/Vy+OXrNTtepRsg=="],
|
||||||
|
|
||||||
|
"html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="],
|
||||||
|
|
||||||
"html-react-parser": ["html-react-parser@1.4.12", "", { "dependencies": { "domhandler": "4.3.1", "html-dom-parser": "1.2.0", "react-property": "2.0.0", "style-to-js": "1.1.0" }, "peerDependencies": { "react": "0.14 || 15 || 16 || 17 || 18" } }, "sha512-nqYQzr4uXh67G9ejAG7djupTHmQvSTgjY83zbXLRfKHJ0F06751jXx6WKSFARDdXxCngo2/7H4Rwtfeowql4gQ=="],
|
"html-react-parser": ["html-react-parser@1.4.12", "", { "dependencies": { "domhandler": "4.3.1", "html-dom-parser": "1.2.0", "react-property": "2.0.0", "style-to-js": "1.1.0" }, "peerDependencies": { "react": "0.14 || 15 || 16 || 17 || 18" } }, "sha512-nqYQzr4uXh67G9ejAG7djupTHmQvSTgjY83zbXLRfKHJ0F06751jXx6WKSFARDdXxCngo2/7H4Rwtfeowql4gQ=="],
|
||||||
|
|
||||||
|
"html-to-text": ["html-to-text@9.0.5", "", { "dependencies": { "@selderee/plugin-htmlparser2": "^0.11.0", "deepmerge": "^4.3.1", "dom-serializer": "^2.0.0", "htmlparser2": "^8.0.2", "selderee": "^0.11.0" } }, "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg=="],
|
||||||
|
|
||||||
"html-tokenize": ["html-tokenize@2.0.1", "", { "dependencies": { "buffer-from": "~0.1.1", "inherits": "~2.0.1", "minimist": "~1.2.5", "readable-stream": "~1.0.27-1", "through2": "~0.4.1" }, "bin": { "html-tokenize": "bin/cmd.js" } }, "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w=="],
|
"html-tokenize": ["html-tokenize@2.0.1", "", { "dependencies": { "buffer-from": "~0.1.1", "inherits": "~2.0.1", "minimist": "~1.2.5", "readable-stream": "~1.0.27-1", "through2": "~0.4.1" }, "bin": { "html-tokenize": "bin/cmd.js" } }, "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w=="],
|
||||||
|
|
||||||
"htmlparser2": ["htmlparser2@7.2.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } }, "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog=="],
|
"htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="],
|
||||||
|
|
||||||
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
||||||
|
|
||||||
"http-parser-js": ["http-parser-js@0.5.9", "", {}, "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw=="],
|
"http-parser-js": ["http-parser-js@0.5.9", "", {}, "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw=="],
|
||||||
|
|
||||||
|
"http-proxy-agent": ["http-proxy-agent@5.0.0", "", { "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w=="],
|
||||||
|
|
||||||
"http_ece": ["http_ece@1.2.0", "", {}, "sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA=="],
|
"http_ece": ["http_ece@1.2.0", "", {}, "sha512-JrF8SSLVmcvc5NducxgyOrKXe3EsyHMgBFgSaIUGmArKe+rwr0uphRkRXvwiom3I+fpIfoItveHrfudL8/rxuA=="],
|
||||||
|
|
||||||
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||||
@@ -2130,6 +2232,8 @@
|
|||||||
|
|
||||||
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
||||||
|
|
||||||
|
"json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="],
|
||||||
|
|
||||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||||
|
|
||||||
"json-parse-better-errors": ["json-parse-better-errors@1.0.2", "", {}, "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="],
|
"json-parse-better-errors": ["json-parse-better-errors@1.0.2", "", {}, "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="],
|
||||||
@@ -2148,11 +2252,15 @@
|
|||||||
|
|
||||||
"jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="],
|
"jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="],
|
||||||
|
|
||||||
|
"jsonwebtoken": ["jsonwebtoken@9.0.3", "", { "dependencies": { "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g=="],
|
||||||
|
|
||||||
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
|
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
|
||||||
|
|
||||||
"jwa": ["jwa@2.0.0", "", { "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA=="],
|
"jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="],
|
||||||
|
|
||||||
"jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="],
|
"jwks-rsa": ["jwks-rsa@3.2.0", "", { "dependencies": { "@types/express": "^4.17.20", "@types/jsonwebtoken": "^9.0.4", "debug": "^4.3.4", "jose": "^4.15.4", "limiter": "^1.1.5", "lru-memoizer": "^2.2.0" } }, "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww=="],
|
||||||
|
|
||||||
|
"jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="],
|
||||||
|
|
||||||
"kdbush": ["kdbush@4.0.2", "", {}, "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="],
|
"kdbush": ["kdbush@4.0.2", "", {}, "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="],
|
||||||
|
|
||||||
@@ -2170,6 +2278,8 @@
|
|||||||
|
|
||||||
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
|
"language-tags": ["language-tags@1.0.9", "", { "dependencies": { "language-subtag-registry": "^0.3.20" } }, "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA=="],
|
||||||
|
|
||||||
|
"leac": ["leac@0.6.0", "", {}, "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg=="],
|
||||||
|
|
||||||
"leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
|
"leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
|
||||||
|
|
||||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||||
@@ -2200,6 +2310,8 @@
|
|||||||
|
|
||||||
"lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
|
"lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
|
||||||
|
|
||||||
|
"limiter": ["limiter@1.1.5", "", {}, "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA=="],
|
||||||
|
|
||||||
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
||||||
|
|
||||||
"linkify-it": ["linkify-it@5.0.0", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ=="],
|
"linkify-it": ["linkify-it@5.0.0", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ=="],
|
||||||
@@ -2214,6 +2326,8 @@
|
|||||||
|
|
||||||
"lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
|
"lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
|
||||||
|
|
||||||
|
"lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
|
||||||
|
|
||||||
"lodash.chunk": ["lodash.chunk@4.2.0", "", {}, "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w=="],
|
"lodash.chunk": ["lodash.chunk@4.2.0", "", {}, "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w=="],
|
||||||
|
|
||||||
"lodash.clonedeep": ["lodash.clonedeep@4.5.0", "", {}, "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="],
|
"lodash.clonedeep": ["lodash.clonedeep@4.5.0", "", {}, "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="],
|
||||||
@@ -2222,8 +2336,22 @@
|
|||||||
|
|
||||||
"lodash.flatten": ["lodash.flatten@4.4.0", "", {}, "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="],
|
"lodash.flatten": ["lodash.flatten@4.4.0", "", {}, "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="],
|
||||||
|
|
||||||
|
"lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="],
|
||||||
|
|
||||||
|
"lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="],
|
||||||
|
|
||||||
|
"lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="],
|
||||||
|
|
||||||
|
"lodash.isnumber": ["lodash.isnumber@3.0.3", "", {}, "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="],
|
||||||
|
|
||||||
|
"lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
|
||||||
|
|
||||||
|
"lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="],
|
||||||
|
|
||||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||||
|
|
||||||
|
"lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="],
|
||||||
|
|
||||||
"lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
|
"lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="],
|
||||||
|
|
||||||
"log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="],
|
"log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="],
|
||||||
@@ -2236,6 +2364,8 @@
|
|||||||
|
|
||||||
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
|
"lru-memoizer": ["lru-memoizer@2.3.0", "", { "dependencies": { "lodash.clonedeep": "^4.5.0", "lru-cache": "6.0.0" } }, "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug=="],
|
||||||
|
|
||||||
"make-cancellable-promise": ["make-cancellable-promise@1.3.2", "", {}, "sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww=="],
|
"make-cancellable-promise": ["make-cancellable-promise@1.3.2", "", {}, "sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww=="],
|
||||||
|
|
||||||
"make-dir": ["make-dir@2.1.0", "", { "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" } }, "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA=="],
|
"make-dir": ["make-dir@2.1.0", "", { "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" } }, "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA=="],
|
||||||
@@ -2314,7 +2444,7 @@
|
|||||||
|
|
||||||
"midtrans-client": ["midtrans-client@1.4.2", "", { "dependencies": { "axios": "^0.26.0", "lodash": "^4.17.21" } }, "sha512-hGT6UDF6WsmOprJYdgxReT5qxOPj+9VGVbJTe6txYICkadI01yC1ApBlkf+5AH/2v4fWNo03421VVpNfJDFAyg=="],
|
"midtrans-client": ["midtrans-client@1.4.2", "", { "dependencies": { "axios": "^0.26.0", "lodash": "^4.17.21" } }, "sha512-hGT6UDF6WsmOprJYdgxReT5qxOPj+9VGVbJTe6txYICkadI01yC1ApBlkf+5AH/2v4fWNo03421VVpNfJDFAyg=="],
|
||||||
|
|
||||||
"mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
|
"mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
|
||||||
|
|
||||||
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||||
|
|
||||||
@@ -2504,6 +2634,8 @@
|
|||||||
|
|
||||||
"parse-svg-path": ["parse-svg-path@0.1.2", "", {}, "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="],
|
"parse-svg-path": ["parse-svg-path@0.1.2", "", {}, "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="],
|
||||||
|
|
||||||
|
"parseley": ["parseley@0.12.1", "", { "dependencies": { "leac": "^0.6.0", "peberminta": "^0.9.0" } }, "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw=="],
|
||||||
|
|
||||||
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
|
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
|
||||||
|
|
||||||
"password-prompt": ["password-prompt@1.1.3", "", { "dependencies": { "ansi-escapes": "^4.3.2", "cross-spawn": "^7.0.3" } }, "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw=="],
|
"password-prompt": ["password-prompt@1.1.3", "", { "dependencies": { "ansi-escapes": "^4.3.2", "cross-spawn": "^7.0.3" } }, "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw=="],
|
||||||
@@ -2530,6 +2662,8 @@
|
|||||||
|
|
||||||
"pdfjs-dist": ["pdfjs-dist@4.10.38", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.65" } }, "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ=="],
|
"pdfjs-dist": ["pdfjs-dist@4.10.38", "", { "optionalDependencies": { "@napi-rs/canvas": "^0.1.65" } }, "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ=="],
|
||||||
|
|
||||||
|
"peberminta": ["peberminta@0.9.0", "", {}, "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ=="],
|
||||||
|
|
||||||
"peerjs": ["peerjs@1.5.4", "", { "dependencies": { "@msgpack/msgpack": "^2.8.0", "eventemitter3": "^4.0.7", "peerjs-js-binarypack": "^2.1.0", "webrtc-adapter": "^9.0.0" } }, "sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw=="],
|
"peerjs": ["peerjs@1.5.4", "", { "dependencies": { "@msgpack/msgpack": "^2.8.0", "eventemitter3": "^4.0.7", "peerjs-js-binarypack": "^2.1.0", "webrtc-adapter": "^9.0.0" } }, "sha512-yFsoLMnurJKlQbx6kVSBpOp+AlNldY1JQS2BrSsHLKCZnq6t7saHleuHM5svuLNbQkUJXHLF3sKOJB1K0xulOw=="],
|
||||||
|
|
||||||
"peerjs-js-binarypack": ["peerjs-js-binarypack@2.1.0", "", {}, "sha512-YIwCC+pTzp3Bi8jPI9UFKO0t0SLo6xALnHkiNt/iUFmUUZG0fEEmEyFKvjsDKweiFitzHRyhuh6NvyJZ4nNxMg=="],
|
"peerjs-js-binarypack": ["peerjs-js-binarypack@2.1.0", "", {}, "sha512-YIwCC+pTzp3Bi8jPI9UFKO0t0SLo6xALnHkiNt/iUFmUUZG0fEEmEyFKvjsDKweiFitzHRyhuh6NvyJZ4nNxMg=="],
|
||||||
@@ -2578,7 +2712,7 @@
|
|||||||
|
|
||||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||||
|
|
||||||
"prettier": ["prettier@3.5.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg=="],
|
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||||
|
|
||||||
"pretty-bytes": ["pretty-bytes@5.6.0", "", {}, "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg=="],
|
"pretty-bytes": ["pretty-bytes@5.6.0", "", {}, "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg=="],
|
||||||
|
|
||||||
@@ -2636,6 +2770,8 @@
|
|||||||
|
|
||||||
"prosemirror-view": ["prosemirror-view@1.38.0", "", { "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0" } }, "sha512-O45kxXQTaP9wPdXhp8TKqCR+/unS/gnfg9Q93svQcB3j0mlp2XSPAmsPefxHADwzC+fbNS404jqRxm3UQaGvgw=="],
|
"prosemirror-view": ["prosemirror-view@1.38.0", "", { "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0" } }, "sha512-O45kxXQTaP9wPdXhp8TKqCR+/unS/gnfg9Q93svQcB3j0mlp2XSPAmsPefxHADwzC+fbNS404jqRxm3UQaGvgw=="],
|
||||||
|
|
||||||
|
"proto3-json-serializer": ["proto3-json-serializer@2.0.2", "", { "dependencies": { "protobufjs": "^7.2.5" } }, "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ=="],
|
||||||
|
|
||||||
"protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
|
"protobufjs": ["protobufjs@7.4.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw=="],
|
||||||
|
|
||||||
"protocol-buffers-schema": ["protocol-buffers-schema@3.6.0", "", {}, "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="],
|
"protocol-buffers-schema": ["protocol-buffers-schema@3.6.0", "", {}, "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="],
|
||||||
@@ -2656,6 +2792,8 @@
|
|||||||
|
|
||||||
"qrcode-terminal": ["qrcode-terminal@0.11.0", "", { "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ=="],
|
"qrcode-terminal": ["qrcode-terminal@0.11.0", "", { "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ=="],
|
||||||
|
|
||||||
|
"querystringify": ["querystringify@2.2.0", "", {}, "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="],
|
||||||
|
|
||||||
"queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="],
|
"queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="],
|
||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||||
@@ -2770,6 +2908,10 @@
|
|||||||
|
|
||||||
"requireg": ["requireg@0.2.2", "", { "dependencies": { "nested-error-stacks": "~2.0.1", "rc": "~1.2.7", "resolve": "~1.7.1" } }, "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg=="],
|
"requireg": ["requireg@0.2.2", "", { "dependencies": { "nested-error-stacks": "~2.0.1", "rc": "~1.2.7", "resolve": "~1.7.1" } }, "sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg=="],
|
||||||
|
|
||||||
|
"requires-port": ["requires-port@1.0.0", "", {}, "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="],
|
||||||
|
|
||||||
|
"resend": ["resend@6.4.2", "", { "dependencies": { "svix": "1.76.1" }, "peerDependencies": { "@react-email/render": "*" }, "optionalPeers": ["@react-email/render"] }, "sha512-YnxmwneltZtjc7Xff+8ZjG1/xPLdstCiqsedgO/JxWTf7vKRAPCx6CkhQ3ZXskG0mrmf8+I5wr/wNRd8PQMUfw=="],
|
||||||
|
|
||||||
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
||||||
|
|
||||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||||
@@ -2788,6 +2930,10 @@
|
|||||||
|
|
||||||
"retimer": ["retimer@3.0.0", "", {}, "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA=="],
|
"retimer": ["retimer@3.0.0", "", {}, "sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA=="],
|
||||||
|
|
||||||
|
"retry": ["retry@0.13.1", "", {}, "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="],
|
||||||
|
|
||||||
|
"retry-request": ["retry-request@7.0.2", "", { "dependencies": { "@types/request": "^2.48.8", "extend": "^3.0.2", "teeny-request": "^9.0.0" } }, "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w=="],
|
||||||
|
|
||||||
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
||||||
|
|
||||||
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
|
"rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
|
||||||
@@ -2818,6 +2964,8 @@
|
|||||||
|
|
||||||
"sdp": ["sdp@3.2.0", "", {}, "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="],
|
"sdp": ["sdp@3.2.0", "", {}, "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="],
|
||||||
|
|
||||||
|
"selderee": ["selderee@0.11.0", "", { "dependencies": { "parseley": "^0.12.0" } }, "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA=="],
|
||||||
|
|
||||||
"selfsigned": ["selfsigned@2.4.1", "", { "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" } }, "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q=="],
|
"selfsigned": ["selfsigned@2.4.1", "", { "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" } }, "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q=="],
|
||||||
|
|
||||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
||||||
@@ -2922,6 +3070,10 @@
|
|||||||
|
|
||||||
"stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="],
|
"stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="],
|
||||||
|
|
||||||
|
"stream-events": ["stream-events@1.0.5", "", { "dependencies": { "stubs": "^3.0.0" } }, "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg=="],
|
||||||
|
|
||||||
|
"stream-shift": ["stream-shift@1.0.3", "", {}, "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ=="],
|
||||||
|
|
||||||
"streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="],
|
"streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="],
|
||||||
|
|
||||||
"string-at": ["string-at@1.1.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" } }, "sha512-jCpPowWKBn0NFdvtmK2qxK40Ol4jPcgCt8qYnKpPx6B5eDwHMDhRvq9MCsDEgsOTNtbXY6beAMHMRT2qPJXllA=="],
|
"string-at": ["string-at@1.1.0", "", { "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" } }, "sha512-jCpPowWKBn0NFdvtmK2qxK40Ol4jPcgCt8qYnKpPx6B5eDwHMDhRvq9MCsDEgsOTNtbXY6beAMHMRT2qPJXllA=="],
|
||||||
@@ -2962,8 +3114,12 @@
|
|||||||
|
|
||||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||||
|
|
||||||
|
"strnum": ["strnum@1.1.2", "", {}, "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA=="],
|
||||||
|
|
||||||
"structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="],
|
"structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="],
|
||||||
|
|
||||||
|
"stubs": ["stubs@3.0.0", "", {}, "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw=="],
|
||||||
|
|
||||||
"style-to-js": ["style-to-js@1.1.0", "", { "dependencies": { "style-to-object": "0.3.0" } }, "sha512-1OqefPDxGrlMwcbfpsTVRyzwdhr4W0uxYQzeA2F1CBc8WG04udg2+ybRnvh3XYL4TdHQrCahLtax2jc8xaE6rA=="],
|
"style-to-js": ["style-to-js@1.1.0", "", { "dependencies": { "style-to-object": "0.3.0" } }, "sha512-1OqefPDxGrlMwcbfpsTVRyzwdhr4W0uxYQzeA2F1CBc8WG04udg2+ybRnvh3XYL4TdHQrCahLtax2jc8xaE6rA=="],
|
||||||
|
|
||||||
"style-to-object": ["style-to-object@0.3.0", "", { "dependencies": { "inline-style-parser": "0.1.1" } }, "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA=="],
|
"style-to-object": ["style-to-object@0.3.0", "", { "dependencies": { "inline-style-parser": "0.1.1" } }, "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA=="],
|
||||||
@@ -2992,6 +3148,8 @@
|
|||||||
|
|
||||||
"svg-arc-to-cubic-bezier": ["svg-arc-to-cubic-bezier@3.2.0", "", {}, "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g=="],
|
"svg-arc-to-cubic-bezier": ["svg-arc-to-cubic-bezier@3.2.0", "", {}, "sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g=="],
|
||||||
|
|
||||||
|
"svix": ["svix@1.76.1", "", { "dependencies": { "@stablelib/base64": "^1.0.0", "@types/node": "^22.7.5", "es6-promise": "^4.2.8", "fast-sha256": "^1.3.0", "url-parse": "^1.5.10", "uuid": "^10.0.0" } }, "sha512-CRuDWBTgYfDnBLRaZdKp9VuoPcNUq9An14c/k+4YJ15Qc5Grvf66vp0jvTltd4t7OIRj+8lM1DAgvSgvf7hdLw=="],
|
||||||
|
|
||||||
"swr": ["swr@2.3.2", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-RosxFpiabojs75IwQ316DGoDRmOqtiAj0tg8wCcbEu4CiLZBs/a9QNtHV7TUfDXmmlgqij/NqzKq/eLelyv9xA=="],
|
"swr": ["swr@2.3.2", "", { "dependencies": { "dequal": "^2.0.3", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-RosxFpiabojs75IwQ316DGoDRmOqtiAj0tg8wCcbEu4CiLZBs/a9QNtHV7TUfDXmmlgqij/NqzKq/eLelyv9xA=="],
|
||||||
|
|
||||||
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
|
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
|
||||||
@@ -3006,6 +3164,8 @@
|
|||||||
|
|
||||||
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
|
||||||
|
|
||||||
|
"teeny-request": ["teeny-request@9.0.0", "", { "dependencies": { "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.9", "stream-events": "^1.0.5", "uuid": "^9.0.0" } }, "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g=="],
|
||||||
|
|
||||||
"temp": ["temp@0.8.4", "", { "dependencies": { "rimraf": "~2.6.2" } }, "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg=="],
|
"temp": ["temp@0.8.4", "", { "dependencies": { "rimraf": "~2.6.2" } }, "sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg=="],
|
||||||
|
|
||||||
"temp-dir": ["temp-dir@2.0.0", "", {}, "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg=="],
|
"temp-dir": ["temp-dir@2.0.0", "", {}, "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg=="],
|
||||||
@@ -3106,7 +3266,7 @@
|
|||||||
|
|
||||||
"undici": ["undici@6.21.1", "", {}, "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ=="],
|
"undici": ["undici@6.21.1", "", {}, "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||||
|
|
||||||
"unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="],
|
"unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="],
|
||||||
|
|
||||||
@@ -3140,6 +3300,8 @@
|
|||||||
|
|
||||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||||
|
|
||||||
|
"url-parse": ["url-parse@1.5.10", "", { "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ=="],
|
||||||
|
|
||||||
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
|
"use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="],
|
||||||
|
|
||||||
"use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="],
|
"use-composed-ref": ["use-composed-ref@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w=="],
|
||||||
@@ -3194,6 +3356,10 @@
|
|||||||
|
|
||||||
"webrtc-adapter": ["webrtc-adapter@9.0.1", "", { "dependencies": { "sdp": "^3.2.0" } }, "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ=="],
|
"webrtc-adapter": ["webrtc-adapter@9.0.1", "", { "dependencies": { "sdp": "^3.2.0" } }, "sha512-1AQO+d4ElfVSXyzNVTOewgGT/tAomwwztX/6e3totvyyzXPvXIIuUUjAmyZGbKBKbZOXauuJooZm3g6IuFuiNQ=="],
|
||||||
|
|
||||||
|
"websocket-driver": ["websocket-driver@0.7.4", "", { "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg=="],
|
||||||
|
|
||||||
|
"websocket-extensions": ["websocket-extensions@0.1.4", "", {}, "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="],
|
||||||
|
|
||||||
"whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="],
|
"whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="],
|
||||||
|
|
||||||
"whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
|
"whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
|
||||||
@@ -3378,6 +3544,22 @@
|
|||||||
|
|
||||||
"@expo/xcpretty/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
|
"@expo/xcpretty/@babel/code-frame": ["@babel/code-frame@7.10.4", "", { "dependencies": { "@babel/highlight": "^7.10.4" } }, "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg=="],
|
||||||
|
|
||||||
|
"@firebase/component/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@firebase/database/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@firebase/database-compat/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@firebase/logger/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@firebase/util/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@google-cloud/storage/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||||
|
|
||||||
|
"@google-cloud/storage/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
|
||||||
|
|
||||||
|
"@grpc/grpc-js/@grpc/proto-loader": ["@grpc/proto-loader@0.8.0", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.5.3", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ=="],
|
||||||
|
|
||||||
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
|
||||||
|
|
||||||
"@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
|
"@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
|
||||||
@@ -3430,8 +3612,16 @@
|
|||||||
|
|
||||||
"@react-pdf/types/@react-pdf/stylesheet": ["@react-pdf/stylesheet@6.0.0", "", { "dependencies": { "@react-pdf/fns": "3.1.1", "@react-pdf/types": "^2.8.0", "color-string": "^1.9.1", "hsl-to-hex": "^1.0.0", "media-engine": "^1.0.3", "postcss-value-parser": "^4.1.0" } }, "sha512-uAwuMjbcEaxhRl7tGlqxAbLzo/KoYr6v9JksUJwgzd+rkvAp8jDq8NcG3sUp88tzgIyyRjBGl4FewgdxbAa2uw=="],
|
"@react-pdf/types/@react-pdf/stylesheet": ["@react-pdf/stylesheet@6.0.0", "", { "dependencies": { "@react-pdf/fns": "3.1.1", "@react-pdf/types": "^2.8.0", "color-string": "^1.9.1", "hsl-to-hex": "^1.0.0", "media-engine": "^1.0.3", "postcss-value-parser": "^4.1.0" } }, "sha512-uAwuMjbcEaxhRl7tGlqxAbLzo/KoYr6v9JksUJwgzd+rkvAp8jDq8NcG3sUp88tzgIyyRjBGl4FewgdxbAa2uw=="],
|
||||||
|
|
||||||
|
"@selderee/plugin-htmlparser2/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||||
|
|
||||||
"@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"@types/jsonwebtoken/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||||
|
|
||||||
|
"@types/request/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||||
|
|
||||||
|
"@types/request/form-data": ["form-data@2.5.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" } }, "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
"aria-hidden/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"aria-hidden/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
@@ -3440,6 +3630,8 @@
|
|||||||
|
|
||||||
"ast-types/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"ast-types/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"autoprefixer/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||||
|
|
||||||
"babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
|
"better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
|
||||||
@@ -3448,6 +3640,8 @@
|
|||||||
|
|
||||||
"blessed-contrib/strip-ansi": ["strip-ansi@3.0.1", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="],
|
"blessed-contrib/strip-ansi": ["strip-ansi@3.0.1", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg=="],
|
||||||
|
|
||||||
|
"browserslist/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||||
|
|
||||||
"cacache/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
"cacache/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||||
|
|
||||||
"caller-callsite/callsites": ["callsites@2.0.0", "", {}, "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ=="],
|
"caller-callsite/callsites": ["callsites@2.0.0", "", {}, "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ=="],
|
||||||
@@ -3478,12 +3672,16 @@
|
|||||||
|
|
||||||
"defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
|
"defaults/clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="],
|
||||||
|
|
||||||
"dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
|
"dom-serializer/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||||
|
|
||||||
|
"domutils/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||||
|
|
||||||
"drawille-canvas-blessed-contrib/gl-matrix": ["gl-matrix@2.8.1", "", {}, "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw=="],
|
"drawille-canvas-blessed-contrib/gl-matrix": ["gl-matrix@2.8.1", "", {}, "sha512-0YCjVpE3pS5XWlN3J4X7AiAx65+nqAI54LndtVFnQZB6G/FVLkZH8y8V6R3cIoOQR4pUdfwQGd1iwyoXHJ4Qfw=="],
|
||||||
|
|
||||||
"duplexer2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
"duplexer2/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
||||||
|
|
||||||
|
"duplexify/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||||
|
|
||||||
"ecdsa-sig-formatter/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
"ecdsa-sig-formatter/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"engine.io-client/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
"engine.io-client/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
|
||||||
@@ -3540,17 +3738,29 @@
|
|||||||
|
|
||||||
"finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="],
|
"finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="],
|
||||||
|
|
||||||
|
"firebase-admin/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||||
|
|
||||||
|
"firebase-admin/uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
||||||
|
|
||||||
"fontkit/@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
"fontkit/@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||||
|
|
||||||
"formdata-node/web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="],
|
"formdata-node/web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="],
|
||||||
|
|
||||||
|
"gaxios/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
|
||||||
|
|
||||||
"gm/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
"gm/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||||
|
|
||||||
|
"google-gax/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
|
||||||
|
|
||||||
"has-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="],
|
"has-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="],
|
||||||
|
|
||||||
|
"html-dom-parser/htmlparser2": ["htmlparser2@7.2.0", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } }, "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog=="],
|
||||||
|
|
||||||
"html-tokenize/readable-stream": ["readable-stream@1.0.34", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg=="],
|
"html-tokenize/readable-stream": ["readable-stream@1.0.34", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg=="],
|
||||||
|
|
||||||
"htmlparser2/entities": ["entities@3.0.1", "", {}, "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q=="],
|
"htmlparser2/domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||||
|
|
||||||
|
"http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||||
|
|
||||||
"hyperid/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
"hyperid/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||||
|
|
||||||
@@ -3568,6 +3778,8 @@
|
|||||||
|
|
||||||
"jwa/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
"jwa/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
|
"jwks-rsa/jose": ["jose@4.15.9", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="],
|
||||||
|
|
||||||
"jws/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
"jws/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
@@ -3576,6 +3788,8 @@
|
|||||||
|
|
||||||
"log-symbols/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
|
"log-symbols/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
|
||||||
|
|
||||||
|
"lru-memoizer/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
|
||||||
|
|
||||||
"make-dir/pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="],
|
"make-dir/pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="],
|
||||||
|
|
||||||
"make-dir/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
|
"make-dir/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
|
||||||
@@ -3602,12 +3816,16 @@
|
|||||||
|
|
||||||
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"next/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||||
|
|
||||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||||
|
|
||||||
"next-dev/@mantine/hooks": ["@mantine/hooks@7.17.0", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-vo3K49mLy1nJ8LQNb5KDbJgnX0xwt3Y8JOF3ythjB5LEFMptdLSSgulu64zj+QHtzvffFCsMb05DbTLLpVP/JQ=="],
|
"next-dev/@mantine/hooks": ["@mantine/hooks@7.17.0", "", { "peerDependencies": { "react": "^18.x || ^19.x" } }, "sha512-vo3K49mLy1nJ8LQNb5KDbJgnX0xwt3Y8JOF3ythjB5LEFMptdLSSgulu64zj+QHtzvffFCsMb05DbTLLpVP/JQ=="],
|
||||||
|
|
||||||
"next-dev/axios": ["axios@1.8.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g=="],
|
"next-dev/axios": ["axios@1.8.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g=="],
|
||||||
|
|
||||||
|
"next-dev/prettier": ["prettier@3.5.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg=="],
|
||||||
|
|
||||||
"next-dev/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="],
|
"next-dev/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="],
|
||||||
|
|
||||||
"next-dev/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="],
|
"next-dev/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="],
|
||||||
@@ -3650,6 +3868,8 @@
|
|||||||
|
|
||||||
"pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
"pretty-format/react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
|
||||||
|
|
||||||
|
"proto3-json-serializer/protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
|
||||||
|
|
||||||
"pvtsutils/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"pvtsutils/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
|
||||||
@@ -3692,6 +3912,8 @@
|
|||||||
|
|
||||||
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
|
|
||||||
|
"send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
|
||||||
|
|
||||||
"serve-static/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
|
"serve-static/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
|
||||||
|
|
||||||
"simple-plist/bplist-creator": ["bplist-creator@0.1.0", "", { "dependencies": { "stream-buffers": "2.2.x" } }, "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg=="],
|
"simple-plist/bplist-creator": ["bplist-creator@0.1.0", "", { "dependencies": { "stream-buffers": "2.2.x" } }, "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg=="],
|
||||||
@@ -3726,6 +3948,10 @@
|
|||||||
|
|
||||||
"sucrase/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
"sucrase/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||||
|
|
||||||
|
"svix/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||||
|
|
||||||
|
"svix/uuid": ["uuid@10.0.0", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ=="],
|
||||||
|
|
||||||
"tar/fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
"tar/fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
||||||
|
|
||||||
"tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
"tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
||||||
@@ -3738,6 +3964,10 @@
|
|||||||
|
|
||||||
"tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
"tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
|
||||||
|
|
||||||
|
"teeny-request/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
|
||||||
|
|
||||||
|
"teeny-request/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
|
||||||
|
|
||||||
"temp/rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="],
|
"temp/rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="],
|
||||||
|
|
||||||
"tempy/type-fest": ["type-fest@0.16.0", "", {}, "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg=="],
|
"tempy/type-fest": ["type-fest@0.16.0", "", {}, "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg=="],
|
||||||
@@ -3762,8 +3992,12 @@
|
|||||||
|
|
||||||
"use-sidecar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"use-sidecar/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"web-push/jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="],
|
||||||
|
|
||||||
"webcrypto-core/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"webcrypto-core/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"websocket-driver/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
|
"whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
|
||||||
|
|
||||||
"whatwg-url-without-unicode/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
"whatwg-url-without-unicode/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
|
||||||
@@ -3848,6 +4082,10 @@
|
|||||||
|
|
||||||
"@expo/prebuild-config/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
|
"@expo/prebuild-config/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
|
||||||
|
|
||||||
|
"@google-cloud/storage/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||||
|
|
||||||
|
"@grpc/grpc-js/@grpc/proto-loader/protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
|
||||||
|
|
||||||
"@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
"@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
"@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
|
"@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
|
||||||
@@ -3876,6 +4114,8 @@
|
|||||||
|
|
||||||
"@react-pdf/types/@react-pdf/stylesheet/@react-pdf/fns": ["@react-pdf/fns@3.1.1", "", {}, "sha512-fYvgOWWRxTdkCciLSla2iek8W/oDLhExPTLPw3aArGPJHgVUc86V2c3YLULNHIBuy/64QVpPLB7gwNkTEW5m/A=="],
|
"@react-pdf/types/@react-pdf/stylesheet/@react-pdf/fns": ["@react-pdf/fns@3.1.1", "", {}, "sha512-fYvgOWWRxTdkCciLSla2iek8W/oDLhExPTLPw3aArGPJHgVUc86V2c3YLULNHIBuy/64QVpPLB7gwNkTEW5m/A=="],
|
||||||
|
|
||||||
|
"@types/request/form-data/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||||
|
|
||||||
"blessed-contrib/chalk/ansi-styles": ["ansi-styles@2.2.1", "", {}, "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="],
|
"blessed-contrib/chalk/ansi-styles": ["ansi-styles@2.2.1", "", {}, "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="],
|
||||||
@@ -3922,6 +4162,10 @@
|
|||||||
|
|
||||||
"fontkit/@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"fontkit/@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"html-dom-parser/htmlparser2/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="],
|
||||||
|
|
||||||
|
"html-dom-parser/htmlparser2/entities": ["entities@3.0.1", "", {}, "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q=="],
|
||||||
|
|
||||||
"html-tokenize/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="],
|
"html-tokenize/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="],
|
||||||
|
|
||||||
"lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
"lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||||
@@ -3958,6 +4202,8 @@
|
|||||||
|
|
||||||
"onnxruntime-node/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
"onnxruntime-node/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||||
|
|
||||||
|
"openai/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||||
|
|
||||||
"ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
|
"ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
|
||||||
|
|
||||||
"ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
"ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="],
|
||||||
@@ -3972,12 +4218,16 @@
|
|||||||
|
|
||||||
"pkg-dir/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="],
|
"pkg-dir/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="],
|
||||||
|
|
||||||
|
"proto3-json-serializer/protobufjs/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||||
|
|
||||||
"send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
"send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
|
||||||
|
|
||||||
"serve-static/send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
"serve-static/send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
|
||||||
|
|
||||||
"serve-static/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
|
"serve-static/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
|
||||||
|
|
||||||
|
"serve-static/send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
|
||||||
|
|
||||||
"split-string/extend-shallow/is-extendable": ["is-extendable@1.0.1", "", { "dependencies": { "is-plain-object": "^2.0.4" } }, "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA=="],
|
"split-string/extend-shallow/is-extendable": ["is-extendable@1.0.1", "", { "dependencies": { "is-plain-object": "^2.0.4" } }, "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA=="],
|
||||||
|
|
||||||
"sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
@@ -3986,10 +4236,16 @@
|
|||||||
|
|
||||||
"tar/fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
"tar/fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
||||||
|
|
||||||
|
"teeny-request/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||||
|
|
||||||
"terminal-link/ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
|
"terminal-link/ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="],
|
||||||
|
|
||||||
"through2/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="],
|
"through2/readable-stream/string_decoder": ["string_decoder@0.10.31", "", {}, "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="],
|
||||||
|
|
||||||
|
"web-push/jws/jwa": ["jwa@2.0.0", "", { "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA=="],
|
||||||
|
|
||||||
|
"web-push/jws/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
||||||
|
|
||||||
"wibu-pkg/@mantine/core/@floating-ui/react": ["@floating-ui/react@0.26.28", "", { "dependencies": { "@floating-ui/react-dom": "^2.1.2", "@floating-ui/utils": "^0.2.8", "tabbable": "^6.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw=="],
|
"wibu-pkg/@mantine/core/@floating-ui/react": ["@floating-ui/react@0.26.28", "", { "dependencies": { "@floating-ui/react-dom": "^2.1.2", "@floating-ui/utils": "^0.2.8", "tabbable": "^6.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw=="],
|
||||||
|
|
||||||
"wibu-pkg/@mantine/core/react-textarea-autosize": ["react-textarea-autosize@8.5.6", "", { "dependencies": { "@babel/runtime": "^7.20.13", "use-composed-ref": "^1.3.0", "use-latest": "^1.2.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-aT3ioKXMa8f6zHYGebhbdMD2L00tKeRX1zuVuDx9YQK/JLLRSaSxq3ugECEmUB9z2kvk6bFSIoRHLkkUv0RJiw=="],
|
"wibu-pkg/@mantine/core/react-textarea-autosize": ["react-textarea-autosize@8.5.6", "", { "dependencies": { "@babel/runtime": "^7.20.13", "use-composed-ref": "^1.3.0", "use-latest": "^1.2.1" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-aT3ioKXMa8f6zHYGebhbdMD2L00tKeRX1zuVuDx9YQK/JLLRSaSxq3ugECEmUB9z2kvk6bFSIoRHLkkUv0RJiw=="],
|
||||||
@@ -4024,6 +4280,8 @@
|
|||||||
|
|
||||||
"wibu/next/@swc/helpers": ["@swc/helpers@0.5.5", "", { "dependencies": { "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A=="],
|
"wibu/next/@swc/helpers": ["@swc/helpers@0.5.5", "", { "dependencies": { "@swc/counter": "^0.1.3", "tslib": "^2.4.0" } }, "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A=="],
|
||||||
|
|
||||||
|
"wibu/next/caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
|
||||||
|
|
||||||
"wibu/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
"wibu/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||||
|
|
||||||
"wibu/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
|
"wibu/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
|
||||||
@@ -4044,6 +4302,8 @@
|
|||||||
|
|
||||||
"@expo/metro-config/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
"@expo/metro-config/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||||
|
|
||||||
|
"@grpc/grpc-js/@grpc/proto-loader/protobufjs/@types/node": ["@types/node@22.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ=="],
|
||||||
|
|
||||||
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
|
||||||
|
|
||||||
"@react-native/babel-plugin-codegen/@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.23.1", "", {}, "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg=="],
|
"@react-native/babel-plugin-codegen/@react-native/codegen/hermes-parser/hermes-estree": ["hermes-estree@0.23.1", "", {}, "sha512-eT5MU3f5aVhTqsfIReZ6n41X5sYn4IdQL0nvz6yO+MMlPxw49aSARHLg/MSehQftyjnrE8X6bYregzSumqc6cg=="],
|
||||||
@@ -4058,6 +4318,8 @@
|
|||||||
|
|
||||||
"execa/cross-spawn/shebang-command/shebang-regex": ["shebang-regex@1.0.0", "", {}, "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="],
|
"execa/cross-spawn/shebang-command/shebang-regex": ["shebang-regex@1.0.0", "", {}, "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="],
|
||||||
|
|
||||||
|
"html-dom-parser/htmlparser2/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
|
||||||
|
|
||||||
"log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
|
"log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
|
||||||
|
|
||||||
"log-symbols/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
|
"log-symbols/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
|
||||||
@@ -4098,6 +4360,8 @@
|
|||||||
|
|
||||||
"eslint-config-next/@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
"eslint-config-next/@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||||
|
|
||||||
|
"html-dom-parser/htmlparser2/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
|
||||||
|
|
||||||
"log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
"log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
|
||||||
|
|
||||||
"onnxruntime-node/tar/minizlib/rimraf/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
"onnxruntime-node/tar/minizlib/rimraf/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hipmi",
|
"name": "hipmi",
|
||||||
"version": "1.5.6",
|
"version": "1.5.39",
|
||||||
"private": true,
|
"private": true,
|
||||||
"prisma": {
|
"prisma": {
|
||||||
"seed": "bun prisma/seed.ts"
|
"seed": "bun prisma/seed.ts"
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
"@mantine/notifications": "^6.0.17",
|
"@mantine/notifications": "^6.0.17",
|
||||||
"@mantine/tiptap": "^7.5.3",
|
"@mantine/tiptap": "^7.5.3",
|
||||||
"@prisma/client": "^6.3.0",
|
"@prisma/client": "^6.3.0",
|
||||||
|
"@react-email/render": "^2.0.0",
|
||||||
"@react-pdf/renderer": "^3.4.4",
|
"@react-pdf/renderer": "^3.4.4",
|
||||||
"@tabler/icons-react": "^3.31.0",
|
"@tabler/icons-react": "^3.31.0",
|
||||||
"@tiptap/extension-highlight": "^2.2.3",
|
"@tiptap/extension-highlight": "^2.2.3",
|
||||||
@@ -51,6 +52,7 @@
|
|||||||
"autoprefixer": "10.4.14",
|
"autoprefixer": "10.4.14",
|
||||||
"bufferutil": "^4.0.8",
|
"bufferutil": "^4.0.8",
|
||||||
"bun": "^1.1.38",
|
"bun": "^1.1.38",
|
||||||
|
"caniuse-lite": "^1.0.30001757",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
@@ -59,6 +61,7 @@
|
|||||||
"echarts-for-react": "^3.0.2",
|
"echarts-for-react": "^3.0.2",
|
||||||
"embla-carousel-react": "^8.0.0-rc14",
|
"embla-carousel-react": "^8.0.0-rc14",
|
||||||
"eslint-config-next": "^13.5.4",
|
"eslint-config-next": "^13.5.4",
|
||||||
|
"firebase-admin": "^13.6.0",
|
||||||
"iron-session": "^6.3.1",
|
"iron-session": "^6.3.1",
|
||||||
"jose": "^5.9.2",
|
"jose": "^5.9.2",
|
||||||
"jotai": "^2.4.3",
|
"jotai": "^2.4.3",
|
||||||
@@ -90,6 +93,7 @@
|
|||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-responsive-carousel": "^3.2.23",
|
"react-responsive-carousel": "^3.2.23",
|
||||||
"react-toastify": "^9.1.3",
|
"react-toastify": "^9.1.3",
|
||||||
|
"resend": "^6.4.2",
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.2",
|
||||||
"swr": "^2.3.0",
|
"swr": "^2.3.0",
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Donasi_Invoice" ADD COLUMN "masterBankId" TEXT;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Donasi_Invoice" ADD CONSTRAINT "Donasi_Invoice_masterBankId_fkey" FOREIGN KEY ("masterBankId") REFERENCES "MasterBank"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Donasi_Invoice" ALTER COLUMN "masterBankId" SET DEFAULT 'null';
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "termsOfServiceAccepted" BOOLEAN NOT NULL DEFAULT false;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "BlockedUser" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
"blockerId" TEXT NOT NULL,
|
||||||
|
"blockedId" TEXT NOT NULL,
|
||||||
|
"menuFeatureId" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "BlockedUser_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "MenuFeature" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "MenuFeature_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "BlockedUser_blockerId_blockedId_key" ON "BlockedUser"("blockerId", "blockedId");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_menuFeatureId_fkey" FOREIGN KEY ("menuFeatureId") REFERENCES "MenuFeature"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_blockerId_fkey" FOREIGN KEY ("blockerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_blockedId_fkey" FOREIGN KEY ("blockedId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the `MenuFeature` table. If the table is not empty, all the data it contains will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "BlockedUser" DROP CONSTRAINT "BlockedUser_menuFeatureId_fkey";
|
||||||
|
|
||||||
|
-- DropTable
|
||||||
|
DROP TABLE "MenuFeature";
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "BlockedUser" ADD CONSTRAINT "BlockedUser_menuFeatureId_fkey" FOREIGN KEY ("menuFeatureId") REFERENCES "MasterKategoriApp"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "User" ADD COLUMN "acceptedForumTermsAt" TIMESTAMP(3),
|
||||||
|
ADD COLUMN "acceptedTermsAt" TIMESTAMP(3);
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Notifikasi" ADD COLUMN "deepLink" TEXT,
|
||||||
|
ADD COLUMN "readAt" TIMESTAMP(3);
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "TokenUserDevice" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"isActive" BOOLEAN NOT NULL DEFAULT true,
|
||||||
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||||
|
"platform" TEXT,
|
||||||
|
"deviceId" TEXT,
|
||||||
|
"model" TEXT,
|
||||||
|
"appVersion" TEXT,
|
||||||
|
"token" TEXT NOT NULL,
|
||||||
|
"userId" TEXT,
|
||||||
|
|
||||||
|
CONSTRAINT "TokenUserDevice_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "TokenUserDevice_userId_idx" ON "TokenUserDevice"("userId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "TokenUserDevice_token_idx" ON "TokenUserDevice"("token");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "TokenUserDevice" ADD CONSTRAINT "TokenUserDevice_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Donasi_Invoice" ALTER COLUMN "masterBankId" DROP DEFAULT;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Notifikasi" ADD COLUMN "type" TEXT;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "Notifikasi" DROP CONSTRAINT "Notifikasi_userRoleId_fkey";
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Notifikasi" ADD COLUMN "recipientId" TEXT,
|
||||||
|
ADD COLUMN "senderId" TEXT,
|
||||||
|
ALTER COLUMN "userRoleId" DROP NOT NULL;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Notifikasi" ADD CONSTRAINT "Notifikasi_userRoleId_fkey" FOREIGN KEY ("userRoleId") REFERENCES "MasterUserRole"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Notifikasi" ADD CONSTRAINT "Notifikasi_recipientId_fkey" FOREIGN KEY ("recipientId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Notifikasi" ADD CONSTRAINT "Notifikasi_senderId_fkey" FOREIGN KEY ("senderId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Notifikasi" ALTER COLUMN "appId" DROP NOT NULL,
|
||||||
|
ALTER COLUMN "kategoriApp" DROP NOT NULL,
|
||||||
|
ALTER COLUMN "pesan" DROP NOT NULL;
|
||||||
@@ -49,8 +49,20 @@ model User {
|
|||||||
BusinessMaps BusinessMaps[]
|
BusinessMaps BusinessMaps[]
|
||||||
Investasi_Invoice Investasi_Invoice[]
|
Investasi_Invoice Investasi_Invoice[]
|
||||||
|
|
||||||
EventSponsor EventSponsor[]
|
EventSponsor EventSponsor[]
|
||||||
EventTransaksi EventTransaksi[]
|
EventTransaksi EventTransaksi[]
|
||||||
|
termsOfServiceAccepted Boolean @default(false)
|
||||||
|
|
||||||
|
blockedUsers BlockedUser[] @relation("Blocking")
|
||||||
|
blockedBy BlockedUser[] @relation("BlockedBy")
|
||||||
|
|
||||||
|
acceptedTermsAt DateTime?
|
||||||
|
acceptedForumTermsAt DateTime?
|
||||||
|
tokenUserDevices TokenUserDevice[]
|
||||||
|
|
||||||
|
// For Mobile App
|
||||||
|
NotificationRecipient Notifikasi[] @relation("NotificationRecipient")
|
||||||
|
NotificationSender Notifikasi[] @relation("NotificationSender")
|
||||||
}
|
}
|
||||||
|
|
||||||
model MasterUserRole {
|
model MasterUserRole {
|
||||||
@@ -202,6 +214,7 @@ model MasterBank {
|
|||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
Investasi_Invoice Investasi_Invoice[]
|
Investasi_Invoice Investasi_Invoice[]
|
||||||
EventTransaksi EventTransaksi[]
|
EventTransaksi EventTransaksi[]
|
||||||
|
Donasi_Invoice Donasi_Invoice[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model MasterStatus {
|
model MasterStatus {
|
||||||
@@ -576,7 +589,9 @@ model Donasi_Invoice {
|
|||||||
Images Images? @relation(fields: [imagesId], references: [id])
|
Images Images? @relation(fields: [imagesId], references: [id])
|
||||||
imagesId String?
|
imagesId String?
|
||||||
|
|
||||||
imageId String?
|
imageId String?
|
||||||
|
MasterBank MasterBank? @relation(fields: [masterBankId], references: [id])
|
||||||
|
masterBankId String?
|
||||||
}
|
}
|
||||||
|
|
||||||
model Donasi_Kabar {
|
model Donasi_Kabar {
|
||||||
@@ -967,20 +982,32 @@ model Notifikasi {
|
|||||||
isActive Boolean @default(true)
|
isActive Boolean @default(true)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
isRead Boolean @default(false)
|
appId String?
|
||||||
appId String
|
kategoriApp String?
|
||||||
kategoriApp String
|
pesan String?
|
||||||
pesan String
|
|
||||||
title String?
|
title String?
|
||||||
status String?
|
status String?
|
||||||
|
|
||||||
|
isRead Boolean @default(false)
|
||||||
|
readAt DateTime? // kapan user membaca notifikasi ini
|
||||||
|
deepLink String? // misal: "announcement/123", "user/profile/cmha6wb9w0001cfndwl9fcse6"
|
||||||
|
type String?
|
||||||
|
|
||||||
Role MasterUserRole? @relation(fields: [userRoleId], references: [id])
|
Role MasterUserRole? @relation(fields: [userRoleId], references: [id])
|
||||||
userRoleId String
|
userRoleId String?
|
||||||
|
|
||||||
User User? @relation("UserNotifikasi", fields: [userId], references: [id], map: "NotifikasiUser")
|
User User? @relation("UserNotifikasi", fields: [userId], references: [id], map: "NotifikasiUser")
|
||||||
userId String?
|
userId String?
|
||||||
Admin User? @relation("AdminNotifikasi", fields: [adminId], references: [id], map: "NotifikasiAdmin")
|
Admin User? @relation("AdminNotifikasi", fields: [adminId], references: [id], map: "NotifikasiAdmin")
|
||||||
adminId String?
|
adminId String?
|
||||||
|
|
||||||
|
// Recipient (user who receives the notification)
|
||||||
|
recipient User? @relation("NotificationRecipient", fields: [recipientId], references: [id])
|
||||||
|
recipientId String?
|
||||||
|
|
||||||
|
// Sender (user who sent the notification)
|
||||||
|
sender User? @relation("NotificationSender", fields: [senderId], references: [id])
|
||||||
|
senderId String?
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAPS
|
// MAPS
|
||||||
@@ -1008,6 +1035,8 @@ model MasterKategoriApp {
|
|||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
name String
|
name String
|
||||||
value String?
|
value String?
|
||||||
|
|
||||||
|
blockedUsers BlockedUser[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================= EVENT ======================= //
|
// ======================= EVENT ======================= //
|
||||||
@@ -1070,3 +1099,39 @@ model Sticker {
|
|||||||
|
|
||||||
MasterEmotions MasterEmotions[] @relation("StikerEmotions")
|
MasterEmotions MasterEmotions[] @relation("StikerEmotions")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model BlockedUser {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
isActive Boolean @default(true)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
blockerId String // ID user yang memblokir
|
||||||
|
blockedId String // ID user yang diblokir
|
||||||
|
|
||||||
|
menuFeatureId String
|
||||||
|
menuFeature MasterKategoriApp @relation(fields: [menuFeatureId], references: [id])
|
||||||
|
|
||||||
|
blocker User @relation("BlockedBy", fields: [blockerId], references: [id])
|
||||||
|
blocked User @relation("Blocking", fields: [blockedId], references: [id])
|
||||||
|
|
||||||
|
@@unique([blockerId, blockedId])
|
||||||
|
}
|
||||||
|
|
||||||
|
model TokenUserDevice {
|
||||||
|
id String @id @default(uuid())
|
||||||
|
isActive Boolean @default(true)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
platform String? // "ios" | "android"
|
||||||
|
deviceId String? // UUID unik dari device (misal: dari expo-device)
|
||||||
|
model String? // "iPhone15,4", "Pixel 7", dll
|
||||||
|
appVersion String? // "1.5.15" — sangat berguna saat debug
|
||||||
|
|
||||||
|
token String @db.Text
|
||||||
|
user User? @relation(fields: [userId], references: [id])
|
||||||
|
userId String?
|
||||||
|
|
||||||
|
@@index([userId])
|
||||||
|
@@index([token]) // untuk pencarian cepat & deduplikasi
|
||||||
|
}
|
||||||
|
|||||||
1098
prisma/schema.prisma.backup
Normal file
1098
prisma/schema.prisma.backup
Normal file
File diff suppressed because it is too large
Load Diff
11
public/.well-known/apple-app-site-association
Normal file
11
public/.well-known/apple-app-site-association
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"applinks": {
|
||||||
|
"apps": [],
|
||||||
|
"details": [
|
||||||
|
{
|
||||||
|
"appID": "BMY6GT6W3D.com.anonymous.hipmi-mobile",
|
||||||
|
"paths": ["*"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
8
public/.well-known/assetlinks.json
Normal file
8
public/.well-known/assetlinks.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "com.bip.hipmimobileapp",
|
||||||
|
"sha256_cert_fingerprints": ["CFF8431520BFAE665025B68138774A4E64AA6338D2DF6C7D900A71F0551FFD2D"]
|
||||||
|
}
|
||||||
|
}]
|
||||||
BIN
public/aset/logo/hiconnect.png
Normal file
BIN
public/aset/logo/hiconnect.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 509 KiB |
301
public/privacy-policy.html
Normal file
301
public/privacy-policy.html
Normal file
@@ -0,0 +1,301 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Privacy Policy</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #333;
|
||||||
|
max-width: 900px;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.last-updated {
|
||||||
|
color: #777;
|
||||||
|
font-style: italic;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
margin: 15px 0;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #0066cc;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.summary-box {
|
||||||
|
background-color: #faf8e8;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 25px 0;
|
||||||
|
}
|
||||||
|
.summary-box h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
.section-title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
address {
|
||||||
|
margin-top: 15px;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Privacy Policy</h1>
|
||||||
|
<div class="last-updated">Last updated November 06, 2025</div>
|
||||||
|
|
||||||
|
<p>This Privacy Notice for Bali Interaktif Perkasa ("<strong>we</strong>", "<strong>us</strong>", or "<strong>our</strong>"), describes how and why we might access, collect, store, use, and/or share ("<strong>process</strong>") your personal information when you use our services ("<strong>Services</strong>"), including when you:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Download and use our mobile application (HIPMI Badung Connect), or any other application of ours that links to this Privacy Notice</li>
|
||||||
|
|
||||||
|
<li>Use HIPMI Badung Connect. HIPMI Badung Connect is an official digital platform developed to support the network of members of HIPMI (Himpunan Pengusaha Muda Indonesia – Indonesian Young Entrepreneurs Association) in Badung Regency. The app aims to strengthen collaboration, partnerships, and the business ecosystem among young entrepreneurs through a range of interactive and informative features. Key features of the app include:
|
||||||
|
<ul style="list-style-type: none; padding-left: 0;">
|
||||||
|
<li><strong>Profile:</strong> Displays users’ personal and professional background as HIPMI Badung members.</li>
|
||||||
|
<li><strong>Business Portfolio:</strong> Allows users to showcase their business name, business information, and associated social media links.</li>
|
||||||
|
<li><strong>User Search:</strong> Enables members to discover and connect with other users based on specific criteria.</li>
|
||||||
|
<li><strong>Events:</strong> Provides information and registration for business events, seminars, workshops, and HIPMI Badung community activities.</li>
|
||||||
|
<li><strong>Voting:</strong> Supports internal organizational decision-making through a digital voting system.</li>
|
||||||
|
<li><strong>Collaboration Projects:</strong> Serves as a hub for initiating, managing, and participating in joint business initiatives.</li>
|
||||||
|
<li><strong>Job Search:</strong> Offers job postings and career opportunities within the members’ business ecosystem.</li>
|
||||||
|
<li><strong>Forum:</strong> An interactive space for members to exchange ideas, ask questions, and share solutions related to entrepreneurship.</li>
|
||||||
|
<li><strong>Business Map (Maps):</strong> Displays the physical locations of members’ businesses to facilitate networking and in-person visits.</li>
|
||||||
|
<li><strong>Crowdfunding:</strong> Includes two funding mechanisms—Investment (for business opportunities offering returns) and Donation (for social support with no expectation of return).</li>
|
||||||
|
</ul>
|
||||||
|
This app is designed to uphold user data integrity while promoting transparency, collaboration, and sustainable economic growth among young entrepreneurs in Badung. All personal and business information collected through the app is used solely to enable core functionalities and is managed in accordance with applicable privacy policies.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>Engage with us in other related ways, including any sales, marketing, or events</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p><strong>Questions or concerns?</strong> Reading this Privacy Notice will help you understand your privacy rights and choices. We are responsible for making decisions about how your personal information is processed. If you do not agree with our policies and practices, please do not use our Services. If you still have any questions or concerns, please contact us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a>.</p>
|
||||||
|
|
||||||
|
<!-- SUMMARY OF KEY POINTS -->
|
||||||
|
<div class="summary-box">
|
||||||
|
<h3>Summary of Key Points</h3>
|
||||||
|
<p>This summary provides key points from our Privacy Notice, but you can find out more details about any of these topics by using the table of contents below.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><strong>What personal information do we process?</strong> We may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use.</li>
|
||||||
|
<li><strong>Do we process any sensitive personal information?</strong> We do not process sensitive personal information.</li>
|
||||||
|
<li><strong>Do we collect any information from third parties?</strong> We do not collect any information from third parties.</li>
|
||||||
|
<li><strong>How do we process your information?</strong> To provide, improve, and administer our Services; communicate with you; for security and fraud prevention; and to comply with law.</li>
|
||||||
|
<li><strong>In what situations and with which parties do we share personal information?</strong> We may share information in specific situations and with specific third parties.</li>
|
||||||
|
<li><strong>How do we keep your information safe?</strong> We have adequate organizational and technical processes in place to protect your personal information.</li>
|
||||||
|
<li><strong>What are your rights?</strong> Depending on where you are located geographically, you may have certain rights regarding your personal information.</li>
|
||||||
|
<li><strong>How do you exercise your rights?</strong> By submitting a data subject access request, or by contacting us.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- TABLE OF CONTENTS -->
|
||||||
|
<h3>Table of Contents</h3>
|
||||||
|
<ol>
|
||||||
|
<li><a href="#section1">WHAT INFORMATION DO WE COLLECT?</a></li>
|
||||||
|
<li><a href="#section2">HOW DO WE PROCESS YOUR INFORMATION?</a></li>
|
||||||
|
<li><a href="#section3">WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</a></li>
|
||||||
|
<li><a href="#section4">DO WE USE COOKIES AND OTHER TRACKING TECHNOLOGIES?</a></li>
|
||||||
|
<li><a href="#section5">HOW LONG DO WE KEEP YOUR INFORMATION?</a></li>
|
||||||
|
<li><a href="#section6">HOW DO WE KEEP YOUR INFORMATION SAFE?</a></li>
|
||||||
|
<li><a href="#section7">DO WE COLLECT INFORMATION FROM MINORS?</a></li>
|
||||||
|
<li><a href="#section8">WHAT ARE YOUR PRIVACY RIGHTS?</a></li>
|
||||||
|
<li><a href="#section9">CONTROLS FOR DO-NOT-TRACK FEATURES</a></li>
|
||||||
|
<li><a href="#section10">DO WE MAKE UPDATES TO THIS NOTICE?</a></li>
|
||||||
|
<li><a href="#section11">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a></li>
|
||||||
|
<li><a href="#section12">HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?</a></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<!-- SECTION 1 -->
|
||||||
|
<div id="section1" class="section-title">1. WHAT INFORMATION DO WE COLLECT?</div>
|
||||||
|
<h4>Personal information you disclose to us</h4>
|
||||||
|
<p><em>In Short:</em> We collect personal information that you provide to us.</p>
|
||||||
|
<p>We collect personal information that you voluntarily provide to us when you register on the Services, express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us.</p>
|
||||||
|
<h4>Personal Information Provided by You.</h4>
|
||||||
|
<p>The personal information that we collect depends on the context of your interactions with us and the Services, the choices you make, and the products and features you use. The personal information we collect may include the following:</p>
|
||||||
|
<ul>
|
||||||
|
<li>names</li>
|
||||||
|
<li>phone numbers</li>
|
||||||
|
<li>email addresses</li>
|
||||||
|
<li>usernames</li>
|
||||||
|
</ul>
|
||||||
|
<h4>Sensitive Information.</h4>
|
||||||
|
<p>We do not process sensitive information.</p>
|
||||||
|
<h4>Application Data.</h4>
|
||||||
|
<p>If you use our application(s), we also may collect the following information if you choose to provide us with access or permission:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Geolocation Information.</strong> We may request access or permission to track location-based information from your mobile device, either continuously or while you are using our mobile application(s), to provide certain location-based services. If you wish to change our access or permissions, you may do so in your device's settings.</li>
|
||||||
|
<li><strong>Mobile Device Data.</strong> We automatically collect device information (such as your mobile device ID, model, and manufacturer), operating system, version information and system configuration information, device and application identification numbers, browser type and version, hardware model Internet service provider and/or mobile carrier, and Internet Protocol (IP) address (or proxy server). If you are using our application(s), we may also collect information about the phone network associated with your mobile device, your mobile device’s operating system or platform, the type of mobile device you use, your mobile device’s unique device ID, and information about the features of our application(s) you accessed.</li>
|
||||||
|
<li><strong>Push Notifications.</strong> We may request to send you push notifications regarding your account or certain features of the application(s). If you wish to opt out from receiving these types of communications, you may turn them off in your device's settings.</li>
|
||||||
|
</ul>
|
||||||
|
<p>This information is primarily needed to maintain the security and operation of our application(s), for troubleshooting, and for our internal analytics and reporting purposes.</p>
|
||||||
|
<p>All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information.</p>
|
||||||
|
<h4>Information automatically collected</h4>
|
||||||
|
<p><em>In Short:</em> Some information — such as your Internet Protocol (IP) address and/or browser and device characteristics — is collected automatically when you visit our Services.</p>
|
||||||
|
<p>We automatically collect certain information when you visit, use, or navigate the Services. This information does not reveal your specific identity (like your name or contact information) but may include device and usage information, such as your IP address, browser and device characteristics, operating system, language preferences, referring URLs, device name, country, location, information about how and when you use our Services, and other technical information. This information is primarily needed to maintain the security and operation of our Services, and for our internal analytics and reporting purposes.</p>
|
||||||
|
<p>Like many businesses, we also collect information through cookies and similar technologies.</p>
|
||||||
|
<h4>The information we collect includes:</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Log and Usage Data.</strong> Log and usage data is service-related, diagnostic, usage, and performance information our servers automatically collect when you access or use our Services and which we record in log files. Depending on how you interact with us, this log data may include your IP address, device information, browser type, and settings and information about your activity in the Services (such as the date/time stamps associated with your usage, pages and files viewed, searches, and other actions you take such as which features you use), device event information (such as system activity, error reports (sometimes called "crash dumps"), and hardware settings).</li>
|
||||||
|
<li><strong>Device Data.</strong> We collect device data such as information about your computer, phone, tablet, or other device you use to access the Services. Depending on the device used, this device data may include information such as your IP address (or proxy server), device and application identification numbers, location, browser type, hardware model, Internet service provider and/or mobile carrier, operating system, and system configuration information.</li>
|
||||||
|
<li><strong>Location Data.</strong> We collect location data such as information about your device's location, which can be either precise or imprecise. How much information we collect depends on the type and settings of the device you use to access the Services. For example, we may use GPS and other technologies to collect geolocation data that tells us your current location (based on your IP address). You can opt out of allowing us to collect this information either by refusing access to the information or by disabling your Location setting on your device. However, if you choose to opt out, you may not be able to use certain aspects of the Services.</li>
|
||||||
|
</ul>
|
||||||
|
<h4>Google API</h4>
|
||||||
|
<p>Our use of information received from Google APIs will adhere to <a href="https://developers.google.com/terms/api-services-user-data-policy" target="_blank">Google API Services User Data Policy</a>, including the <a href="https://developers.google.com/terms/api-services-user-data-policy#limited-use" target="_blank">Limited Use requirements</a>.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 2 -->
|
||||||
|
<div id="section2" class="section-title">2. HOW DO WE PROCESS YOUR INFORMATION?</div>
|
||||||
|
<p><em>In Short:</em> We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent.</p>
|
||||||
|
<p>We process your personal information for a variety of reasons, depending on how you interact with our Services, including:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>To facilitate account creation and authentication and otherwise manage user accounts.</strong> We may process your information so you can create and log in to your account, as well as keep your account in working order.</li>
|
||||||
|
<li><strong>To deliver and facilitate delivery of services to the user.</strong> We may process your information to provide you with the requested service.</li>
|
||||||
|
<li><strong>To respond to user inquiries/offer support to users.</strong> We may process your information to respond to your inquiries and solve any potential issues you might have with the requested service.</li>
|
||||||
|
<li><strong>To send administrative information to you.</strong> We may process your information to send you details about our products and services, changes to our terms and policies, and other similar information.</li>
|
||||||
|
<li><strong>To enable user-to-user communications.</strong> We may process your information if you choose to use any of our offerings that allow for communication with another user.</li>
|
||||||
|
<li><strong>To request feedback.</strong> We may process your information when necessary to request feedback and to contact you about your use of our Services.</li>
|
||||||
|
<li><strong>To send you marketing and promotional communications.</strong> We may process the personal information you send to us for our marketing purposes, if this is in accordance with your marketing preferences. You can opt out of our marketing emails at any time. For more information, see "<a href="#section8">WHAT ARE YOUR PRIVACY RIGHTS?</a>" below.</li>
|
||||||
|
<li><strong>To protect our Services.</strong> We may process your information as part of our efforts to keep our Services safe and secure, including fraud monitoring and prevention.</li>
|
||||||
|
<li><strong>To evaluate and improve our Services, products, marketing, and your experience.</strong> We may process your information when we believe it is necessary to identify usage trends, determine the effectiveness of our promotional campaigns, and to evaluate and improve our Services, products, marketing, and your experience.</li>
|
||||||
|
<li><strong>To identify usage trends.</strong> We may process information about how you use our Services to better understand how they are being used so we can improve them.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- SECTION 3 -->
|
||||||
|
<div id="section3" class="section-title">3. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?</div>
|
||||||
|
<p><em>In Short:</em> We may share information in specific situations described in this section and/or with the following third parties.</p>
|
||||||
|
<h4>Vendors, Consultants, and Other Third-Party Service Providers.</h4>
|
||||||
|
<p>We may share your data with third-party vendors, service providers, contractors, or agents (“<strong>third parties</strong>”) who perform services for us or on our behalf and require access to such information to do that work. We have contracts in place with our third parties, which are designed to help safeguard your personal information. This means that they cannot do anything with your personal information unless we have instructed them to do it. They will also not share your personal information with any organization apart from us. They also commit to protect the data they hold on our behalf and to retain it for the period we instruct.</p>
|
||||||
|
<p>The third parties we may share personal information with are as follows:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Cloud Computing Services</strong>
|
||||||
|
<ul style="list-style-type: none; padding-left: 15px;">
|
||||||
|
<li>Google Cloud Platform</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><strong>Functionality and Infrastructure Optimization</strong>
|
||||||
|
<ul style="list-style-type: none; padding-left: 15px;">
|
||||||
|
<li>Firebase Realtime Database</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><strong>Web and Mobile Analytics</strong>
|
||||||
|
<ul style="list-style-type: none; padding-left: 15px;">
|
||||||
|
<li>Google Analytics for Firebase</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><strong>Website Performance Monitoring</strong>
|
||||||
|
<ul style="list-style-type: none; padding-left: 15px;">
|
||||||
|
<li>Firebase Crash Reporting</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><strong>Website Testing</strong>
|
||||||
|
<ul style="list-style-type: none; padding-left: 15px;">
|
||||||
|
<li>Google Play Console and TestFlight</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>We also may need to share your personal information in the following situations:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Business Transfers.</strong> We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company.</li>
|
||||||
|
<li><strong>When we use Google Maps Platform APIs.</strong> We may share your information with certain Google Maps Platform APIs (e.g., Google Maps API, Places API). Google Maps uses GPS, Wi-Fi, and cell towers to estimate your location. GPS is accurate to about 20 meters, while Wi-Fi and cell towers help improve accuracy when GPS signals are weak, like indoors. This data helps Google Maps provide directions, but it is not always perfectly precise. We obtain and store on your device (“cache”) your location. You may revoke your consent anytime by contacting us at the contact details provided at the end of this document.</li>
|
||||||
|
<li><strong>Business Partners.</strong> We may share your information with our business partners to offer you certain products, services, or promotions.</li>
|
||||||
|
<li><strong>Other Users.</strong> When you share personal information (for example, by posting comments, contributions, or other content to the Services) or otherwise interact with public areas of the Services, such personal information may be viewed by all users and may be publicly made available outside the Services in perpetuity. Similarly, other users will be able to view descriptions of your activity, communicate with you within our Services, and view your profile.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- SECTION 4 -->
|
||||||
|
<div id="section4" class="section-title">4. DO WE USE COOKIES AND OTHER TRACKING TECHNOLOGIES?</div>
|
||||||
|
<p><em>In Short:</em> We may use cookies and other tracking technologies to collect and store your information.</p>
|
||||||
|
<p>We may use cookies and similar tracking technologies (like web beacons and pixels) to gather information when you interact with our Services. Some online tracking technologies help us maintain the security of our Services and your account, prevent crashes, fix bugs, save your preferences, and assist with basic site functions.</p>
|
||||||
|
<p>We also permit third parties and service providers to use online tracking technologies on our Services for analytics and advertising, including to help manage and display advertisements, to tailor advertisements to your interests, or to send abandoned shopping cart reminders (depending on your communication preferences). The third parties and service providers use their technology to provide advertising about products and services tailored to your interests which may appear either on our Services or on other websites.</p>
|
||||||
|
<p>Specific information about how we use such technologies and how you can refuse certain cookies is set out in our Cookie Notice.</p>
|
||||||
|
<h4>Google Analytics</h4>
|
||||||
|
<p>We may share your information with Google Analytics to track and analyze the use of the Services. To opt out of being tracked by Google Analytics across the Services, visit <a href="https://tools.google.com/dlpage/gaoptout" target="_blank">https://tools.google.com/dlpage/gaoptout</a>. For more information on the privacy practices of Google, please visit the <a href="https://policies.google.com/privacy" target="_blank">Google Privacy & Terms page</a>.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 5 -->
|
||||||
|
<div id="section5" class="section-title">5. HOW LONG DO WE KEEP YOUR INFORMATION?</div>
|
||||||
|
<p><em>In Short:</em> We keep your information for as long as necessary to fulfill the purposes outlined in this Privacy Notice unless otherwise required by law.</p>
|
||||||
|
<p>We will only keep your personal information for as long as it is necessary for the purposes set out in this Privacy Notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). No purpose in this notice will require us keeping your personal information for longer than the period of time in which users have an account with us.</p>
|
||||||
|
<p>When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymize such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 6 -->
|
||||||
|
<div id="section6" class="section-title">6. HOW DO WE KEEP YOUR INFORMATION SAFE?</div>
|
||||||
|
<p><em>In Short:</em> We aim to protect your personal information through a system of organizational and technical security measures.</p>
|
||||||
|
<p>We have implemented appropriate and reasonable technical and organizational security measures designed to protect the security of any personal information we process. However, despite our safeguards and efforts to secure your information, no electronic transmission over the Internet or information storage technology can be guaranteed to be 100% secure, so we cannot promise or guarantee that hackers, cybercriminals, or other unauthorized third parties will not be able to defeat our security and improperly collect, access, steal, or modify your information. Although we will do our best to protect your personal information, transmission of personal information to and from our Services is at your own risk. You should only access the Services within a secure environment.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 7 -->
|
||||||
|
<div id="section7" class="section-title">7. DO WE COLLECT INFORMATION FROM MINORS?</div>
|
||||||
|
<p><em>In Short:</em> We do not knowingly collect data from or market to minors.</p>
|
||||||
|
<p>HIPMI Badung Connect is not intended for use by individuals under the age of 18. We do not knowingly collect personal information from children under 18. If we become aware that we have inadvertently collected such information, we will take steps to delete it as soon as possible.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 8 -->
|
||||||
|
<div id="section8" class="section-title">8. WHAT ARE YOUR PRIVACY RIGHTS?</div>
|
||||||
|
<p><em>In Short:</em> You may review, change, or terminate your account at any time, depending on your country, province, or state of residence.</p>
|
||||||
|
<h4>Withdrawing your consent:</h4>
|
||||||
|
<p>If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section "<a href="#section11">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a>" below.</p>
|
||||||
|
<p>However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent.</p>
|
||||||
|
<h4>Opting out of marketing and promotional communications:</h4>
|
||||||
|
<p>You can unsubscribe from our marketing and promotional communications at any time by clicking on the unsubscribe link in the emails that we send, or by contacting us using the details provided in the section "<a href="#section11">HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</a>" below. You will then be removed from the marketing lists. However, we may still communicate with you — for example, to send you service-related messages that are necessary for the administration and use of your account, to respond to service requests, or for other non-marketing purposes.</p>
|
||||||
|
<h4>Account Information</h4>
|
||||||
|
<p>If you would at any time like to review or change the information in your account or terminate your account, you can:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Log in to your account settings and update your user account.</li>
|
||||||
|
<li>Contact us using the contact information provided.</li>
|
||||||
|
<li><a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a></li>
|
||||||
|
</ul>
|
||||||
|
<p>Upon your request to terminate your account, we will deactivate or delete your account and information from our active databases. However, we may retain some information in our files to prevent fraud, troubleshoot problems, assist with any investigations, enforce our legal terms and/or comply with applicable legal requirements.</p>
|
||||||
|
<h4>Cookies and similar technologies:</h4>
|
||||||
|
<p>Most Web browsers are set to accept cookies by default. If you prefer, you can usually choose to set your browser to remove cookies and to reject cookies. If you choose to remove cookies or reject cookies, this could affect certain features or services of our Services.</p>
|
||||||
|
<p>If you have questions or comments about your privacy rights, you may email us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a>.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 9 -->
|
||||||
|
<div id="section9" class="section-title">9. CONTROLS FOR DO-NOT-TRACK FEATURES</div>
|
||||||
|
<p>Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track ("DNT") feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage, no uniform technology standard for recognizing and implementing DNT signals has been finalized. As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this Privacy Notice.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 10 -->
|
||||||
|
<div id="section10" class="section-title">10. DO WE MAKE UPDATES TO THIS NOTICE?</div>
|
||||||
|
<p><em>In Short:</em> Yes, we will update this notice as necessary to stay compliant with relevant laws.</p>
|
||||||
|
<p>We may update this Privacy Notice from time to time. The updated version will be indicated by an updated "Revised" date at the top of this Privacy Notice. If we make material changes to this Privacy Notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this Privacy Notice frequently to be informed of how we are protecting your information.</p>
|
||||||
|
|
||||||
|
<!-- SECTION 11 -->
|
||||||
|
<div id="section11" class="section-title">11. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?</div>
|
||||||
|
<p>If you have questions or comments about this notice, you may email us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a> or contact us by post at:</p>
|
||||||
|
<address>
|
||||||
|
Bali Interaktif Perkasa<br>
|
||||||
|
Park23 Creative Hub, Bali Interaktif Perkasa - Private Office<br>
|
||||||
|
Jl. Kediri 3rd Floor, Number 01 - 02, Tuban<br>
|
||||||
|
Badung, Bali, Indonesia 80361<br>
|
||||||
|
Indonesia
|
||||||
|
</address>
|
||||||
|
|
||||||
|
<!-- SECTION 12 -->
|
||||||
|
<div id="section12" class="section-title">12. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?</div>
|
||||||
|
<p>You have the right to request access to the personal information we collect from you, details about how we have processed it, correct inaccuracies, or delete your personal information. You may also have the right to withdraw your consent to our processing of your personal information. These rights may be limited in some circumstances by applicable law.</p>
|
||||||
|
<p>To make a request, please contact us at <a href="mailto:bip.baliinteraktifperkasa@gmail.com">bip.baliinteraktifperkasa@gmail.com</a>.</p>
|
||||||
|
<hr style="margin: 30px 0; border: 0; border-top: 1px solid #eee;">
|
||||||
|
<p>© 2026 Bali Interaktif Perkasa. All rights reserved.</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
110
public/terms-of-service.html
Normal file
110
public/terms-of-service.html
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="id">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<title>Syarat & Ketentuan - HIPMI Badung Connect</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #333;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
h1, h2, h3 {
|
||||||
|
color: #1a365d;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
margin-top: 40px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #666;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Syarat & Ketentuan Penggunaan HIPMI Badung Connect</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Dengan menggunakan aplikasi <strong>HIPMI Badung Connect</strong> (“Aplikasi”), Anda setuju untuk mematuhi dan terikat oleh syarat dan ketentuan berikut. Jika Anda tidak setuju dengan ketentuan ini, harap jangan gunakan Aplikasi.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>1. Definisi</h2>
|
||||||
|
<p>
|
||||||
|
<strong>HIPMI Badung Connect</strong> adalah platform digital resmi untuk anggota Himpunan Pengusaha Muda Indonesia (HIPMI) Kabupaten Badung, yang bertujuan memfasilitasi jaringan, kolaborasi, dan pertumbuhan bisnis para pengusaha muda.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>2. Larangan Konten Tidak Pantas</h2>
|
||||||
|
<p>
|
||||||
|
Anda <strong>dilarang keras</strong> memposting, mengirim, membagikan, atau mengunggah konten apa pun yang mengandung:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Ujaran kebencian, diskriminasi, atau konten SARA (Suku, Agama, Ras, Antar-golongan)</li>
|
||||||
|
<li>Pornografi, konten seksual eksplisit, atau gambar tidak senonoh</li>
|
||||||
|
<li>Ancaman, pelecehan, bullying, atau perilaku melecehkan</li>
|
||||||
|
<li>Informasi palsu, hoaks, spam, atau konten menyesatkan</li>
|
||||||
|
<li>Konten ilegal, melanggar hukum, atau melanggar hak kekayaan intelektual pihak lain</li>
|
||||||
|
<li>Promosi narkoba, perjudian, atau aktivitas ilegal lainnya</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>3. Tanggung Jawab Pengguna</h2>
|
||||||
|
<p>
|
||||||
|
Anda bertanggung jawab penuh atas setiap konten yang Anda unggah atau bagikan melalui fitur-fitur berikut:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Profil (bio, foto, portofolio)</li>
|
||||||
|
<li>Forum diskusi</li>
|
||||||
|
<li>Chat pribadi atau grup</li>
|
||||||
|
<li>Lowongan kerja, investasi, dan donasi</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Konten yang melanggar ketentuan ini dapat dihapus kapan saja tanpa pemberitahuan.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>4. Tindakan terhadap Pelanggaran</h2>
|
||||||
|
<p>
|
||||||
|
Jika kami menerima laporan atau menemukan konten yang melanggar ketentuan ini, kami akan:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Segera menghapus konten tersebut</li>
|
||||||
|
<li>Memberikan peringatan atau memblokir akun pengguna</li>
|
||||||
|
<li>Dalam kasus berat, melaporkan ke pihak berwajib sesuai hukum yang berlaku</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Tim kami berkomitmen untuk menanggapi laporan konten tidak pantas <strong>dalam waktu 24 jam</strong>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>5. Mekanisme Pelaporan</h2>
|
||||||
|
<p>
|
||||||
|
Anda dapat melaporkan konten atau pengguna yang mencurigakan melalui:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Tombol <strong>“Laporkan”</strong> di setiap posting forum atau pesan chat</li>
|
||||||
|
<li>Tombol <strong>“Blokir Pengguna”</strong> di profil pengguna</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Setiap laporan akan ditangani secara rahasia dan segera.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>6. Perubahan Ketentuan</h2>
|
||||||
|
<p>
|
||||||
|
Kami berhak memperbarui Syarat & Ketentuan ini sewaktu-waktu. Versi terbaru akan dipublikasikan di halaman ini dengan tanggal revisi yang diperbarui.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2>7. Kontak</h2>
|
||||||
|
<p>
|
||||||
|
Jika Anda memiliki pertanyaan tentang ketentuan ini, silakan hubungi kami di:
|
||||||
|
<strong>bip.baliinteraktifperkasa@gmail.com</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>© 2026 Bali Interaktif Perkasa. All rights reserved.</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
30
sendWhatsapp.js
Normal file
30
sendWhatsapp.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// sendWhatsapp.js
|
||||||
|
|
||||||
|
// --- INPUT MANUAL ---
|
||||||
|
let phoneNumber = "6282340374412";
|
||||||
|
const codeOtp = "3546";
|
||||||
|
// ---------------------
|
||||||
|
|
||||||
|
phoneNumber = phoneNumber.replace(/\D/g, "");
|
||||||
|
|
||||||
|
// Format pesan
|
||||||
|
const message =
|
||||||
|
`HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n` +
|
||||||
|
`>> Kode OTP anda: ${codeOtp}.`;
|
||||||
|
|
||||||
|
const encodedMessage = encodeURIComponent(message);
|
||||||
|
|
||||||
|
const waLink = `https://wa.wibudev.com/code?nom=${phoneNumber}&text=${encodedMessage}`;
|
||||||
|
|
||||||
|
console.log("Mengirim request ke server...\n");
|
||||||
|
|
||||||
|
// Jalankan HTTP GET
|
||||||
|
fetch(waLink)
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(data => {
|
||||||
|
console.log("Response dari server:");
|
||||||
|
console.log(data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error("Terjadi error:", err);
|
||||||
|
});
|
||||||
153
src/app/(support)/delete-account/page.tsx
Normal file
153
src/app/(support)/delete-account/page.tsx
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Grid,
|
||||||
|
Paper,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { notifications } from "@mantine/notifications";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { useParams } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export default function DeleteAccount() {
|
||||||
|
const [phoneNumber, setPhoneNumber] = useState<string>("");
|
||||||
|
const [data, setData] = useState({
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Hanya di client, setelah mount
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const phone = urlParams.get("phone");
|
||||||
|
if (phone) {
|
||||||
|
setPhoneNumber(phone);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handlerSubmit = async () => {
|
||||||
|
if (!phoneNumber) {
|
||||||
|
return notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
message: "Please check your phone number",
|
||||||
|
color: "red",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.description) {
|
||||||
|
return notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
message: "Please fill in description with 'Delete Account'",
|
||||||
|
color: "red",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.description !== "Delete Account") {
|
||||||
|
return notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
message: "Please fill in description with 'Delete Account'",
|
||||||
|
color: "red",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await fetch("/api/helper/delete-account", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
number: phoneNumber,
|
||||||
|
description: data.description,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
if (result.success) {
|
||||||
|
notifications.show({
|
||||||
|
title: "Success",
|
||||||
|
message: "Account will process to delete",
|
||||||
|
color: "green",
|
||||||
|
});
|
||||||
|
|
||||||
|
setData({
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
message: result.error || "Failed to delete account.",
|
||||||
|
color: "red",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100vh",
|
||||||
|
backgroundColor: "#f5f5f5",
|
||||||
|
padding: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Paper withBorder shadow="md" p={"lg"}>
|
||||||
|
<Stack align="center">
|
||||||
|
<Image
|
||||||
|
src="/aset/logo/hiconnect.png"
|
||||||
|
alt="logo"
|
||||||
|
width={100}
|
||||||
|
height={100}
|
||||||
|
/>
|
||||||
|
<Title>Delete Account</Title>
|
||||||
|
<Stack spacing={0} align="center">
|
||||||
|
<Text align="center" fw={"lighter"}>
|
||||||
|
To delete your account with phone number{" "}
|
||||||
|
{phoneNumber ? `+${phoneNumber}` : ""}.
|
||||||
|
</Text>
|
||||||
|
<Text align="center" fw={"lighter"}>
|
||||||
|
Type your message with subject ‘Delete Account’
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Grid w={"100%"}>
|
||||||
|
<Grid.Col span={8}>
|
||||||
|
<TextInput
|
||||||
|
value={data.description}
|
||||||
|
w={"100%"}
|
||||||
|
placeholder="Type your subject here"
|
||||||
|
onChange={(e) => {
|
||||||
|
setData({
|
||||||
|
...data,
|
||||||
|
description: e.target.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={4}>
|
||||||
|
<Button onClick={handlerSubmit} w={"100%"} loading={isLoading}>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
202
src/app/(support)/support-center/page.tsx
Normal file
202
src/app/(support)/support-center/page.tsx
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
"use client";
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Group,
|
||||||
|
Paper,
|
||||||
|
SimpleGrid,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
Textarea,
|
||||||
|
TextInput,
|
||||||
|
Title,
|
||||||
|
} from "@mantine/core";
|
||||||
|
import { notifications } from "@mantine/notifications";
|
||||||
|
import { IconBrandGmail, IconLocation } from "@tabler/icons-react";
|
||||||
|
import Image from "next/image";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function SupportCenter() {
|
||||||
|
const [data, setData] = useState({
|
||||||
|
email: "",
|
||||||
|
title: "",
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!data.email || !data.title || !data.description) {
|
||||||
|
return notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
color: "red",
|
||||||
|
message: "Please fill in all fields.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const response = await fetch("/api/helper/support-center", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
notifications.show({
|
||||||
|
title: "Success",
|
||||||
|
color: "green",
|
||||||
|
message: "Message sent successfully.",
|
||||||
|
});
|
||||||
|
|
||||||
|
setData({
|
||||||
|
email: "",
|
||||||
|
title: "",
|
||||||
|
description: "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
|
notifications.show({
|
||||||
|
title: "Error",
|
||||||
|
color: "red",
|
||||||
|
message: result.error || "Failed to send message.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
height: "100vh",
|
||||||
|
backgroundColor: "#f5f5f5",
|
||||||
|
padding: "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack spacing={"lg"}>
|
||||||
|
<Stack align="center">
|
||||||
|
<Stack spacing={"xs"} align="center">
|
||||||
|
<Group>
|
||||||
|
<Image
|
||||||
|
src="/aset/logo/hiconnect.png"
|
||||||
|
alt="logo"
|
||||||
|
width={50}
|
||||||
|
height={50}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Title>Support Center</Title>
|
||||||
|
</Group>
|
||||||
|
<Text align="center">
|
||||||
|
Send us a message and we'll get back to you as soon as possible.
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Paper style={{ padding: "20px" }} withBorder shadow="md">
|
||||||
|
<SimpleGrid
|
||||||
|
cols={2}
|
||||||
|
// verticalSpacing={50}
|
||||||
|
spacing={50}
|
||||||
|
breakpoints={[
|
||||||
|
{ maxWidth: "md", cols: 2, spacing: "md" },
|
||||||
|
{ maxWidth: "sm", cols: 2, spacing: "sm" },
|
||||||
|
{ maxWidth: "xs", cols: 1, spacing: "sm" },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Stack>
|
||||||
|
<Stack spacing={0}>
|
||||||
|
<Title order={2}>Contact Information</Title>
|
||||||
|
<Text>For general inquiries, please contact us !</Text>
|
||||||
|
</Stack>
|
||||||
|
<Group>
|
||||||
|
<IconBrandGmail
|
||||||
|
size={40}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "gray",
|
||||||
|
borderRadius: "10%",
|
||||||
|
padding: "5px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Stack spacing={0}>
|
||||||
|
<Text fw={"bold"}>Email</Text>
|
||||||
|
<Text>bip.baliinteraktifperkasa@gmail.com</Text>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Group>
|
||||||
|
<IconLocation
|
||||||
|
size={40}
|
||||||
|
style={{
|
||||||
|
backgroundColor: "gray",
|
||||||
|
borderRadius: "10%",
|
||||||
|
padding: "5px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Stack spacing={0}>
|
||||||
|
<Text fw={"bold"}>Location</Text>
|
||||||
|
<Text>Bali, Indonesia</Text>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Stack>
|
||||||
|
<Title order={2}>Send a Message</Title>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
label="Email"
|
||||||
|
placeholder="Email"
|
||||||
|
onChange={(e) => {
|
||||||
|
setData({
|
||||||
|
...data,
|
||||||
|
email: e.target.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
label="Title"
|
||||||
|
placeholder="Title"
|
||||||
|
onChange={(e) => {
|
||||||
|
setData({
|
||||||
|
...data,
|
||||||
|
title: e.target.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Textarea
|
||||||
|
label="Description"
|
||||||
|
placeholder="Description"
|
||||||
|
onChange={(e) => {
|
||||||
|
setData({
|
||||||
|
...data,
|
||||||
|
description: e.target.value,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
loading={isLoading}
|
||||||
|
color="yellow"
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</SimpleGrid>
|
||||||
|
</Paper>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,109 +3,107 @@ import backendLogger from "@/util/backendLogger";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
export async function GET(req: Request,
|
export async function GET(
|
||||||
{ params }: { params: { id: string } }) {
|
req: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
let fixData;
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
|
||||||
try {
|
if (!page) {
|
||||||
let fixData;
|
fixData = await prisma.donasi_Invoice.findMany({
|
||||||
const { id } = params;
|
orderBy: {
|
||||||
const { searchParams } = new URL(req.url);
|
createdAt: "desc",
|
||||||
const page = searchParams.get("page");
|
|
||||||
const status = searchParams.get("status");
|
|
||||||
const takeData = 10
|
|
||||||
const skipData = Number(page) * takeData - takeData;
|
|
||||||
|
|
||||||
if (!page) {
|
|
||||||
fixData = await prisma.donasi_Invoice.findMany({
|
|
||||||
orderBy: {
|
|
||||||
createdAt: "desc",
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
donasiId: id,
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
nominal: true,
|
|
||||||
createdAt: true,
|
|
||||||
Author: true,
|
|
||||||
DonasiMaster_Bank: true,
|
|
||||||
DonasiMaster_StatusInvoice: true,
|
|
||||||
donasiMaster_StatusInvoiceId: true,
|
|
||||||
imagesId: true,
|
|
||||||
imageId: true,
|
|
||||||
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
const fixStatus = _.startCase(status ? status : "");
|
|
||||||
const data = await prisma.donasi_Invoice.findMany({
|
|
||||||
take: takeData,
|
|
||||||
skip: skipData,
|
|
||||||
orderBy: {
|
|
||||||
createdAt: "desc",
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
|
|
||||||
donasiId: id,
|
|
||||||
active: true,
|
|
||||||
DonasiMaster_StatusInvoice: {
|
|
||||||
name: {
|
|
||||||
contains: fixStatus,
|
|
||||||
mode: "insensitive",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
nominal: true,
|
|
||||||
createdAt: true,
|
|
||||||
Author: true,
|
|
||||||
DonasiMaster_Bank: true,
|
|
||||||
DonasiMaster_StatusInvoice: true,
|
|
||||||
donasiMaster_StatusInvoiceId: true,
|
|
||||||
imagesId: true,
|
|
||||||
imageId: true,
|
|
||||||
|
|
||||||
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const nCount = await prisma.donasi_Invoice.count({
|
|
||||||
where: {
|
|
||||||
donasiId: id,
|
|
||||||
active: true,
|
|
||||||
DonasiMaster_StatusInvoice: {
|
|
||||||
name: {
|
|
||||||
contains: fixStatus,
|
|
||||||
mode: "insensitive",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
fixData = {
|
|
||||||
data: data,
|
|
||||||
nPage: _.ceil(nCount / takeData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NextResponse.json({
|
|
||||||
success: true,
|
|
||||||
message: "Success",
|
|
||||||
data: fixData,
|
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
where: {
|
||||||
)
|
donasiId: id,
|
||||||
} catch (error) {
|
active: true,
|
||||||
backendLogger.error("Error get data donatur >>", error);
|
|
||||||
return NextResponse.json({
|
|
||||||
success: false,
|
|
||||||
message: "Error get data donatur",
|
|
||||||
reason: (error as Error).message
|
|
||||||
},
|
},
|
||||||
{ status: 500 }
|
select: {
|
||||||
)
|
id: true,
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
Author: true,
|
||||||
|
DonasiMaster_Bank: true,
|
||||||
|
DonasiMaster_StatusInvoice: true,
|
||||||
|
donasiMaster_StatusInvoiceId: true,
|
||||||
|
imagesId: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const fixStatus = _.startCase(status ? status : "");
|
||||||
|
const data = await prisma.donasi_Invoice.findMany({
|
||||||
|
take: takeData,
|
||||||
|
skip: skipData,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
active: true,
|
||||||
|
DonasiMaster_StatusInvoice: {
|
||||||
|
name: {
|
||||||
|
contains: fixStatus,
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
Author: true,
|
||||||
|
DonasiMaster_Bank: true,
|
||||||
|
DonasiMaster_StatusInvoice: true,
|
||||||
|
donasiMaster_StatusInvoiceId: true,
|
||||||
|
imagesId: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const nCount = await prisma.donasi_Invoice.count({
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
active: true,
|
||||||
|
DonasiMaster_StatusInvoice: {
|
||||||
|
name: {
|
||||||
|
contains: fixStatus,
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
data: data,
|
||||||
|
nPage: _.ceil(nCount / takeData),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
backendLogger.error("Error get data donatur >>", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get data donatur",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ import { prisma } from "@/lib";
|
|||||||
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
import backendLogger from "@/util/backendLogger";
|
import backendLogger from "@/util/backendLogger";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { funSendToWhatsApp } from "@/lib/code-otp-sender";
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
if (req.method !== "POST") {
|
if (req.method !== "POST") {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ success: false, message: "Method Not Allowed" },
|
{ success: false, message: "Method Not Allowed" },
|
||||||
{ status: 405 }
|
{ status: 405 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,31 +27,30 @@ export async function POST(req: Request) {
|
|||||||
if (!createOtpId)
|
if (!createOtpId)
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ success: false, message: "Gagal mengirim kode OTP" },
|
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||||
{ status: 400 }
|
{ status: 400 },
|
||||||
);
|
);
|
||||||
|
|
||||||
const res = await fetch(
|
const resSendCode = await funSendToWhatsApp({
|
||||||
`https://wa.wibudev.com/code?nom=${nomor}&text=HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.
|
nomor,
|
||||||
\n
|
codeOtp: codeOtp.toString(),
|
||||||
>> Kode OTP anda: ${codeOtp}.
|
});
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
const sendWa = await res.json();
|
if (resSendCode.status !== 200)
|
||||||
|
|
||||||
if (sendWa.status !== "success")
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||||
{ status: 400 }
|
{ status: 400 },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const sendWa = await resSendCode.text();
|
||||||
|
console.log("WA Response:", sendWa);
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
message: "Kode verifikasi terkirim",
|
message: "Kode verifikasi terkirim",
|
||||||
kodeId: createOtpId.id,
|
kodeId: createOtpId.id,
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
{ status: 200 },
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
backendLogger.log("Error Login", error);
|
backendLogger.log("Error Login", error);
|
||||||
@@ -60,9 +60,7 @@ export async function POST(req: Request) {
|
|||||||
message: "Terjadi masalah saat login",
|
message: "Terjadi masalah saat login",
|
||||||
reason: error as Error,
|
reason: error as Error,
|
||||||
},
|
},
|
||||||
{ status: 500 }
|
{ status: 500 },
|
||||||
);
|
);
|
||||||
} finally {
|
|
||||||
await prisma.$disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/app/api/auth/mobile-eula/route.tsx
Normal file
54
src/app/api/auth/mobile-eula/route.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
try {
|
||||||
|
const { nomor } = await req.json();
|
||||||
|
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
nomor: nomor,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "User belum terdaftar",
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateTerms = await prisma.user.update({
|
||||||
|
where: { nomor: nomor },
|
||||||
|
data: {
|
||||||
|
termsOfServiceAccepted: true,
|
||||||
|
acceptedTermsAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateTerms) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal setujui syarat dan ketentuan",
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Anda telah setujui syarat dan ketentuan",
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Terjadi masalah saat setujui syarat dan ketentuan",
|
||||||
|
reason: error as Error,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/app/api/auth/mobile-login/route.ts
Normal file
71
src/app/api/auth/mobile-login/route.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { funSendToWhatsApp } from "@/lib/code-otp-sender";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
try {
|
||||||
|
const codeOtp = randomOTP();
|
||||||
|
const body = await req.json();
|
||||||
|
const { nomor } = body;
|
||||||
|
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
nomor: nomor,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "User tidak ditemukan",
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
|
data: {
|
||||||
|
nomor: nomor,
|
||||||
|
otp: codeOtp,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createOtpId)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const resSendCode = await funSendToWhatsApp({
|
||||||
|
nomor,
|
||||||
|
codeOtp: codeOtp.toString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resSendCode.status !== 200)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const sendWa = await resSendCode.text();
|
||||||
|
console.log("WA Response:", sendWa);
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Kode verifikasi terkirim",
|
||||||
|
kodeId: createOtpId.id,
|
||||||
|
isAcceptTerms: user.termsOfServiceAccepted,
|
||||||
|
},
|
||||||
|
{ status: 200 },
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Terjadi masalah saat login",
|
||||||
|
reason: error as Error,
|
||||||
|
},
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
139
src/app/api/auth/mobile-register/route.ts
Normal file
139
src/app/api/auth/mobile-register/route.ts
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../types/type-mobile-notification";
|
||||||
|
import { funSendToWhatsApp } from "@/lib/code-otp-sender";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Method Not Allowed" },
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data } = await req.json();
|
||||||
|
console.log("data >>", data);
|
||||||
|
const codeOtp = randomOTP();
|
||||||
|
try {
|
||||||
|
const cekUsername = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
username: data.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cekUsername)
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Username sudah digunakan",
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ Validasi wajib setuju Terms
|
||||||
|
if (data.termsOfServiceAccepted !== true) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "You must agree to the Terms of Service",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const createUser = await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
username: data.username,
|
||||||
|
nomor: data.nomor,
|
||||||
|
active: false,
|
||||||
|
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||||
|
acceptedTermsAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createUser)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal Registrasi" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
|
data: {
|
||||||
|
nomor: data.nomor,
|
||||||
|
otp: codeOtp,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createOtpId)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const resSendCode = await funSendToWhatsApp({
|
||||||
|
nomor: data.nomor,
|
||||||
|
codeOtp: codeOtp.toString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (resSendCode.status !== 200)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const sendWa = await resSendCode.text();
|
||||||
|
console.log("WA Response:", sendWa);
|
||||||
|
|
||||||
|
|
||||||
|
// =========== START SEND NOTIFICATION =========== //
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: { masterUserRoleId: "2", NOT: { id: data.authorId } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Users to notify:", adminUsers);
|
||||||
|
|
||||||
|
const dataNotification = {
|
||||||
|
title: "Pendaftaran Baru",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "OTHER",
|
||||||
|
createdAt: new Date(),
|
||||||
|
pesan: "User baru telah melakukan registrasi. Ayo cek dan verifikasi!",
|
||||||
|
deepLink: `/admin/user-access/${createUser.id}`,
|
||||||
|
senderId: createUser.id,
|
||||||
|
};
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pendaftaran User Baru" as NotificationMobileTitleType,
|
||||||
|
body: "User baru telah melakukan registrasi. Ayo cek dan verifikasi!" as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeAdminMobile.userAccess({ id: createUser.id }),
|
||||||
|
kategoriApp: "OTHER",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// =========== END SEND NOTIFICATION =========== //
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Registrasi Berhasil",
|
||||||
|
kodeId: createOtpId.id,
|
||||||
|
},
|
||||||
|
{ status: 201 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Maaf, Terjadi Keselahan",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/app/api/auth/mobile-validasi/route.ts
Normal file
82
src/app/api/auth/mobile-validasi/route.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import backendLogger from "@/util/backendLogger";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Method Not Allowed" },
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { nomor } = await req.json();
|
||||||
|
|
||||||
|
const dataUser = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
nomor: nomor,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nomor: true,
|
||||||
|
username: true,
|
||||||
|
active: true,
|
||||||
|
masterUserRoleId: true,
|
||||||
|
termsOfServiceAccepted: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dataUser == null)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Nomor Belum Terdaftar" },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const token = await sessionCreate({
|
||||||
|
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||||
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
|
user: dataUser as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal membuat session" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Buat response dengan token dalam cookie
|
||||||
|
const response = NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil Login",
|
||||||
|
roleId: dataUser.masterUserRoleId,
|
||||||
|
active: dataUser.active,
|
||||||
|
termsOfServiceAccepted: dataUser.termsOfServiceAccepted,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set cookie dengan token yang sudah dipastikan tidak null
|
||||||
|
response.cookies.set(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, token, {
|
||||||
|
path: "/",
|
||||||
|
sameSite: "lax",
|
||||||
|
secure: process.env.NODE_ENV === "production",
|
||||||
|
maxAge: 30 * 24 * 60 * 60, // 30 hari dalam detik (1 bulan)
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
backendLogger.log("API Error or Server Error", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Maaf, Terjadi Keselahan",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@ export async function POST(req: Request) {
|
|||||||
try {
|
try {
|
||||||
const { data } = await req.json();
|
const { data } = await req.json();
|
||||||
|
|
||||||
|
console.log("data >>", data);
|
||||||
|
|
||||||
const cekUsername = await prisma.user.findUnique({
|
const cekUsername = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
username: data.username,
|
username: data.username,
|
||||||
@@ -26,11 +28,20 @@ export async function POST(req: Request) {
|
|||||||
message: "Username sudah digunakan",
|
message: "Username sudah digunakan",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ✅ Validasi wajib setuju Terms
|
||||||
|
if (data.termsOfServiceAccepted !== true) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "You must agree to the Terms of Service",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const createUser = await prisma.user.create({
|
const createUser = await prisma.user.create({
|
||||||
data: {
|
data: {
|
||||||
username: data.username,
|
username: data.username,
|
||||||
nomor: data.nomor,
|
nomor: data.nomor,
|
||||||
active: false,
|
active: false,
|
||||||
|
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -51,7 +62,7 @@ export async function POST(req: Request) {
|
|||||||
success: true,
|
success: true,
|
||||||
message: "Registrasi Berhasil, Anda Sedang Login",
|
message: "Registrasi Berhasil, Anda Sedang Login",
|
||||||
token: token,
|
token: token,
|
||||||
// data: createUser,
|
// data: createUser,x
|
||||||
},
|
},
|
||||||
{ status: 201 }
|
{ status: 201 }
|
||||||
);
|
);
|
||||||
@@ -65,7 +76,5 @@ export async function POST(req: Request) {
|
|||||||
},
|
},
|
||||||
{ status: 500 }
|
{ status: 500 }
|
||||||
);
|
);
|
||||||
} finally {
|
|
||||||
await prisma.$disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ import { prisma } from "@/lib";
|
|||||||
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
import backendLogger from "@/util/backendLogger";
|
import backendLogger from "@/util/backendLogger";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { funSendToWhatsApp } from "@/lib/code-otp-sender";
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
if (req.method !== "POST") {
|
if (req.method !== "POST") {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ success: false, message: "Method Not Allowed" },
|
{ success: false, message: "Method Not Allowed" },
|
||||||
{ status: 405 }
|
{ status: 405 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,23 +17,20 @@ export async function POST(req: Request) {
|
|||||||
const body = await req.json();
|
const body = await req.json();
|
||||||
const { nomor } = body;
|
const { nomor } = body;
|
||||||
|
|
||||||
const res = await fetch(
|
const resSendCode = await funSendToWhatsApp({
|
||||||
`https://wa.wibudev.com/code?nom=${nomor}&text=HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.
|
nomor,
|
||||||
\n
|
codeOtp: codeOtp.toString(),
|
||||||
>> Kode OTP anda: ${codeOtp}.
|
});
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
const sendWa = await res.json();
|
if (resSendCode.status !== 200)
|
||||||
if (sendWa.status !== "success")
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||||
success: false,
|
{ status: 400 },
|
||||||
message: "Nomor Whatsapp Tidak Aktif",
|
|
||||||
},
|
|
||||||
{ status: 400 }
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const sendWa = await resSendCode.text();
|
||||||
|
console.log("WA Response:", sendWa);
|
||||||
|
|
||||||
const createOtpId = await prisma.kodeOtp.create({
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
data: {
|
data: {
|
||||||
nomor: nomor,
|
nomor: nomor,
|
||||||
@@ -46,7 +44,7 @@ export async function POST(req: Request) {
|
|||||||
success: false,
|
success: false,
|
||||||
message: "Gagal Membuat Kode OTP",
|
message: "Gagal Membuat Kode OTP",
|
||||||
},
|
},
|
||||||
{ status: 400 }
|
{ status: 400 },
|
||||||
);
|
);
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -55,7 +53,7 @@ export async function POST(req: Request) {
|
|||||||
message: "Kode Verifikasi Dikirim",
|
message: "Kode Verifikasi Dikirim",
|
||||||
kodeId: createOtpId.id,
|
kodeId: createOtpId.id,
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
{ status: 200 },
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
backendLogger.error(" Error Resend OTP", error);
|
backendLogger.error(" Error Resend OTP", error);
|
||||||
@@ -64,7 +62,7 @@ export async function POST(req: Request) {
|
|||||||
success: false,
|
success: false,
|
||||||
message: "Server Whatsapp Error !!",
|
message: "Server Whatsapp Error !!",
|
||||||
},
|
},
|
||||||
{ status: 500 }
|
{ status: 500 },
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
await prisma.$disconnect();
|
await prisma.$disconnect();
|
||||||
|
|||||||
29
src/app/api/auth/term-service/route.ts
Normal file
29
src/app/api/auth/term-service/route.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
try {
|
||||||
|
const { data } = await req.json();
|
||||||
|
console.log("data >>", data);
|
||||||
|
|
||||||
|
const updateTermService = await prisma.user.update({
|
||||||
|
where: {
|
||||||
|
id: data.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("error >>", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ export async function POST(req: Request) {
|
|||||||
username: true,
|
username: true,
|
||||||
active: true,
|
active: true,
|
||||||
masterUserRoleId: true,
|
masterUserRoleId: true,
|
||||||
|
termsOfServiceAccepted: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ export async function POST(req: Request) {
|
|||||||
message: "Berhasil Login",
|
message: "Berhasil Login",
|
||||||
roleId: dataUser.masterUserRoleId,
|
roleId: dataUser.masterUserRoleId,
|
||||||
active: dataUser.active,
|
active: dataUser.active,
|
||||||
|
termsOfServiceAccepted: dataUser.termsOfServiceAccepted,
|
||||||
token: token,
|
token: token,
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
{ status: 200 }
|
||||||
@@ -76,7 +78,5 @@ export async function POST(req: Request) {
|
|||||||
},
|
},
|
||||||
{ status: 500 }
|
{ status: 500 }
|
||||||
);
|
);
|
||||||
} finally {
|
|
||||||
await prisma.$disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
41
src/app/api/helper/delete-account/route.ts
Normal file
41
src/app/api/helper/delete-account/route.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { Resend } from "resend";
|
||||||
|
|
||||||
|
const resend = new Resend(process.env.RESEND_APIKEY);
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
const body = await req.json();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { number } = body;
|
||||||
|
|
||||||
|
if (!number) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: "Missing required fields.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await resend.emails.send({
|
||||||
|
from: `+${number} <onboarding@resend.dev>`,
|
||||||
|
to: ["bagasbanuna02@gmail.com"], // ganti sesuai email kamu
|
||||||
|
// cc: ["bip.baliinteraktifperkasa@gmail.com"],
|
||||||
|
subject: "Delete Account",
|
||||||
|
html: `
|
||||||
|
<div style="font-family: Arial, sans-serif; font-size: 16px; color: #333;">
|
||||||
|
<h3>New Message to Delete Account</h3>
|
||||||
|
<p><strong>User with phone number +${number}</strong></p>
|
||||||
|
<p><strong>Description: Want to delete account !!</strong></p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, data });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/app/api/helper/support-center/route.ts
Normal file
42
src/app/api/helper/support-center/route.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { Resend } from "resend";
|
||||||
|
|
||||||
|
const resend = new Resend(process.env.RESEND_APIKEY);
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
const body = await req.json();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { email, title, description } = body;
|
||||||
|
|
||||||
|
if (!email || !title || !description) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: "Missing required fields.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await resend.emails.send({
|
||||||
|
from: `${email} <onboarding@resend.dev>`,
|
||||||
|
to: ["bagasbanuna02@gmail.com"],
|
||||||
|
// to: ["bip.baliinteraktifperkasa@gmail.com"],
|
||||||
|
subject: title,
|
||||||
|
html: `
|
||||||
|
<div style="font-family: Arial, sans-serif; font-size: 16px; color: #333;">
|
||||||
|
<h3>New Message Received</h3>
|
||||||
|
<p><strong>Email:</strong> ${email}</p>
|
||||||
|
<p><strong>Title:</strong> ${title}</p>
|
||||||
|
<p><strong>Description:</strong><br/>${description.replace(/\n/g, "<br/>")}</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, data });
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,6 +78,7 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
select: {
|
select: {
|
||||||
User: {
|
User: {
|
||||||
select: {
|
select: {
|
||||||
|
nomor: true,
|
||||||
username: true,
|
username: true,
|
||||||
id: true,
|
id: true,
|
||||||
Profile: {
|
Profile: {
|
||||||
|
|||||||
215
src/app/api/mobile/admin/donation/[id]/disbursement/route.ts
Normal file
215
src/app/api/mobile/admin/donation/[id]/disbursement/route.ts
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
import { funFindDonaturList } from "@/lib/mobile/donation/find-donatur-list";
|
||||||
|
import {
|
||||||
|
sendNotificationMobileToManyUser,
|
||||||
|
sendNotificationMobileToOneUser,
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
|
export { POST, GET };
|
||||||
|
|
||||||
|
async function POST(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
const { title, nominalCair, deskripsi, imageId, authorId } = data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const dataDonasi = await prisma.donasi.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
akumulasiPencairan: true,
|
||||||
|
totalPencairan: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!dataDonasi)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "DataPencarian Donasi Gagal",
|
||||||
|
reason: "Data Pencarian Donasi Gagal",
|
||||||
|
},
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const createPencairan = await prisma.donasi_PencairanDana.create({
|
||||||
|
data: {
|
||||||
|
donasiId: id,
|
||||||
|
nominalCair: +nominalCair,
|
||||||
|
deskripsi: deskripsi,
|
||||||
|
title: title,
|
||||||
|
imageId: imageId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createPencairan)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Pencairan Dana Gagal",
|
||||||
|
reason: "Pencairan Dana Gagal",
|
||||||
|
},
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasilTotalPencairan =
|
||||||
|
Number(dataDonasi.totalPencairan) + Number(nominalCair);
|
||||||
|
// const hasilAkumulasiPencairan = Number(dataDonasi.akumulasiPencairan) + 1;
|
||||||
|
|
||||||
|
const countPencairan = await prisma.donasi_PencairanDana.count({
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateDonasi = await prisma.donasi.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
akumulasiPencairan: countPencairan,
|
||||||
|
totalPencairan: hasilTotalPencairan,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
title: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// ================= START SEND NOTIFICATION =================
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateDonasi?.authorId!,
|
||||||
|
senderId: authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pencairan Dana Berhasil" as NotificationMobileTitleType,
|
||||||
|
body: `Telah dilaksanakan pencairan dana untuk ${updateDonasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationDetailPublish({
|
||||||
|
id: id,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const recipientIds = await funFindDonaturList(id);
|
||||||
|
|
||||||
|
if (recipientIds.length > 0) {
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds,
|
||||||
|
senderId: authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pencarian Dana" as NotificationMobileTitleType,
|
||||||
|
body: `Update pencarian dana pada ${updateDonasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationDetailPublish({
|
||||||
|
id: id,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================= END SEND NOTIFICATION =================
|
||||||
|
|
||||||
|
if (!updateDonasi)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Update Donasi Gagal",
|
||||||
|
reason: "Update Donasi Gagal",
|
||||||
|
},
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Pencairan Dana Berhasil",
|
||||||
|
// data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 },
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Pencairan Dana Gagal",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
|
||||||
|
console.log("[CATEGORY]", category);
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
if (category === "get-all") {
|
||||||
|
fixData = await prisma.donasi_PencairanDana.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
createdAt: true,
|
||||||
|
nominalCair: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (category === "get-one") {
|
||||||
|
fixData = await prisma.donasi_PencairanDana.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Category tidak ditemukan",
|
||||||
|
reason: "Category tidak ditemukan",
|
||||||
|
},
|
||||||
|
{ status: 400 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success get data disbursement",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 },
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mendapatkan data disbursement",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
115
src/app/api/mobile/admin/donation/[id]/donatur/route.ts
Normal file
115
src/app/api/mobile/admin/donation/[id]/donatur/route.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(req: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
const fixStatus = _.startCase(status || "");
|
||||||
|
|
||||||
|
console.log("[FIX STATUS]", fixStatus);
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
if (status === null) {
|
||||||
|
fixData = await prisma.donasi_Invoice.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
Author: true,
|
||||||
|
DonasiMaster_Bank: true,
|
||||||
|
DonasiMaster_StatusInvoice: true,
|
||||||
|
donasiMaster_StatusInvoiceId: true,
|
||||||
|
imagesId: true,
|
||||||
|
imageId: true,
|
||||||
|
MasterBank: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const checkStatusTransaksi =
|
||||||
|
await prisma.donasiMaster_StatusInvoice.findFirst({
|
||||||
|
where: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[CHECK STATUS TRANSAKSI]", checkStatusTransaksi);
|
||||||
|
|
||||||
|
if (!checkStatusTransaksi)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get detail Investasi",
|
||||||
|
reason: "Status not found",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = await prisma.donasi_Invoice.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
active: true,
|
||||||
|
DonasiMaster_StatusInvoice: {
|
||||||
|
name: {
|
||||||
|
contains: checkStatusTransaksi.name,
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
Author: true,
|
||||||
|
DonasiMaster_Bank: true,
|
||||||
|
DonasiMaster_StatusInvoice: true,
|
||||||
|
donasiMaster_StatusInvoiceId: true,
|
||||||
|
imagesId: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil mendapatkan data",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get detail Investasi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
215
src/app/api/mobile/admin/donation/[id]/invoice/route.ts
Normal file
215
src/app/api/mobile/admin/donation/[id]/invoice/route.ts
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { sendNotificationMobileToOneUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { NotificationMobileBodyType, NotificationMobileTitleType } from "../../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(req: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
console.log("[ID]", id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.donasi_Invoice.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
donasiId: true,
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
Author: true,
|
||||||
|
DonasiMaster_StatusInvoice: true,
|
||||||
|
imageId: true,
|
||||||
|
MasterBank: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil mendapatkan data",
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get detail Investasi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TYPE DATA
|
||||||
|
interface DataType {
|
||||||
|
donationId: string;
|
||||||
|
nominal: number;
|
||||||
|
senderId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(req: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await req.json();
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const fixStatus = _.startCase(status as string);
|
||||||
|
|
||||||
|
console.log("[ID]", id);
|
||||||
|
console.log("[DATA]", data);
|
||||||
|
console.log("[FIX STATUS]", fixStatus);
|
||||||
|
|
||||||
|
const cloneData = data as DataType;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const checkStatusTransaksi =
|
||||||
|
await prisma.donasiMaster_StatusInvoice.findFirst({
|
||||||
|
where: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!checkStatusTransaksi)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed update status invoice",
|
||||||
|
reason: "Status not found",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const donasi = await prisma.donasi.findUnique({
|
||||||
|
where: {
|
||||||
|
id: data?.donationId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
target: true,
|
||||||
|
terkumpul: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!donasi) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed update status invoice",
|
||||||
|
reason: "Donasi not found",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateInvoice = await prisma.donasi_Invoice.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
donasiMaster_StatusInvoiceId: checkStatusTransaksi.id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateInvoice) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed update status invoice",
|
||||||
|
reason: "Update invoice failed",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalNominal =
|
||||||
|
Number(cloneData.nominal) + (Number(donasi.terkumpul) || 0);
|
||||||
|
const progres =
|
||||||
|
Math.floor((totalNominal / Number(donasi.target)) * 1000) / 10;
|
||||||
|
|
||||||
|
console.log("[STATUS]", checkStatusTransaksi);
|
||||||
|
console.log("[TOTAL NOMINAL]", totalNominal);
|
||||||
|
console.log("[PROGRES]", progres);
|
||||||
|
|
||||||
|
const updateDonasi = await prisma.donasi.update({
|
||||||
|
where: {
|
||||||
|
id: data?.donationId,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
terkumpul: "" + totalNominal,
|
||||||
|
progres: "" + progres,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateDonasi) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed update status invoice",
|
||||||
|
reason: "Update donasi failed",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEND NOTIFICATION: to donatur
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateInvoice?.authorId as string,
|
||||||
|
senderId: data?.senderId || "",
|
||||||
|
payload: {
|
||||||
|
title: "Transaksi Berhasil" as NotificationMobileTitleType,
|
||||||
|
body: `Selamat anda menjadi donatur pada ${updateDonasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationTransaction,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION: to creator
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateDonasi?.authorId as any,
|
||||||
|
senderId: data?.senderId || "",
|
||||||
|
payload: {
|
||||||
|
title: "Ada Donatur Baru !" as NotificationMobileTitleType,
|
||||||
|
body: `Cek daftar donatur pada ${updateDonasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationDetailPublish({
|
||||||
|
id: updateDonasi?.id as string,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil update status invoice",
|
||||||
|
data: updateDonasi,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error update status invoice",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
211
src/app/api/mobile/admin/donation/[id]/route.ts
Normal file
211
src/app/api/mobile/admin/donation/[id]/route.ts
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import {
|
||||||
|
sendNotificationMobileToManyUser,
|
||||||
|
sendNotificationMobileToOneUser,
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
try {
|
||||||
|
const { id } = params;
|
||||||
|
const donasiId = id;
|
||||||
|
const data = await prisma.donasi.findUnique({
|
||||||
|
where: {
|
||||||
|
id: donasiId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
target: true,
|
||||||
|
active: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: true,
|
||||||
|
publishTime: true,
|
||||||
|
catatan: true,
|
||||||
|
progres: true,
|
||||||
|
terkumpul: true,
|
||||||
|
authorId: true,
|
||||||
|
namaBank: true,
|
||||||
|
rekening: true,
|
||||||
|
totalPencairan: true,
|
||||||
|
akumulasiPencairan: true,
|
||||||
|
imagesId: true,
|
||||||
|
donasiMaster_KategoriId: true,
|
||||||
|
donasiMaster_DurasiId: true,
|
||||||
|
donasiMaster_StatusDonasiId: true,
|
||||||
|
Author: true,
|
||||||
|
imageDonasi: true,
|
||||||
|
CeritaDonasi: true,
|
||||||
|
DonasiMaster_Ketegori: true,
|
||||||
|
DonasiMaster_Durasi: true,
|
||||||
|
DonasiMaster_Status: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const successInvoice = await prisma.donasi_Invoice.count({
|
||||||
|
where: {
|
||||||
|
donasiId: donasiId,
|
||||||
|
DonasiMaster_StatusInvoice: {
|
||||||
|
name: "Berhasil",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Data Donasi Berhasil Diambil",
|
||||||
|
data: {
|
||||||
|
donasi: data,
|
||||||
|
donatur: successInvoice,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ status: 200 },
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get detail Investasi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
const { catatan, senderId } = data;
|
||||||
|
console.log("[PUT CATATAN]", catatan);
|
||||||
|
console.log("[PUT SENDER ID]", senderId);
|
||||||
|
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const fixStatus = _.startCase(status as string);
|
||||||
|
|
||||||
|
console.log("[PUT ID]", id);
|
||||||
|
console.log("[PUT DATA DONASI]", data);
|
||||||
|
console.log("[PUT DATA DONASI]", fixStatus);
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
const checkStatus = await prisma.donasiMaster_StatusDonasi.findFirst({
|
||||||
|
where: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[PUT CHECK STATUS]", checkStatus);
|
||||||
|
|
||||||
|
if (!checkStatus)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error update data event",
|
||||||
|
reason: "Status not found",
|
||||||
|
},
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
|
||||||
|
if (fixStatus === "Reject") {
|
||||||
|
const updateData = await prisma.donasi.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
catatan: catatan,
|
||||||
|
donasiMaster_StatusDonasiId: checkStatus.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateData.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Ditolak",
|
||||||
|
body: "Mohon perbaiki data sesuai catatan penolakan !",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationByStatus({ status: "reject" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = updateData;
|
||||||
|
} else if (fixStatus === "Publish") {
|
||||||
|
const updateData = await prisma.donasi.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
donasiMaster_StatusDonasiId: checkStatus.id,
|
||||||
|
publishTime: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICAtION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateData.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Review Selesai",
|
||||||
|
body: `Donasi kamu telah dipublikasikan ! ${updateData.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationByStatus({ status: "publish" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const allUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
NOT: { id: updateData.authorId as any },
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: allUsers.map((user) => user.id),
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Ayo Cek Donasi Terbaru" as NotificationMobileTitleType,
|
||||||
|
body: `${updateData.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationDetailPublish({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = updateData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Data Donasi Berhasil Diambil",
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 },
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get detail Investasi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
134
src/app/api/mobile/admin/donation/route.ts
Normal file
134
src/app/api/mobile/admin/donation/route.ts
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
console.log("[CATEGORY]", category);
|
||||||
|
let fixData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (category === "dashboard") {
|
||||||
|
const publish = await prisma.donasi.count({
|
||||||
|
where: {
|
||||||
|
DonasiMaster_Status: {
|
||||||
|
name: "Publish",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const review = await prisma.donasi.count({
|
||||||
|
where: {
|
||||||
|
DonasiMaster_Status: {
|
||||||
|
name: "Review",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const reject = await prisma.donasi.count({
|
||||||
|
where: {
|
||||||
|
DonasiMaster_Status: {
|
||||||
|
name: "Reject",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const countCategoryDonation = await prisma.donasiMaster_Kategori.findMany(
|
||||||
|
{
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "asc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const categoryDonation = countCategoryDonation.length;
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
publish,
|
||||||
|
review,
|
||||||
|
reject,
|
||||||
|
categoryDonation,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const fixCategory = _.startCase(category || "");
|
||||||
|
|
||||||
|
const checkStatus = await prisma.donasiMaster_StatusDonasi.findFirst({
|
||||||
|
where: {
|
||||||
|
name: fixCategory,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[STATUS]", checkStatus);
|
||||||
|
|
||||||
|
if (!checkStatus) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed to get data donation",
|
||||||
|
reason: "Status not found",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fixData = await prisma.donasi.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
DonasiMaster_Status: {
|
||||||
|
name: checkStatus.name,
|
||||||
|
},
|
||||||
|
active: true,
|
||||||
|
title: {
|
||||||
|
contains: search || "",
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[LIST]", fixData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: `Success get data donation ${category}`,
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error get data donation:", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed to get data donation",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/app/api/mobile/admin/event/[id]/participants/route.ts
Normal file
58
src/app/api/mobile/admin/event/[id]/participants/route.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
try {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
const data = await prisma.event_Peserta.findMany({
|
||||||
|
where: {
|
||||||
|
eventId: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
eventId: true,
|
||||||
|
userId: true,
|
||||||
|
isPresent: true,
|
||||||
|
User: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
nomor: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Event: {
|
||||||
|
select: {
|
||||||
|
tanggal: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success get participants",
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get participants",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
184
src/app/api/mobile/admin/event/[id]/route.ts
Normal file
184
src/app/api/mobile/admin/event/[id]/route.ts
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import _ from "lodash";
|
||||||
|
import {
|
||||||
|
sendNotificationMobileToManyUser,
|
||||||
|
sendNotificationMobileToOneUser,
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.event.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
nomor: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
alamat: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EventMaster_TipeAcara: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EventMaster_Status: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success get data event",
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed to get data",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
const { catatan, senderId } = data;
|
||||||
|
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const fixStatus = _.startCase(status as string);
|
||||||
|
|
||||||
|
console.log("ID", id);
|
||||||
|
console.log("DATA", data);
|
||||||
|
console.log("FIX STATUS", fixStatus);
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
const checkStatus = await prisma.eventMaster_Status.findFirst({
|
||||||
|
where: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!checkStatus)
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error update data event",
|
||||||
|
reason: "Status not found",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
|
||||||
|
if (fixStatus === "Reject") {
|
||||||
|
const updateData = await prisma.event.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
catatan: catatan,
|
||||||
|
eventMaster_StatusId: checkStatus.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateData.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Ditolak",
|
||||||
|
body: "Mohon perbaiki data sesuai catatan penolakan !",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "EVENT",
|
||||||
|
deepLink: routeUserMobile.eventByStatus({status: "reject"}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = updateData;
|
||||||
|
} else if (fixStatus === "Publish") {
|
||||||
|
const updateData = await prisma.event.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
eventMaster_StatusId: checkStatus.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateData.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Review Selesai",
|
||||||
|
body: "Event kamu telah dipublikasikan !" as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "EVENT",
|
||||||
|
deepLink: routeUserMobile.eventByStatus({status: "publish"}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: "1",
|
||||||
|
NOT: { id: updateData.authorId as any },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Event Baru" as NotificationMobileTitleType,
|
||||||
|
body: `${updateData.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "EVENT",
|
||||||
|
deepLink: routeUserMobile.eventDetailPublised({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = updateData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success update data event",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Failed to update data",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
193
src/app/api/mobile/admin/event/route.ts
Normal file
193
src/app/api/mobile/admin/event/route.ts
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
const fixStatus = _.startCase(category || "");
|
||||||
|
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
let fixData;
|
||||||
|
|
||||||
|
console.log("[CATEGORY]", category);
|
||||||
|
// console.log("[FIX STATUS]", fixStatus);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (category === "dashboard") {
|
||||||
|
const publish = await prisma.event.count({
|
||||||
|
where: {
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: "Publish",
|
||||||
|
},
|
||||||
|
isArsip: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const review = await prisma.event.count({
|
||||||
|
where: {
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: "Review",
|
||||||
|
},
|
||||||
|
isArsip: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const reject = await prisma.event.count({
|
||||||
|
where: {
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: "Reject",
|
||||||
|
},
|
||||||
|
isArsip: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const history = await prisma.event.count({
|
||||||
|
where: {
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: "Publish",
|
||||||
|
},
|
||||||
|
isArsip: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const typeOfEvent = await prisma.eventMaster_TipeAcara.count({
|
||||||
|
where: {
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
publish,
|
||||||
|
review,
|
||||||
|
reject,
|
||||||
|
history,
|
||||||
|
typeOfEvent,
|
||||||
|
};
|
||||||
|
} else if (category === "history") {
|
||||||
|
console.log("[HISTORY HERE]");
|
||||||
|
|
||||||
|
const data = await prisma.event.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
isArsip: true,
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: "Publish",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
contains: search || "",
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = data;
|
||||||
|
} else {
|
||||||
|
if (fixStatus === "Publish") {
|
||||||
|
const getAllData = await prisma.event.findMany({
|
||||||
|
where: {
|
||||||
|
active: true,
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
isArsip: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i of getAllData) {
|
||||||
|
if (moment(i.tanggalSelesai).diff(moment(), "minutes") < 0) {
|
||||||
|
await prisma.event.update({
|
||||||
|
where: {
|
||||||
|
id: i.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
isArsip: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await prisma.event.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
tanggal: "asc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
active: true,
|
||||||
|
isArsip: false,
|
||||||
|
EventMaster_Status: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
contains: search || "",
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
tanggal: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: `Success get data event ${category}`,
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`[ERROR GET DATA EVENT: ${category}]`, error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: `Error get data event ${category}`,
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { sendNotificationMobileToOneUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { GET, PUT };
|
export { GET, PUT };
|
||||||
|
|
||||||
@@ -82,21 +88,43 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
|
const data = await request.json();
|
||||||
|
|
||||||
|
console.log("SENDER Comment", data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const deleteData = await prisma.forum_Komentar.update({
|
const deactiveComment = await prisma.forum_Komentar.update({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
isActive: false,
|
isActive: false,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
komentar: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: deactiveComment?.authorId as string,
|
||||||
|
senderId: data?.senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Penghapusan Komentar" as NotificationMobileTitleType,
|
||||||
|
body: `Komentar anda telah dilaporkan: ${deactiveComment?.komentar}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeUserMobile.forumPreviewReportComment({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[DEACTIVATE COMMENT]");
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
message: "Success deactivate comment",
|
message: "Success deactivate comment",
|
||||||
data: deleteData,
|
// data: deactiveComment,
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
{ status: 200 }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { sendNotificationMobileToOneUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { GET, PUT };
|
export { GET, PUT };
|
||||||
|
|
||||||
@@ -78,14 +84,23 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
|
const data = await request.json();
|
||||||
|
const { senderId } = data;
|
||||||
|
|
||||||
|
console.log("SENDER POSTING", data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await prisma.forum_Posting.update({
|
const deactivePosting = await prisma.forum_Posting.update({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
isActive: false,
|
isActive: false,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
diskusi: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const deactivateComment = await prisma.forum_Komentar.updateMany({
|
const deactivateComment = await prisma.forum_Komentar.updateMany({
|
||||||
@@ -97,12 +112,25 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("[DEACTIVATE COMMENT]", deactivateComment);
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: deactivePosting?.authorId as string,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Penghapusan Postingan" as NotificationMobileTitleType,
|
||||||
|
body: `Postingan anda telah dilaporkan: ${deactivePosting?.diskusi}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeUserMobile.forumPreviewReportPosting({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[DEACTIVATE POSTINGAN & COMMENT]", deactivateComment);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
message: "Success deactivate posting",
|
message: "Success deactivate posting",
|
||||||
data: data,
|
data: deactivePosting,
|
||||||
},
|
},
|
||||||
{ status: 200 }
|
{ status: 200 }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
export { GET };
|
export { GET };
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ async function GET(request: Request, { params }: { params: { name: string } }) {
|
|||||||
reportComment,
|
reportComment,
|
||||||
};
|
};
|
||||||
} else if (category === "posting") {
|
} else if (category === "posting") {
|
||||||
fixData = await prisma.forum_Posting.findMany({
|
const data = await prisma.forum_Posting.findMany({
|
||||||
take: page ? takeData : undefined,
|
take: page ? takeData : undefined,
|
||||||
skip: page ? skipData : undefined,
|
skip: page ? skipData : undefined,
|
||||||
orderBy: {
|
orderBy: {
|
||||||
@@ -75,10 +76,24 @@ async function GET(request: Request, { params }: { params: { name: string } }) {
|
|||||||
Profile: true,
|
Profile: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
_count: {
|
||||||
|
select: {
|
||||||
|
Forum_ReportPosting: true,
|
||||||
|
Forum_Komentar: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fixData = data.map((item) => ({
|
||||||
|
..._.omit(item, "_count"),
|
||||||
|
reportPosting: item._count.Forum_ReportPosting,
|
||||||
|
komentar: item._count.Forum_Komentar,
|
||||||
|
}));
|
||||||
|
|
||||||
|
console.log("fixData >>", fixData);
|
||||||
} else if (category === "report_posting") {
|
} else if (category === "report_posting") {
|
||||||
fixData = await prisma.forum_ReportPosting.findMany({
|
const data = await prisma.forum_ReportPosting.findMany({
|
||||||
take: page ? takeData : undefined,
|
take: page ? takeData : undefined,
|
||||||
skip: page ? skipData : undefined,
|
skip: page ? skipData : undefined,
|
||||||
orderBy: {
|
orderBy: {
|
||||||
@@ -123,8 +138,25 @@ async function GET(request: Request, { params }: { params: { name: string } }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const filterLatest = (data: any) =>
|
||||||
|
Object.values(
|
||||||
|
data.reduce((acc: any, item: any) => {
|
||||||
|
const key = item.Forum_Posting?.id;
|
||||||
|
if (!key) return acc;
|
||||||
|
if (
|
||||||
|
!acc[key] ||
|
||||||
|
new Date(item.createdAt) > new Date(acc[key].createdAt)
|
||||||
|
) {
|
||||||
|
acc[key] = item;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
|
|
||||||
|
fixData = filterLatest(data);
|
||||||
} else if (category === "report_comment") {
|
} else if (category === "report_comment") {
|
||||||
fixData = await prisma.forum_ReportKomentar.findMany({
|
const data = await prisma.forum_ReportKomentar.findMany({
|
||||||
take: page ? takeData : undefined,
|
take: page ? takeData : undefined,
|
||||||
skip: page ? skipData : undefined,
|
skip: page ? skipData : undefined,
|
||||||
orderBy: {
|
orderBy: {
|
||||||
@@ -160,6 +192,23 @@ async function GET(request: Request, { params }: { params: { name: string } }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const filterLatest = (data: any) =>
|
||||||
|
Object.values(
|
||||||
|
data.reduce((acc: any, item: any) => {
|
||||||
|
const key = item.Forum_Komentar?.id;
|
||||||
|
if (!key) return acc;
|
||||||
|
if (
|
||||||
|
!acc[key] ||
|
||||||
|
new Date(item.createdAt) > new Date(acc[key].createdAt)
|
||||||
|
) {
|
||||||
|
acc[key] = item;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
);
|
||||||
|
|
||||||
|
fixData = filterLatest(data);
|
||||||
} else {
|
} else {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
@@ -171,7 +220,6 @@ async function GET(request: Request, { params }: { params: { name: string } }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
70
src/app/api/mobile/admin/investment/[id]/investor/route.ts
Normal file
70
src/app/api/mobile/admin/investment/[id]/investor/route.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
let fixData;
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
|
||||||
|
const fixStatus = _.startCase(status ? status : "");
|
||||||
|
|
||||||
|
const checkStatus = await prisma.investasiMaster_StatusInvoice.findFirst({
|
||||||
|
where: {
|
||||||
|
name: fixStatus,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await prisma.investasi_Invoice.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
investasiId: id,
|
||||||
|
isActive: true,
|
||||||
|
StatusInvoice: {
|
||||||
|
name: {
|
||||||
|
contains: checkStatus?.name,
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
Author: true,
|
||||||
|
StatusInvoice: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = data;
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success get status transaksi",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Eror get status transaksi", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get status transaksi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
235
src/app/api/mobile/admin/investment/[id]/invoice/route.ts
Normal file
235
src/app/api/mobile/admin/investment/[id]/invoice/route.ts
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { sendNotificationMobileToOneUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(req: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.investasi_Invoice.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
investasiId: true,
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
Author: true,
|
||||||
|
StatusInvoice: true,
|
||||||
|
imageId: true,
|
||||||
|
MasterBank: true,
|
||||||
|
lembarTerbeli: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil mendapatkan data",
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get detail Investasi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(req: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await req.json();
|
||||||
|
const { searchParams } = new URL(req.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
|
||||||
|
console.log("[ID]", id);
|
||||||
|
console.log("[DATA]", data);
|
||||||
|
console.log("[CATEGORY]", category);
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
if (category === "deny") {
|
||||||
|
const updt = await prisma.investasi_Invoice.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
statusInvoiceId: "4",
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
Investasi: {
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICAtION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updt?.authorId as string,
|
||||||
|
senderId: data?.senderId || "",
|
||||||
|
payload: {
|
||||||
|
title: "Transaksi Tertolak" as NotificationMobileTitleType,
|
||||||
|
body: `Maaf transaksi kamu telah ditolak ! ${updt?.Investasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentTransaction,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = updt;
|
||||||
|
} else if (category === "accept") {
|
||||||
|
const findInvestasi = await prisma.investasi.findFirst({
|
||||||
|
where: {
|
||||||
|
id: data.investasiId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
authorId: true,
|
||||||
|
totalLembar: true,
|
||||||
|
sisaLembar: true,
|
||||||
|
lembarTerbeli: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hitung TOTAL SISA LEMBAR
|
||||||
|
const investasi_sisaLembar = Number(findInvestasi?.sisaLembar);
|
||||||
|
const invoice_lembarTerbeli = Number(data.lembarTerbeli);
|
||||||
|
const resultSisaLembar = investasi_sisaLembar - invoice_lembarTerbeli;
|
||||||
|
|
||||||
|
// TAMBAH LEMBAR TERBELI
|
||||||
|
const investasi_lembarTerbeli = Number(findInvestasi?.lembarTerbeli);
|
||||||
|
const resultLembarTerbeli =
|
||||||
|
investasi_lembarTerbeli + invoice_lembarTerbeli;
|
||||||
|
|
||||||
|
// Progress
|
||||||
|
const investasi_totalLembar = Number(findInvestasi?.totalLembar);
|
||||||
|
const progress = (resultLembarTerbeli / investasi_totalLembar) * 100;
|
||||||
|
const resultProgres = Number(progress).toFixed(2);
|
||||||
|
|
||||||
|
const updateInvoice = await prisma.investasi_Invoice.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
statusInvoiceId: "1",
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateInvoice) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Gagal Update Status",
|
||||||
|
reason: "Update status failed",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateInvestasi = await prisma.investasi.update({
|
||||||
|
where: {
|
||||||
|
id: data.investasiId,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
sisaLembar: resultSisaLembar.toString(),
|
||||||
|
lembarTerbeli: resultLembarTerbeli.toString(),
|
||||||
|
progress: resultProgres,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
MasterStatusInvestasi: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updateInvestasi) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Gagal Update Data Investasi",
|
||||||
|
reason: "Update data investasi failed",
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SEND NOTIFICATION: to investor
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateInvoice?.authorId as string,
|
||||||
|
senderId: data?.senderId || "",
|
||||||
|
payload: {
|
||||||
|
title: "Transaksi Berhasil" as NotificationMobileTitleType,
|
||||||
|
body: `Selamat anda menjadi investor pada investasi ${findInvestasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentTransaction,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION: to creator
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: findInvestasi?.authorId as any,
|
||||||
|
senderId: data?.senderId || "",
|
||||||
|
payload: {
|
||||||
|
title: "Ada Investor Baru !" as NotificationMobileTitleType,
|
||||||
|
body: `Cek daftar investor pada ${findInvestasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentDetailPublish({
|
||||||
|
id: findInvestasi?.id as string,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = updateInvoice;
|
||||||
|
} else {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Invalid category",
|
||||||
|
reason: "Invalid category",
|
||||||
|
},
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil update data",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error update detail Investasi",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
201
src/app/api/mobile/admin/investment/[id]/route.ts
Normal file
201
src/app/api/mobile/admin/investment/[id]/route.ts
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
import {
|
||||||
|
sendNotificationMobileToManyUser,
|
||||||
|
sendNotificationMobileToOneUser,
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.investasi.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
imageId: true,
|
||||||
|
prospektusFileId: true,
|
||||||
|
id: true,
|
||||||
|
author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
nomor: true,
|
||||||
|
Profile: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
title: true,
|
||||||
|
authorId: true,
|
||||||
|
hargaLembar: true,
|
||||||
|
targetDana: true,
|
||||||
|
totalLembar: true,
|
||||||
|
sisaLembar: true,
|
||||||
|
lembarTerbeli: true,
|
||||||
|
progress: true,
|
||||||
|
roi: true,
|
||||||
|
active: true,
|
||||||
|
createdAt: true,
|
||||||
|
updatedAt: true,
|
||||||
|
catatan: true,
|
||||||
|
imagesId: true,
|
||||||
|
MasterStatusInvestasi: true,
|
||||||
|
BeritaInvestasi: true,
|
||||||
|
DokumenInvestasi: true,
|
||||||
|
ProspektusInvestasi: true,
|
||||||
|
MasterPembagianDeviden: true,
|
||||||
|
MasterPencarianInvestor: true,
|
||||||
|
MasterPeriodeDeviden: true,
|
||||||
|
MasterProgresInvestasi: true,
|
||||||
|
masterStatusInvestasiId: true,
|
||||||
|
countDown: true,
|
||||||
|
Investasi_Invoice: {
|
||||||
|
where: {
|
||||||
|
statusInvoiceId: "2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success get data investment",
|
||||||
|
data: data,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get data investment",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
const { catatan, senderId } = data;
|
||||||
|
|
||||||
|
console.log("[DATA]", data);
|
||||||
|
console.log("[CATATAN]", catatan);
|
||||||
|
console.log("[SENDER ID]", senderId);
|
||||||
|
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const status = searchParams.get("status");
|
||||||
|
|
||||||
|
// console.log("[=======Start Investment console=======]");
|
||||||
|
// console.log("[ID]", id);
|
||||||
|
// console.log("[STATUS]", status);
|
||||||
|
// console.log("[=======End Investment console=======]");
|
||||||
|
|
||||||
|
const publishTime = new Date();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (status === "reject") {
|
||||||
|
const updatedData = await prisma.investasi.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
catatan: catatan,
|
||||||
|
masterStatusInvestasiId: "4",
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
title: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updatedData.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Ditolak",
|
||||||
|
body: "Mohon perbaiki data sesuai catatan penolakan !",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentPortofolioByStatus({ status: "reject" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[UPDATE REJECT]", updatedData);
|
||||||
|
} else if (status === "publish") {
|
||||||
|
const updatedData = await prisma.investasi.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
masterStatusInvestasiId: "1",
|
||||||
|
masterProgresInvestasiId: "1",
|
||||||
|
countDown: publishTime,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICAtION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updatedData.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Review Selesai",
|
||||||
|
body: `Investasi kamu telah dipublikasikan ! ${updatedData.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentPortofolioByStatus({ status: "publish" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const allUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
NOT: { id: updatedData.authorId as any },
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: allUsers.map((user) => user.id),
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Ayo Cek Investasi Terbaru" as NotificationMobileTitleType,
|
||||||
|
body: `${updatedData.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentDetailPublish({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[UPDATE PUBLISH]", updatedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success update data investment",
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error update data investment",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/app/api/mobile/admin/investment/route.ts
Normal file
104
src/app/api/mobile/admin/investment/route.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = Number(page) * takeData - takeData;
|
||||||
|
|
||||||
|
console.log("[CATEGORY]", category);
|
||||||
|
console.log("[PAGE]", page);
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
if (category === "dashboard") {
|
||||||
|
const publish = await prisma.investasi.count({
|
||||||
|
where: {
|
||||||
|
MasterStatusInvestasi: {
|
||||||
|
name: "Publish",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const review = await prisma.investasi.count({
|
||||||
|
where: {
|
||||||
|
MasterStatusInvestasi: {
|
||||||
|
name: "Review",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const reject = await prisma.investasi.count({
|
||||||
|
where: {
|
||||||
|
MasterStatusInvestasi: {
|
||||||
|
name: "Reject",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
publish,
|
||||||
|
review,
|
||||||
|
reject,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const fixCategoryToStatus = _.startCase(category || "");
|
||||||
|
console.log("[STATUS]", fixCategoryToStatus);
|
||||||
|
|
||||||
|
const data = await prisma.investasi.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
updatedAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
active: true,
|
||||||
|
MasterStatusInvestasi: {
|
||||||
|
name: fixCategoryToStatus,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
contains: search || "",
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success get data investment",
|
||||||
|
data: fixData,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[ERROR GET DATA INVESTMENT]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get data investment",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import {
|
||||||
|
sendNotificationMobileToManyUser,
|
||||||
|
sendNotificationMobileToOneUser,
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
import { NotificationMobileBodyType, NotificationMobileTitleType } from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { GET, PUT };
|
export { GET, PUT };
|
||||||
|
|
||||||
@@ -54,6 +60,9 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
const { catatan, senderId } = data;
|
||||||
|
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const status = searchParams.get("status");
|
const status = searchParams.get("status");
|
||||||
const fixStatus = _.startCase(status as string);
|
const fixStatus = _.startCase(status as string);
|
||||||
@@ -83,7 +92,7 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
masterStatusId: checkStatus.id,
|
masterStatusId: checkStatus.id,
|
||||||
catatan: data,
|
catatan: catatan,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -97,6 +106,18 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updt.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Ditolak",
|
||||||
|
body: "Mohon perbaiki data sesuai catatan penolakan !",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "JOB",
|
||||||
|
deepLink: routeUserMobile.jobByStatus({ status: "reject" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
fixData = updt;
|
fixData = updt;
|
||||||
} else if (fixStatus === "Publish") {
|
} else if (fixStatus === "Publish") {
|
||||||
const updt = await prisma.job.update({
|
const updt = await prisma.job.update({
|
||||||
@@ -118,6 +139,35 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updt.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Review Selesai",
|
||||||
|
body: "Selamat data anda telah terpublikasi",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "JOB",
|
||||||
|
deepLink: routeUserMobile.jobByStatus({ status: "publish" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: { masterUserRoleId: "1", NOT: { id: updt.authorId as any } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Ada Lowongan Kerja Baru" as NotificationMobileTitleType,
|
||||||
|
body: `${updt.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeUserMobile.jobDetailPublised({ id: id }),
|
||||||
|
kategoriApp: "JOB",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
fixData = updt;
|
fixData = updt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,19 +4,55 @@ import { prisma } from "@/lib";
|
|||||||
export { GET, PUT };
|
export { GET, PUT };
|
||||||
|
|
||||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
let fixData;
|
||||||
try {
|
try {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const data = await prisma.masterBidangBisnis.findUnique({
|
const { searchParams } = new URL(request.url);
|
||||||
where: {
|
const category = searchParams.get("category");
|
||||||
id: id,
|
const subBidangId = searchParams.get("subBidangId");
|
||||||
},
|
|
||||||
});
|
if (category === "all") {
|
||||||
|
const bidang = await prisma.masterBidangBisnis.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const subBidang = await prisma.masterSubBidangBisnis.findMany({
|
||||||
|
orderBy: {
|
||||||
|
updatedAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
masterBidangBisnisId: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
bidang,
|
||||||
|
subBidang,
|
||||||
|
};
|
||||||
|
} else if (category === "bidang") {
|
||||||
|
const bidang = await prisma.masterBidangBisnis.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = bidang;
|
||||||
|
} else if (category === "sub-bidang") {
|
||||||
|
const subBidang = await prisma.masterSubBidangBisnis.findUnique({
|
||||||
|
where: {
|
||||||
|
id: subBidangId as any,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = subBidang;
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
success: true,
|
success: true,
|
||||||
message: "Berhasil mendapatkan data",
|
message: "Berhasil mendapatkan data",
|
||||||
data: data,
|
data: fixData,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error Get Master Bank >>", error);
|
console.error("Error Get Master Bank >>", error);
|
||||||
@@ -32,17 +68,34 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
|
||||||
|
console.log("category", category);
|
||||||
|
console.log("data", data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const updateData = await prisma.masterBidangBisnis.update({
|
if (category === "bidang") {
|
||||||
where: {
|
const updateData = await prisma.masterBidangBisnis.update({
|
||||||
id: id,
|
where: {
|
||||||
},
|
id: id,
|
||||||
data: {
|
},
|
||||||
name: data.name,
|
data: {
|
||||||
active: data.active,
|
name: data.name,
|
||||||
},
|
active: data.active,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
} else if (category === "sub-bidang") {
|
||||||
|
const updateData = await prisma.masterSubBidangBisnis.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
isActive: data.isActive,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
export { GET, POST };
|
export { GET, POST };
|
||||||
|
|
||||||
@@ -31,35 +33,186 @@ async function GET(request: Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BidangInput = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type SubBidangInput = {
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type RequestBody = {
|
||||||
|
data: {
|
||||||
|
bidang: BidangInput;
|
||||||
|
subBidang: SubBidangInput[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------
|
||||||
|
POST handler
|
||||||
|
- body: { bidang: { name }, subBidang: [{ name }, ...] }
|
||||||
|
- buat masterBidangBisnis (id incremental dari count + 1)
|
||||||
|
- generate id untuk tiap subBidang, cek unik, dan createMany via transaction
|
||||||
|
--------------------------- */
|
||||||
async function POST(request: Request) {
|
async function POST(request: Request) {
|
||||||
const { data } = await request.json();
|
|
||||||
try {
|
try {
|
||||||
const count = await prisma.masterBidangBisnis.count();
|
const { data } = (await request.json()) as RequestBody;
|
||||||
const createNewId = count + 1;
|
|
||||||
|
|
||||||
const slugName = data.name.toLowerCase().replace(/\s+/g, "_");
|
if (!data.bidang.name || !Array.isArray(data.subBidang)) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
success: false,
|
||||||
|
message:
|
||||||
|
"Invalid payload. Expect { bidang: { name }, subBidang: [] }",
|
||||||
|
},
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const create = await prisma.masterBidangBisnis.create({
|
// run in transaction to avoid race conditions
|
||||||
data: {
|
const result = await prisma.$transaction(async (tx) => {
|
||||||
id: createNewId.toString(),
|
// ambil last id numerik dengan cast (Postgres)
|
||||||
name: data.name,
|
const rows = await tx.$queryRaw<{ id: string }[]>`
|
||||||
slug: slugName,
|
SELECT id FROM "MasterBidangBisnis" ORDER BY (id::int) DESC LIMIT 1;
|
||||||
},
|
`;
|
||||||
|
const lastId = rows[0]?.id ?? null;
|
||||||
|
const bidangId = lastId ? String(Number(lastId) + 1) : "1";
|
||||||
|
|
||||||
|
const slugName = data.bidang.name.toLowerCase().replace(/\s+/g, "_");
|
||||||
|
|
||||||
|
const createdBidang = await tx.masterBidangBisnis.create({
|
||||||
|
data: {
|
||||||
|
id: bidangId,
|
||||||
|
name: data.bidang.name,
|
||||||
|
slug: slugName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2) hitung existing sub bidang untuk bidang ini
|
||||||
|
const existingSubCount = await tx.masterSubBidangBisnis.count({
|
||||||
|
where: { masterBidangBisnisId: createdBidang.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3) generate unique ids satu-per-satu (cek ke DB via tx)
|
||||||
|
const subBidangToCreate: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
masterBidangBisnisId: string;
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < data.subBidang.length; i++) {
|
||||||
|
const seqNumber = existingSubCount + i + 1; // 1-based
|
||||||
|
const uniqueId = await generateUniqueSubBidangId(
|
||||||
|
data.bidang.name,
|
||||||
|
seqNumber,
|
||||||
|
tx
|
||||||
|
);
|
||||||
|
|
||||||
|
// push object to array
|
||||||
|
subBidangToCreate.push({
|
||||||
|
id: uniqueId,
|
||||||
|
name: data.subBidang[i].name,
|
||||||
|
masterBidangBisnisId: createdBidang.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) createMany (batched) -- note: createMany doesn't return created rows
|
||||||
|
if (subBidangToCreate.length > 0) {
|
||||||
|
await tx.masterSubBidangBisnis.createMany({
|
||||||
|
data: subBidangToCreate,
|
||||||
|
skipDuplicates: false, // kita sudah memastikan unik, so false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { createdBidang, subBidang: subBidangToCreate };
|
||||||
});
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
success: true,
|
success: true,
|
||||||
message: "Berhasil menambahkan data",
|
message: "Berhasil menambahkan bidang dan sub bidang",
|
||||||
data: create,
|
data: result,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error Post Master Business Field >>", error);
|
console.error("Error Post Master Business Field >>", error);
|
||||||
return NextResponse.json({
|
const msg = error instanceof Error ? error.message : String(error);
|
||||||
status: 500,
|
return NextResponse.json(
|
||||||
success: false,
|
{
|
||||||
message: "API Error Post Data",
|
status: 500,
|
||||||
reason: (error as Error).message,
|
success: false,
|
||||||
});
|
message: "API Error Post Data",
|
||||||
|
reason: msg,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------
|
||||||
|
Helper: generate base code
|
||||||
|
- mengabaikan stop words: 'dan', 'atau', '&'
|
||||||
|
- ambil dua kata pertama yang tersisa
|
||||||
|
- ambil 3 huruf pertama tiap kata (jika ada)
|
||||||
|
--------------------------- */
|
||||||
|
function generateBaseCode(name: string) {
|
||||||
|
const stopWords = new Set(["dan", "atau", "&"]);
|
||||||
|
// keep only letters and spaces, normalize spaces
|
||||||
|
const cleaned = name
|
||||||
|
.normalize("NFD")
|
||||||
|
.replace(/[\u0300-\u036f]/g, "") // remove diacritics
|
||||||
|
.replace(/[^a-zA-Z\s&]/g, " ")
|
||||||
|
.replace(/\s+/g, " ")
|
||||||
|
.trim()
|
||||||
|
.toLowerCase();
|
||||||
|
|
||||||
|
const words = cleaned
|
||||||
|
.split(" ")
|
||||||
|
.filter((w) => w.length > 0 && !stopWords.has(w));
|
||||||
|
|
||||||
|
const primary = (words[0] ?? "xxx").substring(0, 3).toUpperCase();
|
||||||
|
const secondary = words[1] ? words[1].substring(0, 3).toUpperCase() : "";
|
||||||
|
|
||||||
|
return { primary, secondary };
|
||||||
|
}
|
||||||
|
|
||||||
|
function padNumber(n: number) {
|
||||||
|
return String(n).padStart(2, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------
|
||||||
|
generateUniqueSubBidangId
|
||||||
|
- cek urutan strategi:
|
||||||
|
1) PRIMARY-<NN>
|
||||||
|
2) PRIMARY-SECONDARY-<NN> (jika secondary ada)
|
||||||
|
3) PRIMARYSECONDARY-<NN> (jika secondary ada)
|
||||||
|
4) fallback: PRIMARY + last4Timestamp -<NN>
|
||||||
|
- menggunakan tx (Prisma.TransactionClient) untuk cek di DB
|
||||||
|
--------------------------- */
|
||||||
|
async function generateUniqueSubBidangId(
|
||||||
|
bidangName: string,
|
||||||
|
number: number,
|
||||||
|
tx: Prisma.TransactionClient
|
||||||
|
): Promise<string> {
|
||||||
|
const { primary, secondary } = generateBaseCode(bidangName);
|
||||||
|
const num = padNumber(number);
|
||||||
|
|
||||||
|
const candidates: string[] = [];
|
||||||
|
candidates.push(`${primary}-${num}`);
|
||||||
|
if (secondary) candidates.push(`${primary}-${secondary}-${num}`);
|
||||||
|
if (secondary) candidates.push(`${primary}${secondary}-${num}`);
|
||||||
|
// final fallback
|
||||||
|
candidates.push(`${primary}${String(Date.now()).slice(-4)}-${num}`);
|
||||||
|
|
||||||
|
for (const id of candidates) {
|
||||||
|
// findUnique requires unique field; assuming `id` is the PK/unique
|
||||||
|
const found = await tx.masterSubBidangBisnis.findUnique({
|
||||||
|
where: { id },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
if (!found) return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// theoretically unreachable, but return a final deterministic fallback
|
||||||
|
return `${primary}-${String(Math.floor(Math.random() * 9000) + 1000)}-${num}`;
|
||||||
|
}
|
||||||
|
|||||||
69
src/app/api/mobile/admin/master/donation/[id]/route.ts
Normal file
69
src/app/api/mobile/admin/master/donation/[id]/route.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
let fixData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fixData = await prisma.donasiMaster_Kategori.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Master berhasil diambil",
|
||||||
|
data: fixData,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: "Gagal mengambil data master",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
console.log("id", id);
|
||||||
|
console.log("data", data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updateData = await prisma.donasiMaster_Kategori.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
active: data.active,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Master berhasil diupdate",
|
||||||
|
data: updateData,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: "Gagal mengupdate data master",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
105
src/app/api/mobile/admin/master/donation/route.ts
Normal file
105
src/app/api/mobile/admin/master/donation/route.ts
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET, POST };
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
// const category = searchParams.get("category");
|
||||||
|
let fixData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fixData = await prisma.donasiMaster_Kategori.findMany({
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "asc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// if (category === "category") {
|
||||||
|
// fixData = await prisma.donasiMaster_Kategori.findMany({
|
||||||
|
// orderBy: {
|
||||||
|
// createdAt: "asc",
|
||||||
|
// },
|
||||||
|
// where: {
|
||||||
|
// active: true,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } else if (category === "duration") {
|
||||||
|
// fixData = await prisma.donasiMaster_Durasi.findMany({
|
||||||
|
// orderBy: {
|
||||||
|
// createdAt: "asc",
|
||||||
|
// },
|
||||||
|
// where: {
|
||||||
|
// active: true,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// const category = await prisma.donasiMaster_Kategori.findMany({
|
||||||
|
// orderBy: {
|
||||||
|
// createdAt: "asc",
|
||||||
|
// },
|
||||||
|
// where: {
|
||||||
|
// active: true,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const duration = await prisma.donasiMaster_Durasi.findMany({
|
||||||
|
// orderBy: {
|
||||||
|
// createdAt: "asc",
|
||||||
|
// },
|
||||||
|
// where: {
|
||||||
|
// active: true,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// fixData = {
|
||||||
|
// category: category,
|
||||||
|
// duration: duration,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Master berhasil diambil",
|
||||||
|
data: fixData,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: "Gagal mengambil data master",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function POST(request: Request) {
|
||||||
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
console.log("data", data);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const count = await prisma.donasiMaster_Kategori.count();
|
||||||
|
const createNewId = count + 1;
|
||||||
|
|
||||||
|
const createData = await prisma.donasiMaster_Kategori.create({
|
||||||
|
data: {
|
||||||
|
id: createNewId.toString(),
|
||||||
|
name: data.name,
|
||||||
|
active: data.active,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Master berhasil ditambahkan",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
error: "Gagal menambah data master",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/app/api/mobile/admin/master/type-of-event/[id]/route.ts
Normal file
59
src/app/api/mobile/admin/master/type-of-event/[id]/route.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET, PUT };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.eventMaster_TipeAcara.findUnique({
|
||||||
|
where: {
|
||||||
|
id: Number(id),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Success get type of event",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error get type of event", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error get type of event",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updated = await prisma.eventMaster_TipeAcara.update({
|
||||||
|
where: {
|
||||||
|
id: Number(id),
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
name: data.name,
|
||||||
|
active: data.active,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Success update type of event",
|
||||||
|
data: updated,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error update type of event", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error update type of event",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
70
src/app/api/mobile/admin/master/type-of-event/route.ts
Normal file
70
src/app/api/mobile/admin/master/type-of-event/route.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET, POST };
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
const data = await prisma.eventMaster_TipeAcara.findMany({
|
||||||
|
orderBy: {
|
||||||
|
updatedAt: "desc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Success get type of event",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error get type of event", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error get type of event",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function POST(request: Request) {
|
||||||
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const checkList = await prisma.eventMaster_TipeAcara.count({});
|
||||||
|
|
||||||
|
if (!checkList) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Type of event already exists",
|
||||||
|
},
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const created = await prisma.eventMaster_TipeAcara.create({
|
||||||
|
data: {
|
||||||
|
id: checkList + 1,
|
||||||
|
name: data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Success create type of event",
|
||||||
|
},
|
||||||
|
{ status: 201 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error create type of event", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error create type of event",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
|
import { funSendToWhatsApp } from "@/lib/code-otp-sender";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
@@ -34,9 +35,15 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
|
||||||
|
console.log("Received data:", data);
|
||||||
|
console.log("User ID:", id);
|
||||||
|
console.log("Category:", category);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (data.active) {
|
if (category === "access") {
|
||||||
const updateData = await prisma.user.update({
|
const updateData = await prisma.user.update({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
@@ -44,10 +51,27 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
data: {
|
data: {
|
||||||
active: data.active,
|
active: data.active,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
nomor: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (data.active) {
|
||||||
|
const resSendCode = await funSendToWhatsApp({
|
||||||
|
nomor: updateData.nomor,
|
||||||
|
newMessage:
|
||||||
|
"Halo sahabat HIConnect, \nSelamat akun anda telah aktif ! \n\n*Pesan ini di kirim secara otomatis, tidak perlu di balas.",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const resSendCode = await funSendToWhatsApp({
|
||||||
|
nomor: updateData.nomor,
|
||||||
|
newMessage:
|
||||||
|
"Halo sahabat HIConnect, \nMohon maaf akun anda telah dinonaktifkan ! Hubungi admin untuk informasi lebih lanjut. \n\n*Pesan ini di kirim secara otomatis, tidak perlu di balas.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
console.log("[Update Active Berhasil]", updateData);
|
console.log("[Update Active Berhasil]", updateData);
|
||||||
} else if (data.role) {
|
} else if (category === "role") {
|
||||||
const fixName = _.startCase(data.role.replace(/_/g, " "));
|
const fixName = _.startCase(data.role.replace(/_/g, " "));
|
||||||
|
|
||||||
const checkRole = await prisma.masterUserRole.findFirst({
|
const checkRole = await prisma.masterUserRole.findFirst({
|
||||||
@@ -68,6 +92,12 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
console.log("[Update Role Berhasil]", updateData);
|
console.log("[Update Role Berhasil]", updateData);
|
||||||
|
} else {
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 400,
|
||||||
|
success: false,
|
||||||
|
message: "Invalid category",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import {
|
||||||
|
sendNotificationMobileToManyUser,
|
||||||
|
sendNotificationMobileToOneUser,
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { GET , PUT};
|
export { GET, PUT };
|
||||||
|
|
||||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
@@ -41,12 +50,16 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
async function PUT(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
|
const { catatan, senderId } = data;
|
||||||
|
|
||||||
|
console.log("catatan", catatan);
|
||||||
|
console.log("senderId", senderId);
|
||||||
|
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const status = searchParams.get("status");
|
const status = searchParams.get("status");
|
||||||
const fixStatus = _.startCase(status as string);
|
const fixStatus = _.startCase(status as string);
|
||||||
let fixData;
|
let fixData;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const checkStatus = await prisma.voting_Status.findFirst({
|
const checkStatus = await prisma.voting_Status.findFirst({
|
||||||
where: {
|
where: {
|
||||||
@@ -71,9 +84,23 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
voting_StatusId: checkStatus.id,
|
voting_StatusId: checkStatus.id,
|
||||||
catatan: data,
|
catatan: catatan,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateStatus.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Ditolak",
|
||||||
|
body: "Mohon perbaiki data sesuai catatan penolakan !",
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "VOTING",
|
||||||
|
deepLink: routeUserMobile.votingByStatus({ status: "reject" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
fixData = updateStatus;
|
fixData = updateStatus;
|
||||||
} else if (fixStatus === "Publish") {
|
} else if (fixStatus === "Publish") {
|
||||||
const updateStatus = await prisma.voting.update({
|
const updateStatus = await prisma.voting.update({
|
||||||
@@ -84,6 +111,39 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
voting_StatusId: checkStatus.id,
|
voting_StatusId: checkStatus.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: updateStatus.authorId as any,
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Review Selesai",
|
||||||
|
body: "Voting kamu telah dipublikasikan !" as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "VOTING",
|
||||||
|
deepLink: routeUserMobile.votingByStatus({ status: "publish" }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: "1",
|
||||||
|
NOT: { id: updateStatus.authorId as any },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: senderId,
|
||||||
|
payload: {
|
||||||
|
title: "Cek Voting Baru Terpublikasi" as NotificationMobileTitleType,
|
||||||
|
body: `${updateStatus.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "VOTING",
|
||||||
|
deepLink: routeUserMobile.votingDetailPublised({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
fixData = updateStatus;
|
fixData = updateStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
|
||||||
export { GET };
|
export { GET };
|
||||||
|
|
||||||
|
|||||||
51
src/app/api/mobile/auth/device-tokens/[id]/route.ts
Normal file
51
src/app/api/mobile/auth/device-tokens/[id]/route.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
|
||||||
|
export { DELETE };
|
||||||
|
|
||||||
|
async function DELETE(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const deviceId = searchParams.get("deviceId");
|
||||||
|
|
||||||
|
console.log("ID", id);
|
||||||
|
console.log("DEVICE ID", deviceId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const findFirst = await prisma.tokenUserDevice.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: id,
|
||||||
|
deviceId: deviceId as any,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!findFirst) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "User tidak ditemukan !",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleted = await prisma.tokenUserDevice.delete({
|
||||||
|
where: {
|
||||||
|
id: findFirst.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("DEL", deleted);
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil menghapus device token user",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("ERROR", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: (error as Error).message, message: "Terjadi error pada API" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/app/api/mobile/auth/device-tokens/route.ts
Normal file
86
src/app/api/mobile/auth/device-tokens/route.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
|
||||||
|
export { POST, GET };
|
||||||
|
|
||||||
|
async function POST(request: NextRequest) {
|
||||||
|
const { data } = await request.json();
|
||||||
|
try {
|
||||||
|
|
||||||
|
const { userId, platform, deviceId, model, appVersion, fcmToken } = data;
|
||||||
|
|
||||||
|
if (!fcmToken) {
|
||||||
|
return NextResponse.json({ error: "Missing Token" }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
|
const existing = await prisma.tokenUserDevice.findFirst({
|
||||||
|
where: {
|
||||||
|
token: fcmToken,
|
||||||
|
userId: userId,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
console.log("✅ EX", existing);
|
||||||
|
|
||||||
|
let deviceToken;
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
deviceToken = await prisma.tokenUserDevice.update({
|
||||||
|
where: {
|
||||||
|
id: existing?.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
platform,
|
||||||
|
deviceId,
|
||||||
|
model,
|
||||||
|
appVersion,
|
||||||
|
isActive: true,
|
||||||
|
updatedAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Buat baru jika belum ada
|
||||||
|
deviceToken = await prisma.tokenUserDevice.create({
|
||||||
|
data: {
|
||||||
|
token: fcmToken,
|
||||||
|
userId: userId,
|
||||||
|
platform,
|
||||||
|
deviceId,
|
||||||
|
model,
|
||||||
|
appVersion,
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, data: deviceToken });
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: (error as Error).message },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GET(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const data = await prisma.tokenUserDevice.findMany({
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({ success: true, data });
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: (error as Error).message },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/app/api/mobile/auth/login/route.ts
Normal file
82
src/app/api/mobile/auth/login/route.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Method Not Allowed" },
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const codeOtp = randomOTP();
|
||||||
|
const body = await req.json();
|
||||||
|
const { nomor } = body;
|
||||||
|
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
nomor: nomor,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(["cek user", user]);
|
||||||
|
console.log(["cek nomor", nomor]);
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "User tidak ditemukan",
|
||||||
|
status: 404,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
|
data: {
|
||||||
|
nomor: nomor,
|
||||||
|
otp: codeOtp,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createOtpId)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
// const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPAADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n\n> Kode OTP anda: ${codeOtp}.`;
|
||||||
|
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||||
|
// // const encodedMsg = encodeURIComponent(msg);
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
`https://wa.wibudev.com/code?nom=${nomor}&text=${msg}`,
|
||||||
|
{ cache: "no-cache" }
|
||||||
|
);
|
||||||
|
|
||||||
|
const sendWa = await res.json();
|
||||||
|
|
||||||
|
if (sendWa.status !== "success")
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Kode verifikasi terkirim",
|
||||||
|
kodeId: createOtpId.id,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Terjadi masalah saat login",
|
||||||
|
reason: error as Error,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
108
src/app/api/mobile/auth/register/route.ts
Normal file
108
src/app/api/mobile/auth/register/route.ts
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||||
|
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Method Not Allowed" },
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data } = await req.json();
|
||||||
|
console.log("data >>", data);
|
||||||
|
const codeOtp = randomOTP();
|
||||||
|
try {
|
||||||
|
const cekUsername = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
username: data.username,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cekUsername)
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Username sudah digunakan",
|
||||||
|
});
|
||||||
|
|
||||||
|
// ✅ Validasi wajib setuju Terms
|
||||||
|
if (data.termsOfServiceAccepted !== true) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "You must agree to the Terms of Service",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const createUser = await prisma.user.create({
|
||||||
|
data: {
|
||||||
|
username: data.username,
|
||||||
|
nomor: data.nomor,
|
||||||
|
active: false,
|
||||||
|
termsOfServiceAccepted: data.termsOfServiceAccepted,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createUser)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal Registrasi" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
|
||||||
|
// const token = await sessionCreate({
|
||||||
|
// sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||||
|
// encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
|
// user: createUser as any,
|
||||||
|
// });
|
||||||
|
|
||||||
|
const createOtpId = await prisma.kodeOtp.create({
|
||||||
|
data: {
|
||||||
|
nomor: data.nomor,
|
||||||
|
otp: codeOtp,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createOtpId)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal mengirim kode OTP" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
// const msg = `HIPMI - Kode ini bersifat RAHASIA dan JANGAN DI BAGIKAN KEPAADA SIAPAPUN, termasuk anggota ataupun pengurus HIPMI lainnya.\n\n\n> Kode OTP anda: ${codeOtp}.`;
|
||||||
|
const msg = `HIPMI%20-%20Kode%20ini%20bersifat%20RAHASIA%20dan%20JANGAN%20DI%20BAGIKAN%20KEPADA%20SIAPAPUN%2C%20termasuk%20anggota%20ataupun%20pengurus%20HIPMI%20lainnya.%20Kode%20OTP%20anda%3A%20${codeOtp}.`;
|
||||||
|
// // const encodedMsg = encodeURIComponent(msg);
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
`https://wa.wibudev.com/code?nom=${data.nomor}&text=${msg}`,
|
||||||
|
{ cache: "no-cache" }
|
||||||
|
);
|
||||||
|
|
||||||
|
const sendWa = await res.json();
|
||||||
|
|
||||||
|
if (sendWa.status !== "success")
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Nomor Whatsapp Tidak Aktif" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Registrasi Berhasil",
|
||||||
|
// token: token,
|
||||||
|
kodeId: createOtpId.id,
|
||||||
|
},
|
||||||
|
{ status: 201 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Maaf, Terjadi Keselahan",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
src/app/api/mobile/auth/validasi/route.ts
Normal file
82
src/app/api/mobile/auth/validasi/route.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { sessionCreate } from "@/app/(auth)/_lib/session_create";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import backendLogger from "@/util/backendLogger";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
if (req.method !== "POST") {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Method Not Allowed" },
|
||||||
|
{ status: 405 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { nomor } = await req.json();
|
||||||
|
|
||||||
|
const dataUser = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
nomor: nomor,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nomor: true,
|
||||||
|
username: true,
|
||||||
|
active: true,
|
||||||
|
masterUserRoleId: true,
|
||||||
|
termsOfServiceAccepted: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dataUser == null)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Nomor Belum Terdaftar" },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const token = await sessionCreate({
|
||||||
|
sessionKey: process.env.NEXT_PUBLIC_BASE_SESSION_KEY!,
|
||||||
|
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
|
||||||
|
user: dataUser as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: false, message: "Gagal membuat session" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Buat response dengan token dalam cookie
|
||||||
|
const response = NextResponse.json(
|
||||||
|
{
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil Login",
|
||||||
|
roleId: dataUser.masterUserRoleId,
|
||||||
|
active: dataUser.active,
|
||||||
|
termsOfServiceAccepted: dataUser.termsOfServiceAccepted,
|
||||||
|
token: token,
|
||||||
|
},
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set cookie dengan token yang sudah dipastikan tidak null
|
||||||
|
response.cookies.set(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!, token, {
|
||||||
|
path: "/",
|
||||||
|
sameSite: "lax",
|
||||||
|
secure: process.env.NODE_ENV === "production",
|
||||||
|
maxAge: 30 * 24 * 60 * 60, // 30 hari dalam detik (1 bulan)
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
backendLogger.log("API Error or Server Error", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Maaf, Terjadi Keselahan",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/app/api/mobile/block-user/[id]/route.tsx
Normal file
78
src/app/api/mobile/block-user/[id]/route.tsx
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET, DELETE };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
console.log("[ID] >>", id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.blockedUser.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
blocked: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
menuFeature: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "success",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR GET BLOCK USER] >>", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "error",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function DELETE(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
console.log("[ID] >>", id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.blockedUser.delete({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "success",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR DELETE BLOCK USER] >>", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "error",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
109
src/app/api/mobile/block-user/route.ts
Normal file
109
src/app/api/mobile/block-user/route.ts
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { POST, GET };
|
||||||
|
|
||||||
|
async function POST(request: Request) {
|
||||||
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
console.log("data >>", data);
|
||||||
|
console.log("menuFeature masuk>>", data.menuFeature);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const nameApp = _.lowerCase(data.menuFeature);
|
||||||
|
const menuFeature = await prisma.masterKategoriApp.findFirst({
|
||||||
|
where: { value: nameApp },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(" fix menuFeature >>", menuFeature);
|
||||||
|
|
||||||
|
const blockUser = await prisma.blockedUser.create({
|
||||||
|
data: {
|
||||||
|
blockerId: data.blockerId,
|
||||||
|
blockedId: data.blockedId,
|
||||||
|
menuFeatureId: menuFeature?.id as any,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "success",
|
||||||
|
// data: blockUser,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR BLOCK USER] >>", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "error",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const id = searchParams.get("id");
|
||||||
|
const page = Number(searchParams.get("page"));
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = page * takeData - takeData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.blockedUser.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
where: {
|
||||||
|
blockerId: id as any,
|
||||||
|
menuFeature: {
|
||||||
|
id: {
|
||||||
|
contains: search || "",
|
||||||
|
mode: "insensitive",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
blocked: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
menuFeature: {
|
||||||
|
select: {
|
||||||
|
name: true,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "success",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR GET BLOCK USER] >>", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "error",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -113,6 +113,7 @@ async function GET(request: Request) {
|
|||||||
Author: {
|
Author: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
username: true,
|
||||||
Profile: true,
|
Profile: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -141,6 +142,7 @@ async function GET(request: Request) {
|
|||||||
Author: {
|
Author: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
|
username: true,
|
||||||
Profile: true,
|
Profile: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
37
src/app/api/mobile/donation/[id]/disbursement/route.ts
Normal file
37
src/app/api/mobile/donation/[id]/disbursement/route.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const page = Number(searchParams.get("page"));
|
||||||
|
const takeData = 5;
|
||||||
|
const skipData = page * takeData - takeData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.donasi_PencairanDana.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "asc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Success get disbursement data",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Error get disbursement data",
|
||||||
|
reason: error as Error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/app/api/mobile/donation/[id]/donatur/route.ts
Normal file
74
src/app/api/mobile/donation/[id]/donatur/route.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
let fixData;
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const page = Number(searchParams.get("page"));
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = page * takeData - takeData;
|
||||||
|
|
||||||
|
fixData = await prisma.donasi_Invoice.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
donasiId: id,
|
||||||
|
DonasiMaster_StatusInvoice: {
|
||||||
|
name: "Berhasil",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nominal: true,
|
||||||
|
createdAt: true,
|
||||||
|
// updatedAt: true,
|
||||||
|
// DonasiMaster_StatusInvoice: true,
|
||||||
|
// donasiMaster_StatusInvoiceId: true,
|
||||||
|
// Donasi: {
|
||||||
|
// select: {
|
||||||
|
// id: true,
|
||||||
|
// title: true,
|
||||||
|
// target: true,
|
||||||
|
// progres: true,
|
||||||
|
// authorId: true,
|
||||||
|
// imagesId: true,
|
||||||
|
// publishTime: true,
|
||||||
|
// donasiMaster_KategoriId: true,
|
||||||
|
// donasiMaster_DurasiId: true,
|
||||||
|
// donasiMaster_StatusDonasiId: true,
|
||||||
|
// imageDonasi: true,
|
||||||
|
// DonasiMaster_Ketegori: true,
|
||||||
|
// DonasiMaster_Durasi: true,
|
||||||
|
// DonasiMaster_Status: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Data berhasil diambil",
|
||||||
|
data: fixData,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Terjadi kesalahan saat mengambil data",
|
||||||
|
reason: error as Error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { POST, GET, PUT };
|
export { POST, GET, PUT };
|
||||||
|
|
||||||
@@ -13,7 +19,7 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
data: {
|
data: {
|
||||||
donasiId: id,
|
donasiId: id,
|
||||||
nominal: data.nominal,
|
nominal: data.nominal,
|
||||||
donasiMaster_BankId: data.bankId,
|
masterBankId: data.bankId,
|
||||||
authorId: data.authorId,
|
authorId: data.authorId,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
@@ -33,6 +39,14 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!create) {
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "Gagal membuat invoice",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 201,
|
status: 201,
|
||||||
success: true,
|
success: true,
|
||||||
@@ -65,6 +79,7 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
createdAt: true,
|
createdAt: true,
|
||||||
donasiMaster_BankId: true,
|
donasiMaster_BankId: true,
|
||||||
donasiMaster_StatusInvoiceId: true,
|
donasiMaster_StatusInvoiceId: true,
|
||||||
|
MasterBank: true,
|
||||||
Donasi: {
|
Donasi: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -137,13 +152,14 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
message: "Status tidak ditemukan",
|
message: "Status tidak ditemukan",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const update = await prisma.donasi_Invoice.update({
|
|
||||||
|
const updated = await prisma.donasi_Invoice.update({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
donasiMaster_StatusInvoiceId: checkStatus.id,
|
donasiMaster_StatusInvoiceId: checkStatus.id,
|
||||||
imageId: data.fileId,
|
imageId: data || null,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -162,6 +178,41 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!updated) {
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "Gagal memperbarui data",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const findUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: "2",
|
||||||
|
active: true,
|
||||||
|
NOT: { id: updated?.Donasi?.authorId as string },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: findUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Ada Donasi Baru !" as NotificationMobileTitleType,
|
||||||
|
body: `Cek data investor pada ${updated?.Donasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeAdminMobile.donationDetailPublish({
|
||||||
|
id: updated?.Donasi?.id as string,
|
||||||
|
status: "publish",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[UPDATE INVOICE]", updated);
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
@@ -1,25 +1,39 @@
|
|||||||
import { NextRequest, NextResponse } from "next/server";
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
import { funFindDonaturList } from "@/lib/mobile/donation/find-donatur-list";
|
||||||
|
|
||||||
export { POST, GET, PUT, DELETE };
|
export { POST, GET, PUT, DELETE };
|
||||||
|
|
||||||
async function POST(
|
async function POST(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: { id: string } },
|
||||||
) {
|
) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
|
const { title, deskripsi, imageId } = data;
|
||||||
|
|
||||||
|
const senderId = await prisma.donasi.findUnique({
|
||||||
|
where: { id: id },
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (data && data?.imageId) {
|
if (data && data?.imageId) {
|
||||||
const createWithFile = await prisma.donasi_Kabar.create({
|
const createWithFile = await prisma.donasi_Kabar.create({
|
||||||
data: {
|
data: {
|
||||||
title: data.title,
|
title: title,
|
||||||
deskripsi: data.deskripsi,
|
deskripsi: deskripsi,
|
||||||
donasiId: id,
|
donasiId: id,
|
||||||
imageId: data.imageId,
|
imageId: imageId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -28,8 +42,8 @@ async function POST(
|
|||||||
} else {
|
} else {
|
||||||
const create = await prisma.donasi_Kabar.create({
|
const create = await prisma.donasi_Kabar.create({
|
||||||
data: {
|
data: {
|
||||||
title: data.title,
|
title: title,
|
||||||
deskripsi: data.deskripsi,
|
deskripsi: deskripsi,
|
||||||
donasiId: id,
|
donasiId: id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -38,6 +52,25 @@ async function POST(
|
|||||||
return NextResponse.json({ status: 400, message: "Gagal disimpan" });
|
return NextResponse.json({ status: 400, message: "Gagal disimpan" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const recipientIds = await funFindDonaturList(id);
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
if (recipientIds.length > 0) {
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds,
|
||||||
|
senderId: senderId?.authorId!,
|
||||||
|
payload: {
|
||||||
|
title: "Berita terbaru" as NotificationMobileTitleType,
|
||||||
|
body: `Ada berita terupdate pada ${title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
deepLink: routeUserMobile.donationDetailPublish({
|
||||||
|
id: id,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
success: true,
|
success: true,
|
||||||
@@ -56,7 +89,7 @@ async function POST(
|
|||||||
|
|
||||||
async function GET(
|
async function GET(
|
||||||
request: NextRequest,
|
request: NextRequest,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: { id: string } },
|
||||||
) {
|
) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
@@ -178,7 +211,7 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
async function DELETE(
|
async function DELETE(
|
||||||
request: Request,
|
request: Request,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: { id: string } },
|
||||||
) {
|
) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
try {
|
try {
|
||||||
@@ -198,7 +231,7 @@ async function DELETE(
|
|||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!deleteImage) {
|
if (!deleteImage) {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { NotificationMobileBodyType } from "../../../../../types/type-mobile-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { POST };
|
export { POST, GET };
|
||||||
|
|
||||||
async function POST(request: Request) {
|
async function POST(request: Request) {
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
@@ -47,6 +50,28 @@ async function POST(request: Request) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("[DATA DONASI]", dataDonasi);
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: { masterUserRoleId: "2", NOT: { id: data.authorId } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Baru",
|
||||||
|
body: data.title as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeAdminMobile.donationByStatus({ status: "review" }),
|
||||||
|
kategoriApp: "DONASI",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!dataDonasi)
|
if (!dataDonasi)
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 400,
|
status: 400,
|
||||||
@@ -68,6 +93,8 @@ async function POST(request: Request) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("[DATA CERITA]", dataCerita);
|
||||||
|
|
||||||
if (!dataCerita)
|
if (!dataCerita)
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 400,
|
status: 400,
|
||||||
@@ -94,7 +121,7 @@ async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GET ALL DATA DONASI
|
// GET ALL DATA DONASI
|
||||||
export async function GET(request: Request) {
|
async function GET(request: Request) {
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const category = searchParams.get("category");
|
const category = searchParams.get("category");
|
||||||
const authorId = searchParams.get("authorId");
|
const authorId = searchParams.get("authorId");
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const userId = searchParams.get("userId");
|
const userId = searchParams.get("userId");
|
||||||
|
|
||||||
|
console.log("id", id);
|
||||||
|
console.log("userId", userId);
|
||||||
|
|
||||||
let fixData
|
let fixData
|
||||||
|
|
||||||
const checkParticipant = await prisma.event_Peserta.findFirst({
|
const checkParticipant = await prisma.event_Peserta.findFirst({
|
||||||
|
|||||||
168
src/app/api/mobile/event/[id]/confirmation/route.ts
Normal file
168
src/app/api/mobile/event/[id]/confirmation/route.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { id } = params;
|
||||||
|
let fixData;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const userId = searchParams.get("userId");
|
||||||
|
|
||||||
|
const checkDataEvent = await prisma.event.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
title: true,
|
||||||
|
tanggal: true,
|
||||||
|
tanggalSelesai: true,
|
||||||
|
lokasi: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!checkDataEvent) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: "Event Not Found", response: null },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let peserta;
|
||||||
|
const checkPeserta = await prisma.event_Peserta.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: userId,
|
||||||
|
eventId: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkPeserta) {
|
||||||
|
peserta = true;
|
||||||
|
} else {
|
||||||
|
peserta = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let kehadiran;
|
||||||
|
const checkKehadiran = await prisma.event_Peserta.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: userId,
|
||||||
|
eventId: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
isPresent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (checkKehadiran?.isPresent) {
|
||||||
|
kehadiran = true;
|
||||||
|
} else {
|
||||||
|
kehadiran = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fixData = {
|
||||||
|
dataEvent: checkDataEvent,
|
||||||
|
peserta: peserta,
|
||||||
|
kehadiran: kehadiran,
|
||||||
|
};
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: true, message: "Event Found", data: fixData },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error get confirmation event", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error get confirmation event",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
const { data } = await request.json();
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
try {
|
||||||
|
console.log("category", category);
|
||||||
|
console.log("id", id);
|
||||||
|
console.log("data", data);
|
||||||
|
|
||||||
|
if (category === "join_and_confirm") {
|
||||||
|
const join = await prisma.event_Peserta.create({
|
||||||
|
data: {
|
||||||
|
eventId: id,
|
||||||
|
userId: data.userId,
|
||||||
|
isPresent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = join;
|
||||||
|
} else if (category === "confirmation") {
|
||||||
|
const checkPeserta = await prisma.event_Peserta.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: data.userId,
|
||||||
|
eventId: id,
|
||||||
|
isPresent: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!checkPeserta) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ message: "Peserta Not Found", response: null },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirm = await prisma.event_Peserta.update({
|
||||||
|
where: {
|
||||||
|
id: checkPeserta.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
isPresent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = confirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: true, message: `Success ${category}`, data: fixData },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error upsert confirmation event", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "Error upsert confirmation event",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
|
import { sendNotificationMobileToOneUser } from "@/lib/mobile/notification/send-notification";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { GET, POST };
|
export { GET, POST };
|
||||||
|
|
||||||
@@ -13,18 +19,28 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
eventId: id,
|
eventId: id,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
},
|
},
|
||||||
|
|
||||||
// select: {
|
|
||||||
// Event: {
|
|
||||||
// select: {
|
|
||||||
// id: true,
|
|
||||||
// title: true,
|
|
||||||
// authorId: true,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const findEvent = await prisma.event.findUnique({
|
||||||
|
where: { id: id },
|
||||||
|
select: { authorId: true, title: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
if (userId !== findEvent?.authorId) {
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: findEvent?.authorId as string,
|
||||||
|
senderId: userId,
|
||||||
|
payload: {
|
||||||
|
title: "Peserta Baru Join" as NotificationMobileTitleType,
|
||||||
|
body: `Ada peserta baru dalam event: ${findEvent?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeUserMobile.eventDetailPublised({ id: id }),
|
||||||
|
kategoriApp: "EVENT",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { NotificationMobileBodyType } from "../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { GET, POST };
|
export { GET, POST };
|
||||||
|
|
||||||
@@ -30,6 +33,24 @@ async function POST(request: Request) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: { masterUserRoleId: "2", NOT: { id: data.authorId } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Baru",
|
||||||
|
body: create.title as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeAdminMobile.eventByStatus({ status: "review" }),
|
||||||
|
kategoriApp: "EVENT",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { sendNotificationMobileToOneUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { POST, GET, DELETE };
|
export { POST, GET, DELETE };
|
||||||
|
|
||||||
async function POST(request: Request, { params }: { params: { id: string } }) {
|
async function POST(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
|
const { comment, authorId } = data;
|
||||||
|
|
||||||
console.log("[ID COMMENT]", id);
|
console.log("[ID COMMENT]", id);
|
||||||
console.log("[DATA COMMENT]", data);
|
console.log("[DATA COMMENT]", data);
|
||||||
@@ -14,8 +21,8 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
const createComment = await prisma.forum_Komentar.create({
|
const createComment = await prisma.forum_Komentar.create({
|
||||||
data: {
|
data: {
|
||||||
forum_PostingId: id,
|
forum_PostingId: id,
|
||||||
komentar: data.comment,
|
komentar: comment,
|
||||||
authorId: data.authorId,
|
authorId: authorId,
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -38,6 +45,24 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const findForum = await prisma.forum_Posting.findUnique({
|
||||||
|
where: { id: id },
|
||||||
|
select: { authorId: true, diskusi: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToOneUser({
|
||||||
|
recipientId: findForum?.authorId as string,
|
||||||
|
senderId: authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Komentar Baru" as NotificationMobileTitleType,
|
||||||
|
body: `Ayo cek komentar pada postingan: ${findForum?.diskusi}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeUserMobile.forumDetail({ id: id }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!createComment) {
|
if (!createComment) {
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 400,
|
status: 400,
|
||||||
@@ -52,7 +77,6 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
message: "Berhasil update data",
|
message: "Berhasil update data",
|
||||||
data: createComment,
|
data: createComment,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR COMMENT]", error);
|
console.log("[ERROR COMMENT]", error);
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
@@ -66,9 +90,15 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
async function GET(request: Request, { params }: { params: { id: string } }) {
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const page = Number(searchParams.get("page"));
|
||||||
|
const takeData = 5
|
||||||
|
const skipData = page * takeData - takeData;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await prisma.forum_Komentar.findMany({
|
const data = await prisma.forum_Komentar.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: "desc",
|
createdAt: "desc",
|
||||||
},
|
},
|
||||||
@@ -114,7 +144,10 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function DELETE(request: Request, { params }: { params: { id: string } }) {
|
async function DELETE(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -146,4 +179,4 @@ async function DELETE(request: Request, { params }: { params: { id: string } })
|
|||||||
reason: (error as Error).message || error,
|
reason: (error as Error).message || error,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.forum_Komentar.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
komentar: true,
|
||||||
|
isActive: true,
|
||||||
|
createdAt: true,
|
||||||
|
Forum_ReportKomentar: {
|
||||||
|
select: {
|
||||||
|
deskripsi: true,
|
||||||
|
ForumMaster_KategoriReport: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mendapatkan data posting",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: Request,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.forum_Posting.findUnique({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
diskusi: true,
|
||||||
|
isActive: true,
|
||||||
|
createdAt: true,
|
||||||
|
authorId: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Forum_ReportPosting: {
|
||||||
|
select: {
|
||||||
|
deskripsi: true,
|
||||||
|
ForumMaster_KategoriReport: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "Gagal mendapatkan data posting",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { POST };
|
export { POST };
|
||||||
|
|
||||||
@@ -7,26 +13,70 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
let fixData;
|
let fixData;
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
console.log("[DATA]", data);
|
const { authorId: reportedUserId, categoryId, description } = data;
|
||||||
console.log("[ID]", id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (data.categoryId) {
|
// Komentar yang di report
|
||||||
fixData = await prisma.forum_ReportKomentar.create({
|
const findComment = await prisma.forum_Komentar.findUnique({
|
||||||
|
where: { id: id },
|
||||||
|
select: { authorId: true, komentar: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// List admin untuk dikirim notifikasi
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: "2",
|
||||||
|
NOT: { id: findComment?.authorId as any },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (categoryId) {
|
||||||
|
const createdReport = await prisma.forum_ReportKomentar.create({
|
||||||
data: {
|
data: {
|
||||||
forum_KomentarId: id,
|
forum_KomentarId: id,
|
||||||
userId: data.authorId,
|
userId: reportedUserId,
|
||||||
forumMaster_KategoriReportId: data.categoryId as any,
|
forumMaster_KategoriReportId: categoryId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: reportedUserId,
|
||||||
|
payload: {
|
||||||
|
title: "Laporan Dari User" as NotificationMobileTitleType,
|
||||||
|
body: `Report terhadap komentar, ${findComment?.komentar}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeAdminMobile.forumPreviewReportComment,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = createdReport;
|
||||||
} else {
|
} else {
|
||||||
fixData = await prisma.forum_ReportKomentar.create({
|
const createdReport = await prisma.forum_ReportKomentar.create({
|
||||||
data: {
|
data: {
|
||||||
forum_KomentarId: id,
|
forum_KomentarId: id,
|
||||||
userId: data.authorId,
|
userId: reportedUserId,
|
||||||
deskripsi: data.description,
|
deskripsi: description,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: reportedUserId,
|
||||||
|
payload: {
|
||||||
|
title: "Laporan Dari User" as NotificationMobileTitleType,
|
||||||
|
body: `Report terhadap komentar, ${findComment?.komentar}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeAdminMobile.forumPreviewReportComment,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = createdReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fixData) {
|
if (!fixData) {
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
import { NextResponse } from "next/server";
|
import {
|
||||||
|
sendNotificationMobileToManyUser
|
||||||
|
} from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
routeAdminMobile
|
||||||
|
} from "@/lib/mobile/route-page-mobile";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { POST };
|
export { POST };
|
||||||
|
|
||||||
@@ -7,26 +17,70 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
let fixData;
|
let fixData;
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
console.log("[DATA]", data);
|
const { authorId: reportedUserId, categoryId, description } = data;
|
||||||
console.log("[ID]", id);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (data.categoryId) {
|
// Postingan yang akan di report
|
||||||
fixData = await prisma.forum_ReportPosting.create({
|
const findPosting = await prisma.forum_Posting.findUnique({
|
||||||
|
where: { id: id },
|
||||||
|
select: { authorId: true, diskusi: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// List admin untuk dikirim notifikasi
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: "2",
|
||||||
|
NOT: { id: findPosting?.authorId as any },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (categoryId) {
|
||||||
|
const createReported = await prisma.forum_ReportPosting.create({
|
||||||
data: {
|
data: {
|
||||||
forum_PostingId: id,
|
forum_PostingId: id,
|
||||||
userId: data.authorId,
|
userId: reportedUserId,
|
||||||
forumMaster_KategoriReportId: data.categoryId,
|
forumMaster_KategoriReportId: categoryId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: reportedUserId,
|
||||||
|
payload: {
|
||||||
|
title: "Laporan Dari User" as NotificationMobileTitleType,
|
||||||
|
body: `Report terhadap postingan, ${findPosting?.diskusi}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeAdminMobile.forumPreviewReportPosting,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = createReported;
|
||||||
} else {
|
} else {
|
||||||
fixData = await prisma.forum_ReportPosting.create({
|
const createReported = await prisma.forum_ReportPosting.create({
|
||||||
data: {
|
data: {
|
||||||
forum_PostingId: id,
|
forum_PostingId: id,
|
||||||
userId: data.authorId,
|
userId: reportedUserId,
|
||||||
deskripsi: data.description,
|
deskripsi: description,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: reportedUserId,
|
||||||
|
payload: {
|
||||||
|
title: "Laporan Dari User" as NotificationMobileTitleType,
|
||||||
|
body: `Report terhadap postingan, ${findPosting?.diskusi}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeAdminMobile.forumPreviewReportPosting,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = createReported;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fixData) {
|
if (!fixData) {
|
||||||
@@ -51,4 +105,4 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
reason: (error as Error).message,
|
reason: (error as Error).message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,54 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { NotificationMobileBodyType, NotificationMobileTitleType } from "../../../../../types/type-mobile-notification";
|
||||||
|
import { routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { POST, GET };
|
export { POST, GET };
|
||||||
|
|
||||||
async function POST(request: Request) {
|
async function POST(request: Request) {
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
console.log("[DATA]", data);
|
console.log("[DATA]", data);
|
||||||
|
const { diskusi, authorId } = data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const create = await prisma.forum_Posting.create({
|
const create = await prisma.forum_Posting.create({
|
||||||
data: {
|
data: {
|
||||||
diskusi: data.diskusi,
|
diskusi: diskusi,
|
||||||
authorId: data.authorId,
|
authorId: authorId,
|
||||||
forumMaster_StatusPostingId: 1,
|
forumMaster_StatusPostingId: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!create) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Gagal memposting",
|
||||||
|
status: 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const allUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
id: { not: authorId },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: allUsers.map((user) => user.id),
|
||||||
|
senderId: authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Ada Diskusi Baru" as NotificationMobileTitleType,
|
||||||
|
body: `${diskusi}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "FORUM",
|
||||||
|
deepLink: routeUserMobile.forumBeranda,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
success: true,
|
success: true,
|
||||||
message: "Berhasil membuat postingan",
|
message: "Berhasil membuat postingan",
|
||||||
@@ -36,11 +68,107 @@ async function GET(request: Request) {
|
|||||||
let fixData;
|
let fixData;
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
const authorId = searchParams.get("authorId");
|
const authorId = searchParams.get("authorId");
|
||||||
|
const userLoginId = searchParams.get("userLoginId");
|
||||||
const search = searchParams.get("search");
|
const search = searchParams.get("search");
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
const page = searchParams.get("page");
|
||||||
|
const takeData = 5;
|
||||||
|
const skipData = (Number(page) - 1) * takeData;
|
||||||
|
|
||||||
|
// console.log("authorId", authorId);
|
||||||
|
// console.log("userLoginId", userLoginId);
|
||||||
|
// console.log("search", search);
|
||||||
|
// console.log("category", category);
|
||||||
|
console.log("page", page);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (authorId) {
|
if (category === "beranda") {
|
||||||
|
const blockUserId = await prisma.blockedUser
|
||||||
|
.findMany({
|
||||||
|
where: {
|
||||||
|
blockerId: userLoginId as string,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
blockedId: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.map((item) => item.blockedId);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("blockUserId", blockUserId);
|
||||||
|
|
||||||
const data = await prisma.forum_Posting.findMany({
|
const data = await prisma.forum_Posting.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
diskusi: {
|
||||||
|
mode: "insensitive",
|
||||||
|
contains: search || "",
|
||||||
|
},
|
||||||
|
authorId: {
|
||||||
|
notIn: blockUserId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
diskusi: true,
|
||||||
|
createdAt: true,
|
||||||
|
isActive: true,
|
||||||
|
authorId: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Forum_Komentar: {
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ForumMaster_StatusPosting: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
forumMaster_StatusPostingId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const newData = data.map((item) => {
|
||||||
|
const count = item.Forum_Komentar?.length ?? 0;
|
||||||
|
return {
|
||||||
|
..._.omit(item, ["Forum_Komentar"]),
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = newData;
|
||||||
|
} else if (category === "forumku") {
|
||||||
|
const count = await prisma.forum_Posting.count({
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
authorId: authorId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await prisma.forum_Posting.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: "desc",
|
createdAt: "desc",
|
||||||
},
|
},
|
||||||
@@ -90,62 +218,18 @@ async function GET(request: Request) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
fixData = newData;
|
const dataFix = {
|
||||||
|
data: newData,
|
||||||
|
count,
|
||||||
|
};
|
||||||
|
|
||||||
|
fixData = dataFix;
|
||||||
} else {
|
} else {
|
||||||
const data = await prisma.forum_Posting.findMany({
|
return NextResponse.json({
|
||||||
orderBy: {
|
success: false,
|
||||||
createdAt: "desc",
|
message: "Gagal mendapatkan data",
|
||||||
},
|
reason: "Kategori tidak ditemukan",
|
||||||
where: {
|
|
||||||
isActive: true,
|
|
||||||
diskusi: {
|
|
||||||
mode: "insensitive",
|
|
||||||
contains: search || "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
diskusi: true,
|
|
||||||
createdAt: true,
|
|
||||||
isActive: true,
|
|
||||||
authorId: true,
|
|
||||||
Author: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
username: true,
|
|
||||||
Profile: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
imageId: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Forum_Komentar: {
|
|
||||||
where: {
|
|
||||||
isActive: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ForumMaster_StatusPosting: {
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
status: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
forumMaster_StatusPostingId: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const newData = data.map((item) => {
|
|
||||||
const count = item.Forum_Komentar?.length ?? 0;
|
|
||||||
return {
|
|
||||||
..._.omit(item, ["Forum_Komentar"]),
|
|
||||||
count,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
fixData = newData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
@@ -153,7 +237,6 @@ async function GET(request: Request) {
|
|||||||
message: "Berhasil mendapatkan data",
|
message: "Berhasil mendapatkan data",
|
||||||
data: fixData,
|
data: fixData,
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("[ERROR]", error);
|
console.log("[ERROR]", error);
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import {
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
import { routeAdminMobile, routeUserMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { POST, GET, DELETE };
|
export { POST, GET, DELETE };
|
||||||
|
|
||||||
@@ -10,7 +16,7 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
console.log("[POST DOCUMENT DATA]", data);
|
console.log("[POST DOCUMENT DATA]", data);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const create = await prisma.dokumenInvestasi.upsert({
|
const createdDocs = await prisma.dokumenInvestasi.upsert({
|
||||||
where: {
|
where: {
|
||||||
id: id,
|
id: id,
|
||||||
},
|
},
|
||||||
@@ -23,9 +29,49 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
title: data.title,
|
title: data.title,
|
||||||
fileId: data.fileId,
|
fileId: data.fileId,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
investasiId: true,
|
||||||
|
investasi: {
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!create)
|
console.log("[CREATED DOCS]", createdDocs);
|
||||||
|
|
||||||
|
const findInvestor = await prisma.investasi_Invoice.findMany({
|
||||||
|
where: {
|
||||||
|
investasiId: id,
|
||||||
|
StatusInvoice: {
|
||||||
|
name: "Berhasil",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("[FIND INVESTOR]", findInvestor);
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: findInvestor.map((e) => e.authorId!),
|
||||||
|
senderId: createdDocs.investasi?.authorId as string,
|
||||||
|
payload: {
|
||||||
|
title: "Cek Dokumen" as NotificationMobileTitleType,
|
||||||
|
body: `Ada dokumen terupdate pada ${createdDocs.investasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeUserMobile.investmentDetailPublish({
|
||||||
|
id: createdDocs.investasiId as string,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!createdDocs)
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 201,
|
status: 201,
|
||||||
success: true,
|
success: true,
|
||||||
@@ -93,7 +139,7 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
async function DELETE(
|
async function DELETE(
|
||||||
request: Request,
|
request: Request,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: { id: string } },
|
||||||
) {
|
) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
|
|
||||||
@@ -111,9 +157,9 @@ async function DELETE(
|
|||||||
headers: {
|
headers: {
|
||||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
48
src/app/api/mobile/investment/[id]/investor/route.ts
Normal file
48
src/app/api/mobile/investment/[id]/investor/route.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request, { params }: { params: { id: string } }) {
|
||||||
|
const { id } = params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.investasi_Invoice.findMany({
|
||||||
|
where: {
|
||||||
|
investasiId: id,
|
||||||
|
statusInvoiceId: "1",
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
nominal: true,
|
||||||
|
Author: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
username: true,
|
||||||
|
Profile: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
imageId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "Berhasil Mendapatkan Data",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "Error Mendapatkan Data",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import {
|
||||||
|
NotificationMobileTitleType,
|
||||||
|
NotificationMobileBodyType,
|
||||||
|
} from "../../../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { POST, GET, PUT };
|
export { POST, GET, PUT };
|
||||||
|
|
||||||
@@ -48,6 +54,8 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
const category = searchParams.get("category");
|
const category = searchParams.get("category");
|
||||||
const authorId = searchParams.get("authorId");
|
const authorId = searchParams.get("authorId");
|
||||||
|
|
||||||
|
console.log("[ID INVOICE]", id);
|
||||||
|
|
||||||
let fixData;
|
let fixData;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -80,6 +88,8 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("[DATA INVOICE]", data ? true : false);
|
||||||
|
|
||||||
const { ...allData } = data;
|
const { ...allData } = data;
|
||||||
const Investor = data?.Investasi?.Investasi_Invoice;
|
const Investor = data?.Investasi?.Investasi_Invoice;
|
||||||
fixData = { ...allData, Investor };
|
fixData = { ...allData, Investor };
|
||||||
@@ -193,8 +203,49 @@ async function PUT(request: Request, { params }: { params: { id: string } }) {
|
|||||||
statusInvoiceId: checkStatus.id,
|
statusInvoiceId: checkStatus.id,
|
||||||
imageId: data.imageId,
|
imageId: data.imageId,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
investasiId: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (fixStatus === "Proses") {
|
||||||
|
// kirim notif ke author investasi
|
||||||
|
const findInvestasi = await prisma.investasi.findUnique({
|
||||||
|
where: {
|
||||||
|
id: update.investasiId as any,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const findUsers = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: "2",
|
||||||
|
active: true,
|
||||||
|
NOT: { id: findInvestasi?.authorId as any },
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: findUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Ada Investor Baru !" as NotificationMobileTitleType,
|
||||||
|
body: `Cek data investor pada ${findInvestasi?.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
deepLink: routeAdminMobile.investmentDetailPublish({
|
||||||
|
id: update.investasiId as string,
|
||||||
|
status: "publish",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
console.log("[UPDATE]", update);
|
console.log("[UPDATE]", update);
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import { prisma } from "@/lib";
|
import { prisma } from "@/lib";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { sendNotificationInvestmentAddNews } from "@/lib/mobile/notification/notification-add-news-investment";
|
||||||
|
|
||||||
export { POST, GET, DELETE };
|
export { POST, GET, DELETE };
|
||||||
|
|
||||||
@@ -21,21 +22,51 @@ async function POST(request: Request, { params }: { params: { id: string } }) {
|
|||||||
deskripsi: data.deskripsi,
|
deskripsi: data.deskripsi,
|
||||||
imageId: data.imageId,
|
imageId: data.imageId,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
investasiId: true,
|
||||||
|
investasi: {
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationInvestmentAddNews({
|
||||||
|
invesmentId: createWithFile.investasiId,
|
||||||
|
senderId: createWithFile.investasi.authorId as string,
|
||||||
|
title: createWithFile.investasi.title,
|
||||||
});
|
});
|
||||||
|
|
||||||
fixData = createWithFile;
|
fixData = createWithFile;
|
||||||
|
} else {
|
||||||
|
const createWitOutFile = await prisma.beritaInvestasi.create({
|
||||||
|
data: {
|
||||||
|
investasiId: id,
|
||||||
|
title: _.startCase(data.title),
|
||||||
|
deskripsi: data.deskripsi,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
investasiId: true,
|
||||||
|
investasi: {
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
authorId: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationInvestmentAddNews({
|
||||||
|
invesmentId: createWitOutFile.investasiId,
|
||||||
|
senderId: createWitOutFile.investasi.authorId as string,
|
||||||
|
title: createWitOutFile.investasi.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = createWitOutFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createWitOutFile = await prisma.beritaInvestasi.create({
|
|
||||||
data: {
|
|
||||||
investasiId: id,
|
|
||||||
title: _.startCase(data.title),
|
|
||||||
deskripsi: data.deskripsi,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
fixData = createWitOutFile;
|
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 201,
|
status: 201,
|
||||||
success: true,
|
success: true,
|
||||||
@@ -111,7 +142,7 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
|
|
||||||
async function DELETE(
|
async function DELETE(
|
||||||
request: Request,
|
request: Request,
|
||||||
{ params }: { params: { id: string } }
|
{ params }: { params: { id: string } },
|
||||||
) {
|
) {
|
||||||
const { id } = params;
|
const { id } = params;
|
||||||
console.log("id", id);
|
console.log("id", id);
|
||||||
|
|||||||
@@ -17,7 +17,11 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
Profile: true,
|
Profile: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Investasi_Invoice: true,
|
Investasi_Invoice: {
|
||||||
|
where: {
|
||||||
|
statusInvoiceId: "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
MasterStatusInvestasi: true,
|
MasterStatusInvestasi: true,
|
||||||
BeritaInvestasi: true,
|
BeritaInvestasi: true,
|
||||||
DokumenInvestasi: true,
|
DokumenInvestasi: true,
|
||||||
|
|||||||
@@ -2,18 +2,24 @@ import _ from "lodash";
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { NotificationMobileBodyType } from "../../../../../types/type-mobile-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
|
|
||||||
export { POST, GET };
|
export { POST, GET };
|
||||||
|
|
||||||
async function POST(request: Request) {
|
async function POST(request: Request) {
|
||||||
const { data } = await request.json();
|
const { data } = await request.json();
|
||||||
console.log(["DATA INVESTASI"], data);
|
console.log(["DATA INVESTASI"], data);
|
||||||
|
|
||||||
|
const fixTitle = _.startCase(data.title)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const create = await prisma.investasi.create({
|
const create = await prisma.investasi.create({
|
||||||
data: {
|
data: {
|
||||||
masterStatusInvestasiId: "2",
|
masterStatusInvestasiId: "2",
|
||||||
authorId: data.authorId,
|
authorId: data.authorId,
|
||||||
title: _.startCase(data.title),
|
title: fixTitle,
|
||||||
targetDana: data.targetDana,
|
targetDana: data.targetDana,
|
||||||
hargaLembar: data.hargaLembar,
|
hargaLembar: data.hargaLembar,
|
||||||
totalLembar: data.totalLembar,
|
totalLembar: data.totalLembar,
|
||||||
@@ -29,6 +35,24 @@ async function POST(request: Request) {
|
|||||||
|
|
||||||
console.log("[CREATE INVESTASI]", create);
|
console.log("[CREATE INVESTASI]", create);
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: { masterUserRoleId: "2", NOT: { id: data.authorId } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
// SEND NOTIFICATION
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Baru",
|
||||||
|
body: fixTitle as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeAdminMobile.investmentByStatus({ status: "review" }),
|
||||||
|
kategoriApp: "INVESTASI",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 201,
|
status: 201,
|
||||||
success: true,
|
success: true,
|
||||||
@@ -46,82 +70,112 @@ async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function GET(request: Request) {
|
async function GET(request: Request) {
|
||||||
let fixData;
|
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
const authorId = searchParams.get("authorId");
|
||||||
|
|
||||||
|
console.log("[CATEGORY]", category);
|
||||||
|
console.log("[AUTHOR ID]", authorId);
|
||||||
|
let fixData;
|
||||||
try {
|
try {
|
||||||
const data = await prisma.investasi.findMany({
|
if (category === "bursa") {
|
||||||
where: {
|
const data = await prisma.investasi.findMany({
|
||||||
masterStatusInvestasiId: "1",
|
where: {
|
||||||
masterProgresInvestasiId: "1",
|
masterStatusInvestasiId: "1",
|
||||||
},
|
masterProgresInvestasiId: "1",
|
||||||
select: {
|
},
|
||||||
id: true,
|
select: {
|
||||||
MasterPencarianInvestor: true,
|
id: true,
|
||||||
countDown: true,
|
MasterPencarianInvestor: true,
|
||||||
progress: true,
|
countDown: true,
|
||||||
},
|
progress: true,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
for (let a of data) {
|
for (let a of data) {
|
||||||
if (
|
if (
|
||||||
(a.MasterPencarianInvestor?.name as any) -
|
(a.MasterPencarianInvestor?.name as any) -
|
||||||
moment(new Date()).diff(new Date(a.countDown as any), "days") <=
|
moment(new Date()).diff(new Date(a.countDown as any), "days") <=
|
||||||
0
|
0
|
||||||
) {
|
) {
|
||||||
await prisma.investasi.update({
|
await prisma.investasi.update({
|
||||||
where: {
|
where: {
|
||||||
id: a.id,
|
id: a.id,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
masterProgresInvestasiId: "3",
|
masterProgresInvestasiId: "3",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.progress === "100") {
|
||||||
|
await prisma.investasi.update({
|
||||||
|
where: {
|
||||||
|
id: a.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
masterProgresInvestasiId: "2",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.progress === "100") {
|
const dataAwal = await prisma.investasi.findMany({
|
||||||
await prisma.investasi.update({
|
orderBy: [
|
||||||
where: {
|
{
|
||||||
id: a.id,
|
masterProgresInvestasiId: "asc",
|
||||||
},
|
},
|
||||||
data: {
|
{
|
||||||
masterProgresInvestasiId: "2",
|
countDown: "desc",
|
||||||
},
|
},
|
||||||
});
|
],
|
||||||
}
|
where: {
|
||||||
}
|
masterStatusInvestasiId: "1",
|
||||||
|
|
||||||
const dataAwal = await prisma.investasi.findMany({
|
|
||||||
orderBy: [
|
|
||||||
{
|
|
||||||
masterProgresInvestasiId: "asc",
|
|
||||||
},
|
},
|
||||||
{
|
select: {
|
||||||
countDown: "desc",
|
id: true,
|
||||||
},
|
imageId: true,
|
||||||
],
|
title: true,
|
||||||
where: {
|
progress: true,
|
||||||
masterStatusInvestasiId: "1",
|
countDown: true,
|
||||||
},
|
MasterPencarianInvestor: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
name: true,
|
||||||
imageId: true,
|
},
|
||||||
title: true,
|
|
||||||
progress: true,
|
|
||||||
countDown: true,
|
|
||||||
MasterPencarianInvestor: {
|
|
||||||
select: {
|
|
||||||
name: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
fixData = dataAwal.map((v: any) => ({
|
fixData = dataAwal.map((v: any) => ({
|
||||||
..._.omit(v, ["MasterPencarianInvestor"]),
|
..._.omit(v, ["MasterPencarianInvestor"]),
|
||||||
pencarianInvestor: v.MasterPencarianInvestor.name,
|
pencarianInvestor: v.MasterPencarianInvestor.name,
|
||||||
}));
|
}));
|
||||||
|
} else if (category === "my-holding") {
|
||||||
|
const data = await prisma.investasi_Invoice.findMany({
|
||||||
|
where: {
|
||||||
|
authorId: authorId,
|
||||||
|
statusInvoiceId: "1",
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
investasiId: true,
|
||||||
|
nominal: true,
|
||||||
|
lembarTerbeli: true,
|
||||||
|
Investasi: {
|
||||||
|
select: {
|
||||||
|
title: true,
|
||||||
|
progress: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fixData = data.map((v: any) => ({
|
||||||
|
..._.omit(v, ["Investasi"]),
|
||||||
|
title: v.Investasi.title,
|
||||||
|
progress: v.Investasi.progress,
|
||||||
|
}));
|
||||||
|
}
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
status: 200,
|
status: 200,
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ async function GET(request: Request, { params }: { params: { id: string } }) {
|
|||||||
include: {
|
include: {
|
||||||
Author: {
|
Author: {
|
||||||
select: {
|
select: {
|
||||||
|
id: true,
|
||||||
username: true,
|
username: true,
|
||||||
nomor: true,
|
nomor: true,
|
||||||
Profile: {
|
Profile: {
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
import { sendNotificationMobileToManyUser } from "@/lib/mobile/notification/send-notification";
|
||||||
|
import { routeAdminMobile } from "@/lib/mobile/route-page-mobile";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { NotificationMobileBodyType } from "../../../../../types/type-mobile-notification";
|
||||||
|
|
||||||
export { POST, GET };
|
export { POST, GET };
|
||||||
|
|
||||||
@@ -17,6 +20,25 @@ async function POST(request: Request) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// kirim notifikasi ke semua admin untuk mengetahui ada job baru yang harus di review
|
||||||
|
|
||||||
|
const adminUsers = await prisma.user.findMany({
|
||||||
|
where: { masterUserRoleId: "2", NOT: { id: data.authorId } },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
await sendNotificationMobileToManyUser({
|
||||||
|
recipientIds: adminUsers.map((user) => user.id),
|
||||||
|
senderId: data.authorId,
|
||||||
|
payload: {
|
||||||
|
title: "Pengajuan Review Baru",
|
||||||
|
body: `${create.title}` as NotificationMobileBodyType,
|
||||||
|
type: "announcement",
|
||||||
|
deepLink: routeAdminMobile.jobByStatus({ status: "review" }),
|
||||||
|
kategoriApp: "JOB",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
@@ -54,10 +76,10 @@ async function GET(request: Request) {
|
|||||||
MasterStatus: {
|
MasterStatus: {
|
||||||
name: "Publish",
|
name: "Publish",
|
||||||
},
|
},
|
||||||
// title: {
|
// title: {
|
||||||
// contains: search || "",
|
// contains: search || "",
|
||||||
// mode: "insensitive",
|
// mode: "insensitive",
|
||||||
// },
|
// },
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: "desc",
|
createdAt: "desc",
|
||||||
@@ -90,46 +112,46 @@ async function GET(request: Request) {
|
|||||||
|
|
||||||
fixData = data;
|
fixData = data;
|
||||||
} else if (category === "beranda") {
|
} else if (category === "beranda") {
|
||||||
const data = await prisma.job.findMany({
|
const data = await prisma.job.findMany({
|
||||||
where: {
|
where: {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
isArsip: false,
|
isArsip: false,
|
||||||
MasterStatus: {
|
MasterStatus: {
|
||||||
name: "Publish",
|
name: "Publish",
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
contains: search || "",
|
contains: search || "",
|
||||||
mode: "insensitive",
|
mode: "insensitive",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
orderBy: {
|
orderBy: {
|
||||||
createdAt: "desc",
|
createdAt: "desc",
|
||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
title: true,
|
title: true,
|
||||||
deskripsi: true,
|
deskripsi: true,
|
||||||
authorId: true,
|
authorId: true,
|
||||||
MasterStatus: {
|
MasterStatus: {
|
||||||
select: {
|
select: {
|
||||||
name: true,
|
name: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Author: {
|
Author: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
username: true,
|
username: true,
|
||||||
Profile: {
|
Profile: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
name: true,
|
name: true,
|
||||||
imageId: true,
|
imageId: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fixData = data;
|
fixData = data;
|
||||||
}
|
}
|
||||||
|
|||||||
28
src/app/api/mobile/master/app-category/route.ts
Normal file
28
src/app/api/mobile/master/app-category/route.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
|
export { GET };
|
||||||
|
|
||||||
|
async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
const data = await prisma.masterKategoriApp.findMany({
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 200,
|
||||||
|
success: true,
|
||||||
|
message: "success",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR GET APP CATEGORY] >>", error);
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 500,
|
||||||
|
success: false,
|
||||||
|
message: "error",
|
||||||
|
reason: (error as Error).message || error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/app/api/mobile/master/transaction-status/route.ts
Normal file
30
src/app/api/mobile/master/transaction-status/route.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
try {
|
||||||
|
const res = await prisma.masterStatusTransaksi.findMany({
|
||||||
|
orderBy: {
|
||||||
|
updatedAt: "asc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return NextResponse.json(
|
||||||
|
{ success: true, message: "Berhasil mendapatkan data", data: res },
|
||||||
|
{ status: 200 }
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.log("[ERROR]", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{
|
||||||
|
success: false,
|
||||||
|
message: "API Error Get Data",
|
||||||
|
reason: (error as Error).message,
|
||||||
|
},
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
246
src/app/api/mobile/notification/[id]/route.ts
Normal file
246
src/app/api/mobile/notification/[id]/route.ts
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import _ from "lodash";
|
||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { NotificationProp } from "../route";
|
||||||
|
import { adminMessaging } from "@/lib/firebase-admin";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
|
||||||
|
let fixData;
|
||||||
|
const fixCategory = _.upperCase(category || "");
|
||||||
|
|
||||||
|
try {
|
||||||
|
const page = Number(searchParams.get("page"));
|
||||||
|
const takeData = 10;
|
||||||
|
const skipData = page ? page * takeData - takeData : 0;
|
||||||
|
|
||||||
|
const data = await prisma.notifikasi.findMany({
|
||||||
|
take: page ? takeData : undefined,
|
||||||
|
skip: page ? skipData : undefined,
|
||||||
|
orderBy: {
|
||||||
|
createdAt: "desc",
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
recipientId: id,
|
||||||
|
kategoriApp: fixCategory,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Jika pagination digunakan, ambil juga total count untuk informasi
|
||||||
|
let totalCount;
|
||||||
|
let totalPages;
|
||||||
|
if (page) {
|
||||||
|
totalCount = await prisma.notifikasi.count({
|
||||||
|
where: {
|
||||||
|
recipientId: id,
|
||||||
|
kategoriApp: fixCategory,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
totalPages = Math.ceil(totalCount / takeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
fixData = data;
|
||||||
|
|
||||||
|
const response = {
|
||||||
|
success: true,
|
||||||
|
data: fixData,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tambahkan metadata pagination jika parameter page disertakan
|
||||||
|
if (page) {
|
||||||
|
Object.assign(response, {
|
||||||
|
meta: {
|
||||||
|
page,
|
||||||
|
take: takeData,
|
||||||
|
skip: skipData,
|
||||||
|
total: totalCount,
|
||||||
|
totalPages,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(response);
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: (error as Error).message },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function PUT(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const category = searchParams.get("category");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (category === "one") {
|
||||||
|
await prisma.notifikasi.update({
|
||||||
|
where: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
isRead: true,
|
||||||
|
readAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (category === "all") {
|
||||||
|
await prisma.notifikasi.updateMany({
|
||||||
|
where: {
|
||||||
|
recipientId: id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
isRead: true,
|
||||||
|
readAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Notifications marked as read",
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error marking notifications as read:", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: (error as Error).message },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// export async function POST(
|
||||||
|
// request: NextRequest,
|
||||||
|
// { params }: { params: { id: string } }
|
||||||
|
// ) {
|
||||||
|
// const { id } = params;
|
||||||
|
|
||||||
|
// const { data } = await request.json();
|
||||||
|
|
||||||
|
// const {
|
||||||
|
// title,
|
||||||
|
// body: notificationBody,
|
||||||
|
// userLoginId,
|
||||||
|
// type,
|
||||||
|
// kategoriApp,
|
||||||
|
// appId,
|
||||||
|
// status,
|
||||||
|
// deepLink,
|
||||||
|
// } = data as NotificationProp;
|
||||||
|
|
||||||
|
// console.log("Notification Send >>", data);
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// // Cari user yang login
|
||||||
|
// const findUserLogin = await prisma.user.findUnique({
|
||||||
|
// where: {
|
||||||
|
// id: userLoginId,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// if (!findUserLogin) {
|
||||||
|
// return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Cari token fcm user yang login
|
||||||
|
// const checkFcmToken = await prisma.tokenUserDevice.findFirst({
|
||||||
|
// where: {
|
||||||
|
// userId: findUserLogin.id,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// if (!checkFcmToken) {
|
||||||
|
// return NextResponse.json(
|
||||||
|
// { error: "FCM Token not found" },
|
||||||
|
// { status: 404 }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const created = await prisma.notifikasi.create({
|
||||||
|
// data: {
|
||||||
|
// title,
|
||||||
|
// type,
|
||||||
|
// createdAt: new Date(),
|
||||||
|
// appId,
|
||||||
|
// kategoriApp,
|
||||||
|
// pesan: notificationBody || "",
|
||||||
|
// userRoleId: findUserLogin.masterUserRoleId,
|
||||||
|
// status,
|
||||||
|
// deepLink,
|
||||||
|
// senderId: findUserLogin.id,
|
||||||
|
// recipientId: id,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// if (created) {
|
||||||
|
// const deviceToken = await prisma.tokenUserDevice.findMany({
|
||||||
|
// where: {
|
||||||
|
// userId: id,
|
||||||
|
// isActive: true,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
// for (let i of deviceToken) {
|
||||||
|
// const message = {
|
||||||
|
// token: i.token,
|
||||||
|
// notification: {
|
||||||
|
// title,
|
||||||
|
// body: notificationBody || "",
|
||||||
|
// },
|
||||||
|
// data: {
|
||||||
|
// sentAt: new Date().toISOString(), // ✅ Simpan metadata di data
|
||||||
|
// id: created.id,
|
||||||
|
// deepLink: deepLink || "",
|
||||||
|
// },
|
||||||
|
// // Konfigurasi Android untuk prioritas tinggi
|
||||||
|
// android: {
|
||||||
|
// priority: "high" as const, // Kirim secepatnya, bahkan di doze mode untuk notifikasi penting
|
||||||
|
// notification: {
|
||||||
|
// channelId: "default", // Sesuaikan dengan channel yang kamu buat di Android
|
||||||
|
// },
|
||||||
|
|
||||||
|
// ttl: 0 as const, // Kirim secepatnya, jangan tunda
|
||||||
|
// },
|
||||||
|
// // Opsional: tambahkan untuk iOS juga
|
||||||
|
// apns: {
|
||||||
|
// payload: {
|
||||||
|
// aps: {
|
||||||
|
// sound: "default" as const,
|
||||||
|
// // 'content-available': 1 as const, // jika butuh silent push
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const response = await adminMessaging.send(message);
|
||||||
|
// console.log("✅ FCM sent successfully", "Response:", response);
|
||||||
|
// } catch (error: any) {
|
||||||
|
// console.error("❌ FCM send failed:", error);
|
||||||
|
// // Lanjutkan ke token berikutnya meski satu gagal
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return NextResponse.json({
|
||||||
|
// success: true,
|
||||||
|
// message: "Notification sent successfully",
|
||||||
|
// });
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error("❌ FCM error:", error);
|
||||||
|
|
||||||
|
// return NextResponse.json(
|
||||||
|
// { error: (error as Error).message },
|
||||||
|
// { status: 500 }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
31
src/app/api/mobile/notification/[id]/unread-count/route.ts
Normal file
31
src/app/api/mobile/notification/[id]/unread-count/route.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: { id: string } }
|
||||||
|
) {
|
||||||
|
const { id } = params;
|
||||||
|
console.log("User ID:", id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await prisma.notifikasi.count({
|
||||||
|
where: {
|
||||||
|
recipientId: id,
|
||||||
|
isRead: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("List Notification >>", data);
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to get unread count",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
210
src/app/api/mobile/notification/route.ts
Normal file
210
src/app/api/mobile/notification/route.ts
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
// app/api/test/notifications/route.ts
|
||||||
|
import { prisma } from "@/lib";
|
||||||
|
import { adminMessaging } from "@/lib/firebase-admin";
|
||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export type NotificationProp = {
|
||||||
|
title: string;
|
||||||
|
body: string;
|
||||||
|
userLoginId: string;
|
||||||
|
appId?: string;
|
||||||
|
status?: string;
|
||||||
|
kategoriApp?: string;
|
||||||
|
type?: string;
|
||||||
|
deepLink?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function POST(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const { data } = await request.json();
|
||||||
|
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
body: notificationBody,
|
||||||
|
userLoginId,
|
||||||
|
type,
|
||||||
|
kategoriApp,
|
||||||
|
appId,
|
||||||
|
status,
|
||||||
|
deepLink,
|
||||||
|
} = data as NotificationProp;
|
||||||
|
|
||||||
|
console.log("Notification Send >>", data);
|
||||||
|
|
||||||
|
// Cari user yang login
|
||||||
|
const findUserLogin = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
id: userLoginId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!findUserLogin) {
|
||||||
|
return NextResponse.json({ error: "User not found" }, { status: 404 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cari token fcm user yang login
|
||||||
|
const checkFcmToken = await prisma.tokenUserDevice.findFirst({
|
||||||
|
where: {
|
||||||
|
userId: findUserLogin.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!checkFcmToken) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "FCM Token not found" },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika user yang masuk maka notifikasik akan dikirim ke semua admin , begitu sebaliknya !
|
||||||
|
const filterByCurrentLoginId =
|
||||||
|
findUserLogin.masterUserRoleId === "1" ? "2" : "1";
|
||||||
|
|
||||||
|
// Cari user yang akan menerima notifikasi
|
||||||
|
const findAllUserBySendTo = await prisma.user.findMany({
|
||||||
|
where: {
|
||||||
|
masterUserRoleId: filterByCurrentLoginId,
|
||||||
|
NOT: {
|
||||||
|
id: findUserLogin.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Find All User By Send To >>", findAllUserBySendTo);
|
||||||
|
|
||||||
|
for (let a of findAllUserBySendTo) {
|
||||||
|
const responseCreatedNotifications = await createNotification({
|
||||||
|
title,
|
||||||
|
type: type as string,
|
||||||
|
createdAt: new Date(),
|
||||||
|
pesan: notificationBody || "",
|
||||||
|
appId: appId as string,
|
||||||
|
kategoriApp: kategoriApp as string,
|
||||||
|
userRoleId: findUserLogin.masterUserRoleId,
|
||||||
|
status: status,
|
||||||
|
deepLink: deepLink,
|
||||||
|
senderId: findUserLogin.id,
|
||||||
|
recipientId: a.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (responseCreatedNotifications) {
|
||||||
|
const deviceToken = await prisma.tokenUserDevice.findMany({
|
||||||
|
where: {
|
||||||
|
userId: a.id,
|
||||||
|
isActive: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i of deviceToken) {
|
||||||
|
const message = {
|
||||||
|
token: i.token,
|
||||||
|
notification: {
|
||||||
|
title,
|
||||||
|
body: notificationBody || "",
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
sentAt: new Date().toISOString(), // ✅ Simpan metadata di data
|
||||||
|
id: responseCreatedNotifications.id,
|
||||||
|
deepLink: deepLink || "",
|
||||||
|
// contoh: senderId, type, etc.
|
||||||
|
},
|
||||||
|
// Konfigurasi Android untuk prioritas tinggi
|
||||||
|
android: {
|
||||||
|
priority: "high" as const, // Kirim secepatnya, bahkan di doze mode untuk notifikasi penting
|
||||||
|
notification: {
|
||||||
|
channelId: "default", // Sesuaikan dengan channel yang kamu buat di Android
|
||||||
|
// Opsional: sesuaikan icon & warna
|
||||||
|
// icon: 'ic_notification',
|
||||||
|
// color: '#FFD700',
|
||||||
|
},
|
||||||
|
// FCM akan bangunkan app jika perlu
|
||||||
|
ttl: 0 as const, // Kirim secepatnya, jangan tunda
|
||||||
|
},
|
||||||
|
// Opsional: tambahkan untuk iOS juga
|
||||||
|
apns: {
|
||||||
|
payload: {
|
||||||
|
aps: {
|
||||||
|
sound: "default" as const,
|
||||||
|
// 'content-available': 1 as const, // jika butuh silent push
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await adminMessaging.send(message);
|
||||||
|
console.log(
|
||||||
|
"✅ FCM sent to token:",
|
||||||
|
"Response:",
|
||||||
|
response
|
||||||
|
);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error("❌ FCM send failed for token:", i.token, error);
|
||||||
|
// Lanjutkan ke token berikutnya meski satu gagal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NextResponse.json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to create notification",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: "Notification sent successfully",
|
||||||
|
});
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error("❌ FCM error:", error);
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: error.message || "Failed to send FCM" },
|
||||||
|
{ status: 500 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createNotification({
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
createdAt,
|
||||||
|
appId,
|
||||||
|
kategoriApp,
|
||||||
|
pesan,
|
||||||
|
userRoleId,
|
||||||
|
status,
|
||||||
|
deepLink,
|
||||||
|
senderId,
|
||||||
|
recipientId,
|
||||||
|
}: {
|
||||||
|
title: string;
|
||||||
|
type: string;
|
||||||
|
createdAt: Date;
|
||||||
|
appId: string;
|
||||||
|
kategoriApp: string;
|
||||||
|
userRoleId: string;
|
||||||
|
status?: string;
|
||||||
|
deepLink?: string;
|
||||||
|
pesan: string;
|
||||||
|
|
||||||
|
senderId: string;
|
||||||
|
recipientId: string;
|
||||||
|
}) {
|
||||||
|
const createNotification = await prisma.notifikasi.create({
|
||||||
|
data: {
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
createdAt,
|
||||||
|
appId,
|
||||||
|
kategoriApp,
|
||||||
|
pesan,
|
||||||
|
userRoleId,
|
||||||
|
status,
|
||||||
|
deepLink,
|
||||||
|
senderId,
|
||||||
|
recipientId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return createNotification;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user