akra35567 commited on
Commit
2da3758
·
verified ·
1 Parent(s): dae9a18

Upload 37 files

Browse files
Files changed (37) hide show
  1. .babelrc +6 -0
  2. .dockerignore +60 -0
  3. .env.example +102 -0
  4. .gitignore +92 -0
  5. .htaccess +120 -0
  6. .huggingface.yaml +14 -0
  7. Dockerfile +142 -0
  8. Dockerfile.railway +0 -0
  9. LICENSE +21 -0
  10. README-RAILWAY.md +80 -0
  11. Railway.json +7 -0
  12. admin.php +413 -0
  13. api.php +142 -0
  14. app.py +333 -0
  15. composer-schema.json +25 -0
  16. composer.json +34 -0
  17. contato.php +300 -0
  18. database.sql +0 -0
  19. dev.sh +58 -0
  20. feedback.php +163 -0
  21. health.php +59 -0
  22. index.php +100 -0
  23. keep-alive.js +76 -0
  24. login.php +5 -0
  25. package.json +85 -0
  26. php.ini +67 -0
  27. projetos.php +444 -0
  28. react-demo.php +207 -0
  29. react-fallback.html +277 -0
  30. register.php +0 -0
  31. render.yaml +25 -0
  32. requirements.txt +4 -0
  33. servicos.php +388 -0
  34. sobre.php +290 -0
  35. test-react.php +0 -0
  36. test.html +49 -0
  37. webpack.config.js +184 -0
.babelrc ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env",
4
+ "@babel/preset-react"
5
+ ]
6
+ }
.dockerignore ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Git
2
+ .git
3
+ .gitignore
4
+
5
+ # Documentation
6
+ README.md
7
+ *.md
8
+
9
+ # Development files
10
+ .env
11
+ .env.example
12
+ .vscode/
13
+ .idea/
14
+
15
+ # Logs
16
+ logs/
17
+ *.log
18
+
19
+ # OS generated files
20
+ .DS_Store
21
+ .DS_Store?
22
+ ._*
23
+ .Spotlight-V100
24
+ .Trashes
25
+ ehthumbs.db
26
+ Thumbs.db
27
+
28
+ # Node modules (if any)
29
+ node_modules/
30
+
31
+ # Temporary files
32
+ tmp/
33
+ temp/
34
+ *.tmp
35
+
36
+ # Backup files
37
+ *.bak
38
+ *.backup
39
+ *~
40
+
41
+ # IDE files
42
+ .vscode/
43
+ .idea/
44
+ *.swp
45
+ *.swo
46
+
47
+ # Composer cache
48
+ vendor/
49
+
50
+ # Docker files
51
+ Dockerfile*
52
+ docker-compose*.yml
53
+ .dockerignore
54
+
55
+ # Railway/Render configs
56
+ railway.json
57
+ render.yaml
58
+
59
+ # Keep-alive script (not needed in main container)
60
+ keep-alive.js
.env.example ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SoftEdge Corporation - Environment Configuration
2
+ # Copy this file to .env and configure your settings
3
+
4
+ # ===========================================
5
+ # APPLICATION SETTINGS
6
+ # ===========================================
7
+ APP_NAME=SoftEdge Corporation
8
+ APP_ENV=production
9
+ APP_KEY=your_app_key_here
10
+ APP_URL=https://softedge-corporation.up.railway.app
11
+
12
+ # ===========================================
13
+ # DATABASE CONFIGURATION
14
+ # ===========================================
15
+ DB_CONNECTION=mysql
16
+ DB_HOST=localhost
17
+ DB_PORT=3306
18
+ DB_NAME=softedge_db
19
+ DB_USER=root
20
+ DB_PASS=
21
+
22
+ # ===========================================
23
+ # SECURITY SETTINGS
24
+ # ===========================================
25
+ JWT_SECRET=your_jwt_secret_here
26
+ CSRF_SECRET=your_csrf_secret_here
27
+
28
+ # ===========================================
29
+ # EMAIL CONFIGURATION
30
+ # ===========================================
31
+ MAIL_MAILER=smtp
32
+ MAIL_HOST=smtp.gmail.com
33
+ MAIL_PORT=587
34
+ MAIL_USERNAME=your_email@gmail.com
35
+ MAIL_PASSWORD=your_app_password
36
+ MAIL_ENCRYPTION=tls
37
+ MAIL_FROM_ADDRESS=your_email@gmail.com
38
+ MAIL_FROM_NAME="SoftEdge Corporation"
39
+
40
+ # ===========================================
41
+ # SOCIAL LOGIN (Optional)
42
+ # ===========================================
43
+ GOOGLE_CLIENT_ID=your_google_client_id
44
+ GOOGLE_CLIENT_SECRET=your_google_client_secret
45
+
46
+ GITHUB_CLIENT_ID=your_github_client_id
47
+ GITHUB_CLIENT_SECRET=your_github_client_secret
48
+
49
+ # ===========================================
50
+ # ADMIN CONFIGURATION
51
+ # ===========================================
52
+ ADMIN_EMAIL=admin@softedge.com
53
+ ADMIN_PASSWORD=Admin@123456
54
+ ADMIN_NAME=Isaac Quarenta
55
+
56
+ # ===========================================
57
+ # RATE LIMITING
58
+ # ===========================================
59
+ RATE_LIMIT_LOGIN=5
60
+ RATE_LIMIT_CONTACT=3
61
+ LOCKOUT_DURATION=900
62
+
63
+ # ===========================================
64
+ # ANALYTICS & LOGGING
65
+ # ===========================================
66
+ ANALYTICS_RETENTION_DAYS=365
67
+ LOG_LEVEL=info
68
+
69
+ # ===========================================
70
+ # TIMEZONE & LOCALIZATION
71
+ # ===========================================
72
+ TIMEZONE=Africa/Luanda
73
+ LANGUAGE=pt-BR
74
+
75
+ # ===========================================
76
+ # FILE UPLOAD SETTINGS
77
+ # ===========================================
78
+ MAX_FILE_SIZE=10240
79
+ ALLOWED_FILE_TYPES=jpg,jpeg,png,pdf,doc,docx
80
+
81
+ # ===========================================
82
+ # CACHE & PERFORMANCE
83
+ # ===========================================
84
+ CACHE_DRIVER=file
85
+ SESSION_DRIVER=file
86
+ SESSION_LIFETIME=86400
87
+
88
+ # ===========================================
89
+ # EXTERNAL SERVICES
90
+ # ===========================================
91
+ # Google Analytics
92
+ GA_TRACKING_ID=GA_MEASUREMENT_ID
93
+
94
+ # reCAPTCHA
95
+ RECAPTCHA_SITE_KEY=your_recaptcha_site_key
96
+ RECAPTCHA_SECRET_KEY=your_recaptcha_secret_key
97
+
98
+ # ===========================================
99
+ # DEVELOPMENT SETTINGS
100
+ # ===========================================
101
+ DEBUG=false
102
+ LOG_QUERIES=false
.gitignore ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dependencies
2
+ /vendor/
3
+ /node_modules/
4
+
5
+ # Environment variables
6
+ .env
7
+ .env.local
8
+ .env.production
9
+ .env.staging
10
+
11
+ # Logs
12
+ logs/
13
+ *.log
14
+ npm-debug.log*
15
+ yarn-debug.log*
16
+ yarn-error.log*
17
+
18
+ # Runtime data
19
+ pids
20
+ *.pid
21
+ *.seed
22
+ *.pid.lock
23
+
24
+ # Coverage directory used by tools like istanbul
25
+ coverage/
26
+ .nyc_output
27
+
28
+ # Dependency directories
29
+ jspm_packages/
30
+
31
+ # Optional npm cache directory
32
+ .npm
33
+
34
+ # Optional REPL history
35
+ .node_repl_history
36
+
37
+ # Output of 'npm pack'
38
+ *.tgz
39
+
40
+ # Yarn Integrity file
41
+ .yarn-integrity
42
+
43
+ # dotenv environment variables file
44
+ .env
45
+
46
+ # IDE files
47
+ .vscode/
48
+ .idea/
49
+ *.swp
50
+ *.swo
51
+ *~
52
+
53
+ # OS generated files
54
+ .DS_Store
55
+ .DS_Store?
56
+ ._*
57
+ .Spotlight-V100
58
+ .Trashes
59
+ ehthumbs.db
60
+ Thumbs.db
61
+
62
+ # Temporary files
63
+ tmp/
64
+ temp/
65
+ *.tmp
66
+ *.bak
67
+ *.backup
68
+
69
+ # Composer
70
+ composer.lock
71
+ /vendor/
72
+
73
+ # PHP
74
+ .phpunit.result.cache
75
+
76
+ # Docker
77
+ .dockerignore
78
+
79
+ # Railway/Render
80
+ railway.json
81
+ render.yaml
82
+
83
+ # Keep-alive script
84
+ keep-alive.js
85
+
86
+ # React build output
87
+ dist/
88
+ build/
89
+
90
+ # Documentation
91
+ README.md
92
+ *.md
.htaccess ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SoftEdge Corporation - Professional Apache Configuration
2
+ # Security and Performance Optimizations
3
+
4
+ # Prevent access to sensitive files
5
+ <FilesMatch "\.(htaccess|htpasswd|ini|log|sh|sql|conf)$">
6
+ Order Allow,Deny
7
+ Deny from all
8
+ </FilesMatch>
9
+
10
+ # Prevent access to vendor directory (using FilesMatch instead)
11
+ <FilesMatch "^vendor/">
12
+ Order Allow,Deny
13
+ Deny from all
14
+ </FilesMatch>
15
+
16
+ # Prevent access to logs directory (using FilesMatch instead)
17
+ <FilesMatch "^logs/">
18
+ Order Allow,Deny
19
+ Deny from all
20
+ </FilesMatch>
21
+
22
+ # Prevent access to .env files
23
+ <Files ".env*">
24
+ Order Allow,Deny
25
+ Deny from all
26
+ </Files>
27
+
28
+ # Enable URL rewriting
29
+ RewriteEngine On
30
+
31
+ # Force HTTPS (uncomment when SSL is available)
32
+ # RewriteCond %{HTTPS} off
33
+ # RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
34
+
35
+ # Remove trailing slash
36
+ RewriteCond %{REQUEST_FILENAME} !-d
37
+ RewriteCond %{REQUEST_URI} (.+)/$
38
+ RewriteRule ^ %1 [R=301,L]
39
+
40
+ # Handle PHP files without .php extension (optional)
41
+ # RewriteCond %{REQUEST_FILENAME} !-d
42
+ # RewriteCond %{REQUEST_FILENAME} !-f
43
+ # RewriteCond %{REQUEST_FILENAME}.php -f
44
+ # RewriteRule ^(.*)$ $1.php [L]
45
+
46
+ # Health check endpoint
47
+ RewriteRule ^health$ health.php [L]
48
+
49
+ # Security headers (additional layer)
50
+ <IfModule mod_headers.c>
51
+ # Prevent clickjacking
52
+ Header always set X-Frame-Options DENY
53
+
54
+ # Prevent MIME type sniffing
55
+ Header always set X-Content-Type-Options nosniff
56
+
57
+ # Enable XSS filtering
58
+ Header always set X-XSS-Protection "1; mode=block"
59
+
60
+ # Referrer Policy
61
+ Header always set Referrer-Policy "strict-origin-when-cross-origin"
62
+
63
+ # Content Security Policy
64
+ Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://unpkg.com https://cdn.tailwindcss.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self'"
65
+
66
+ # HSTS (uncomment when SSL is available)
67
+ # Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
68
+ </IfModule>
69
+
70
+ # Compression
71
+ <IfModule mod_deflate.c>
72
+ AddOutputFilterByType DEFLATE text/plain
73
+ AddOutputFilterByType DEFLATE text/html
74
+ AddOutputFilterByType DEFLATE text/xml
75
+ AddOutputFilterByType DEFLATE text/css
76
+ AddOutputFilterByType DEFLATE application/xml
77
+ AddOutputFilterByType DEFLATE application/xhtml+xml
78
+ AddOutputFilterByType DEFLATE application/rss+xml
79
+ AddOutputFilterByType DEFLATE application/javascript
80
+ AddOutputFilterByType DEFLATE application/x-javascript
81
+ AddOutputFilterByType DEFLATE application/json
82
+ </IfModule>
83
+
84
+ # Browser caching
85
+ <IfModule mod_expires.c>
86
+ ExpiresActive On
87
+ ExpiresByType image/jpg "access plus 1 month"
88
+ ExpiresByType image/jpeg "access plus 1 month"
89
+ ExpiresByType image/gif "access plus 1 month"
90
+ ExpiresByType image/png "access plus 1 month"
91
+ ExpiresByType image/svg+xml "access plus 1 month"
92
+ ExpiresByType text/css "access plus 1 month"
93
+ ExpiresByType application/pdf "access plus 1 month"
94
+ ExpiresByType text/javascript "access plus 1 week"
95
+ ExpiresByType application/javascript "access plus 1 week"
96
+ ExpiresByType application/x-shockwave-flash "access plus 1 month"
97
+ ExpiresByType image/x-icon "access plus 1 year"
98
+ ExpiresDefault "access plus 2 days"
99
+ </IfModule>
100
+
101
+ # PHP settings
102
+ <IfModule mod_php.c>
103
+ php_value upload_max_filesize 10M
104
+ php_value post_max_size 10M
105
+ php_value max_execution_time 300
106
+ php_value memory_limit 256M
107
+ php_flag display_errors Off
108
+ php_flag log_errors On
109
+ php_value error_log logs/php_errors.log
110
+ </IfModule>
111
+
112
+ # Error pages (commented out - files don't exist)
113
+ # ErrorDocument 404 /404.php
114
+ # ErrorDocument 403 /403.php
115
+ # ErrorDocument 500 /500.php
116
+
117
+ # Prevent image hotlinking (optional)
118
+ # RewriteCond %{HTTP_REFERER} !^$
119
+ # RewriteCond %{HTTP_REFERER} !^https?://(www\.)?softedge-corporation\.up\.railway\.app [NC]
120
+ # RewriteRule \.(gif|jpg|jpeg|png|svg)$ - [F,L]
.huggingface.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ emoji: 🚀
2
+ colorFrom: blue
3
+ colorTo: cyan
4
+ sdk: static
5
+ pinned: false
6
+ =======
7
+ title: SoftEdge Corporation
8
+ emoji: 🚀
9
+ colorFrom: blue
10
+ colorTo: cyan
11
+ sdk: gradio
12
+ sdk_version: 4.44.1
13
+ app_file: app.py
14
+ pinned: false
Dockerfile ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ================================
2
+ # SoftEdge Corporation — HF Spaces
3
+ # PHP 8.3 + Apache (ESTÁVEL)
4
+ # ================================
5
+ FROM php:8.3-apache
6
+
7
+ # ----------------
8
+ # VARIÁVEIS
9
+ # ----------------
10
+ ENV PORT=7860
11
+ ENV APACHE_RUN_USER=www-data
12
+ ENV APACHE_RUN_GROUP=www-data
13
+ ENV APACHE_LOG_DIR=/var/log/apache2
14
+
15
+ # ----------------
16
+ # DEPENDÊNCIAS DO SISTEMA
17
+ # ----------------
18
+ RUN apt-get update && apt-get install -y --no-install-recommends \
19
+ libpng-dev \
20
+ libjpeg-dev \
21
+ libfreetype6-dev \
22
+ libzip-dev \
23
+ libicu-dev \
24
+ libxml2-dev \
25
+ libcurl4-openssl-dev \
26
+ libonig-dev \
27
+ sqlite3 \
28
+ libsqlite3-dev \
29
+ git \
30
+ curl \
31
+ cron \
32
+ unzip \
33
+ ca-certificates \
34
+ && rm -rf /var/lib/apt/lists/*
35
+
36
+ # ----------------
37
+ # EXTENSÕES PHP (CONTROLADAS)
38
+ # ----------------
39
+ RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
40
+ && docker-php-ext-install \
41
+ mbstring \
42
+ exif \
43
+ bcmath \
44
+ intl \
45
+ zip \
46
+ gd \
47
+ mysqli \
48
+ pdo \
49
+ pdo_mysql \
50
+ pdo_sqlite \
51
+ && docker-php-ext-enable \
52
+ mbstring exif bcmath intl zip gd mysqli pdo_mysql pdo_sqlite
53
+
54
+ # 🔥 LIMPEZA DE INIs DUPLICADOS (CRÍTICO)
55
+ RUN find /usr/local/etc/php/conf.d -type f -name "*docker-php-ext-*" -exec sed -i '/^extension=/d' {} \;
56
+
57
+ # ----------------
58
+ # COMPOSER
59
+ # ----------------
60
+ RUN curl -sS https://getcomposer.org/installer | php -- \
61
+ --install-dir=/usr/local/bin \
62
+ --filename=composer
63
+
64
+ # ----------------
65
+ # NODE (opcional p/ React)
66
+ # ----------------
67
+ RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
68
+ && apt-get install -y nodejs \
69
+ && node -v && npm -v
70
+
71
+ # ----------------
72
+ # APACHE CONFIG
73
+ # ----------------
74
+ RUN a2enmod rewrite headers
75
+
76
+ # ServerName GLOBAL (remove AH00558 de vez)
77
+ RUN echo "ServerName localhost" > /etc/apache2/conf-available/servername.conf \
78
+ && a2enconf servername
79
+
80
+ # Porta HF Spaces
81
+ RUN sed -i 's/Listen 80/Listen 7860/' /etc/apache2/ports.conf
82
+
83
+ RUN printf '<VirtualHost *:7860>\n\
84
+ ServerName localhost\n\
85
+ DocumentRoot /var/www/html\n\
86
+ <Directory /var/www/html>\n\
87
+ AllowOverride All\n\
88
+ Require all granted\n\
89
+ </Directory>\n\
90
+ ErrorLog ${APACHE_LOG_DIR}/error.log\n\
91
+ CustomLog ${APACHE_LOG_DIR}/access.log combined\n\
92
+ </VirtualHost>\n' > /etc/apache2/sites-available/000-default.conf
93
+
94
+ # ----------------
95
+ # APP
96
+ # ----------------
97
+ WORKDIR /var/www/html
98
+ COPY . .
99
+
100
+ # Logs e storage
101
+ RUN mkdir -p logs storage \
102
+ && chown -R www-data:www-data /var/www/html \
103
+ && chmod -R 775 logs storage
104
+
105
+ # ----------------
106
+ # COMPOSER INSTALL
107
+ # ----------------
108
+ RUN if [ -f composer.json ]; then \
109
+ composer install --no-dev --optimize-autoloader --no-interaction; \
110
+ fi
111
+
112
+ # ----------------
113
+ # REACT BUILD (SE EXISTIR)
114
+ # ----------------
115
+ RUN if [ -f package.json ]; then \
116
+ npm install && npm run build; \
117
+ fi
118
+
119
+ # ----------------
120
+ # PHP CONFIG FINAL
121
+ # ----------------
122
+ RUN printf "display_errors=Off\n\
123
+ log_errors=On\n\
124
+ error_log=/var/www/html/logs/php_errors.log\n\
125
+ memory_limit=256M\n\
126
+ upload_max_filesize=10M\n\
127
+ post_max_size=10M\n\
128
+ max_execution_time=300\n" > /usr/local/etc/php/conf.d/99-softedge.ini
129
+
130
+ # ----------------
131
+ # HEALTHCHECK
132
+ # ----------------
133
+ RUN echo "<?php http_response_code(200); echo 'OK';" > /var/www/html/health.php
134
+
135
+ HEALTHCHECK --interval=60s --timeout=5s \
136
+ CMD curl -f http://localhost:7860/health.php || exit 1
137
+
138
+ # ----------------
139
+ # START
140
+ # ----------------
141
+ EXPOSE 7860
142
+ CMD ["apache2-foreground"]
Dockerfile.railway ADDED
File without changes
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 SoftEdge Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README-RAILWAY.md ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚂 SoftEdge Corporation - Railway Deployment Guide
2
+
3
+ ## Problema Identificado
4
+
5
+ O erro `AH00534: apache2: Configuration error: More than one MPM loaded` ocorre especificamente no Railway devido a conflitos entre múltiplos MPMs (Multi-Processing Modules) do Apache.
6
+
7
+ ## Solução
8
+
9
+ Use o `Dockerfile.railway` otimizado especificamente para Railway:
10
+
11
+ ### Passos para Deploy no Railway:
12
+
13
+ 1. **Renomeie o Dockerfile:**
14
+ ```bash
15
+ mv Dockerfile Dockerfile.original
16
+ mv Dockerfile.railway Dockerfile
17
+ ```
18
+
19
+ 2. **Commit e Push:**
20
+ ```bash
21
+ git add .
22
+ git commit -m "Fix Railway MPM conflict with optimized Dockerfile"
23
+ git push origin main
24
+ ```
25
+
26
+ 3. **Railway fará automaticamente:**
27
+ - Build da imagem Docker otimizada
28
+ - Resolução do conflito de MPMs
29
+ - Deploy bem-sucedido
30
+
31
+ ## O que foi alterado no Dockerfile.railway:
32
+
33
+ ### ✅ Correções Aplicadas:
34
+
35
+ 1. **MPM Fix Robusto:**
36
+ ```dockerfile
37
+ RUN service apache2 stop && \
38
+ a2dismod mpm_event 2>/dev/null || true && \
39
+ a2dismod mpm_worker 2>/dev/null || true && \
40
+ a2dismod mpm_prefork 2>/dev/null || true && \
41
+ a2enmod mpm_prefork
42
+ ```
43
+
44
+ 2. **Configuração Apache Simplificada:**
45
+ - Removidos headers de segurança complexos que podem causar conflitos
46
+ - Configuração mínima necessária para Railway
47
+
48
+ 3. **Startup Direto:**
49
+ - Removido script de startup complexo
50
+ - Apache iniciado diretamente com `apache2-foreground`
51
+
52
+ ## Verificação
53
+
54
+ Após o deploy, verifique:
55
+ - ✅ Container inicia sem erros de MPM
56
+ - ✅ Apache responde na porta configurada
57
+ - ✅ Aplicação PHP+React funcionando
58
+ - ✅ Health check passando
59
+
60
+ ## Rollback (se necessário)
61
+
62
+ Para voltar à versão original:
63
+ ```bash
64
+ mv Dockerfile Dockerfile.railway
65
+ mv Dockerfile.original Dockerfile
66
+ git add .
67
+ git commit -m "Rollback to original Dockerfile"
68
+ git push origin main
69
+ ```
70
+
71
+ ## Suporte
72
+
73
+ Se o problema persistir:
74
+ 1. Verifique os logs do Railway
75
+ 2. Confirme que está usando `Dockerfile.railway`
76
+ 3. Teste localmente: `docker build -f Dockerfile.railway -t test . && docker run -p 8080:8080 test`
77
+
78
+ ---
79
+
80
+ **🎯 Esta solução resolve especificamente o conflito de MPMs no Railway mantendo toda a funcionalidade da aplicação.**
Railway.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://railway.app/railway.schema.json",
3
+ "build": {
4
+ "builder": "dockerfile"
5
+ },
6
+ "start": "apache2-foreground"
7
+ }
admin.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Start session and check authentication
3
+ session_start();
4
+
5
+ // Check if user is logged in and is admin
6
+ if (!isset($_SESSION['user']) || !isset($_SESSION['session_token'])) {
7
+ header('Location: login.php');
8
+ exit;
9
+ }
10
+
11
+ // Autoload Composer dependencies
12
+ require_once __DIR__ . '/vendor/autoload.php';
13
+
14
+ // Load environment variables
15
+ if (file_exists(__DIR__ . '/.env')) {
16
+ $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
17
+ $dotenv->load();
18
+ }
19
+
20
+ // Initialize User class
21
+ $user = new \SoftEdge\User();
22
+
23
+ // Validate session
24
+ $sessionUser = $user->validateSession($_SESSION['session_token']);
25
+ if (!$sessionUser || $sessionUser['role'] !== 'admin') {
26
+ session_destroy();
27
+ header('Location: login.php');
28
+ exit;
29
+ }
30
+
31
+ // Get admin statistics
32
+ $stats = $user->getAdminStats();
33
+
34
+ // Log admin page visit
35
+ $user->logPageVisit($sessionUser['id'], 'admin_dashboard', $_SERVER['HTTP_USER_AGENT'] ?? '');
36
+
37
+ // Handle logout
38
+ if (isset($_POST['logout'])) {
39
+ // Invalidate session
40
+ try {
41
+ $db = new PDO("mysql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_NAME']}", $_ENV['DB_USER'], $_ENV['DB_PASS']);
42
+ $stmt = $db->prepare("DELETE FROM user_sessions WHERE session_token = ?");
43
+ $stmt->execute([$_SESSION['session_token']]);
44
+ } catch (Exception $e) {
45
+ error_log("Session cleanup failed: " . $e->getMessage());
46
+ }
47
+
48
+ session_destroy();
49
+ header('Location: login.php');
50
+ exit;
51
+ }
52
+ ?>
53
+
54
+ <!DOCTYPE html>
55
+ <html lang="pt-BR" class="scroll-smooth">
56
+ <head>
57
+ <meta charset="UTF-8" />
58
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
59
+ <title>Painel Administrativo - SoftEdge Corporation</title>
60
+
61
+ <!-- SEO -->
62
+ <meta name="description" content="Painel administrativo SoftEdge Corporation">
63
+ <meta name="robots" content="noindex, nofollow">
64
+
65
+ <!-- Favicon -->
66
+ <link rel="icon" href="/assets/placeholder.svg" type="image/svg+xml">
67
+
68
+ <!-- Fonts -->
69
+ <link rel="preconnect" href="https://fonts.googleapis.com">
70
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
71
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
72
+
73
+ <!-- Tailwind CSS -->
74
+ <script src="https://cdn.tailwindcss.com"></script>
75
+ <script>
76
+ tailwind.config = {
77
+ theme: {
78
+ extend: {
79
+ fontFamily: {
80
+ sans: ['Inter', 'system-ui', 'sans-serif'],
81
+ },
82
+ colors: {
83
+ primary: {
84
+ 50: '#f8fafc',
85
+ 100: '#f1f5f9',
86
+ 200: '#e2e8f0',
87
+ 300: '#cbd5e1',
88
+ 400: '#94a3b8',
89
+ 500: '#64748b',
90
+ 600: '#475569',
91
+ 700: '#334155',
92
+ 800: '#1e293b',
93
+ 900: '#0f172a',
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ </script>
100
+
101
+ <!-- Lucide Icons -->
102
+ <script src="https://unpkg.com/lucide@latest"></script>
103
+
104
+ <!-- Chart.js for analytics -->
105
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
106
+
107
+ <style>
108
+ .glass-card {
109
+ background: rgba(30, 41, 59, 0.8);
110
+ backdrop-filter: blur(20px);
111
+ -webkit-backdrop-filter: blur(20px);
112
+ border: 1px solid rgba(148, 163, 184, 0.1);
113
+ }
114
+
115
+ .stat-card {
116
+ transition: all 0.3s ease;
117
+ }
118
+
119
+ .stat-card:hover {
120
+ transform: translateY(-2px);
121
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
122
+ }
123
+
124
+ .fade-in {
125
+ animation: fadeIn 0.6s ease-out;
126
+ }
127
+
128
+ @keyframes fadeIn {
129
+ from { opacity: 0; transform: translateY(20px); }
130
+ to { opacity: 1; transform: translateY(0); }
131
+ }
132
+
133
+ .sidebar {
134
+ transform: translateX(-100%);
135
+ transition: transform 0.3s ease;
136
+ }
137
+
138
+ .sidebar.open {
139
+ transform: translateX(0);
140
+ }
141
+
142
+ @media (min-width: 768px) {
143
+ .sidebar {
144
+ transform: translateX(0);
145
+ }
146
+ }
147
+ </style>
148
+ </head>
149
+
150
+ <body class="bg-slate-950 min-h-screen">
151
+ <!-- Sidebar -->
152
+ <div class="sidebar fixed inset-y-0 left-0 z-50 w-64 bg-slate-900 border-r border-slate-700 md:relative md:translate-x-0">
153
+ <div class="flex flex-col h-full">
154
+ <!-- Logo -->
155
+ <div class="flex items-center justify-center p-6 border-b border-slate-700">
156
+ <div class="flex items-center space-x-3">
157
+ <div class="w-8 h-8 rounded-lg overflow-hidden bg-slate-700 border border-slate-600">
158
+ <img src="/assets/logo.jpeg" alt="SoftEdge Logo" class="w-full h-full object-cover">
159
+ </div>
160
+ <span class="text-lg font-semibold text-slate-200 tracking-tight">
161
+ Admin Panel
162
+ </span>
163
+ </div>
164
+ </div>
165
+
166
+ <!-- Navigation -->
167
+ <nav class="flex-1 px-4 py-6 space-y-2">
168
+ <a href="#dashboard" class="nav-link flex items-center gap-3 px-4 py-3 text-slate-300 hover:text-white hover:bg-slate-800 rounded-lg transition-colors active">
169
+ <i data-lucide="layout-dashboard" class="w-5 h-5"></i>
170
+ <span>Dashboard</span>
171
+ </a>
172
+
173
+ <a href="#users" class="nav-link flex items-center gap-3 px-4 py-3 text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors">
174
+ <i data-lucide="users" class="w-5 h-5"></i>
175
+ <span>Usuários</span>
176
+ </a>
177
+
178
+ <a href="#analytics" class="nav-link flex items-center gap-3 px-4 py-3 text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors">
179
+ <i data-lucide="bar-chart-3" class="w-5 h-5"></i>
180
+ <span>Analytics</span>
181
+ </a>
182
+
183
+ <a href="#settings" class="nav-link flex items-center gap-3 px-4 py-3 text-slate-400 hover:text-white hover:bg-slate-800 rounded-lg transition-colors">
184
+ <i data-lucide="settings" class="w-5 h-5"></i>
185
+ <span>Configurações</span>
186
+ </a>
187
+ </nav>
188
+
189
+ <!-- User Info & Logout -->
190
+ <div class="p-4 border-t border-slate-700">
191
+ <div class="flex items-center gap-3 mb-4">
192
+ <div class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center">
193
+ <i data-lucide="user" class="w-4 h-4 text-slate-400"></i>
194
+ </div>
195
+ <div class="flex-1 min-w-0">
196
+ <p class="text-sm font-medium text-slate-200 truncate">
197
+ <?php echo htmlspecialchars($sessionUser['name']); ?>
198
+ </p>
199
+ <p class="text-xs text-slate-400">Administrador</p>
200
+ </div>
201
+ </div>
202
+
203
+ <form method="POST" class="w-full">
204
+ <button type="submit" name="logout" class="w-full flex items-center gap-3 px-4 py-2 text-slate-400 hover:text-white hover:bg-red-500/10 hover:border-red-500/20 border border-transparent rounded-lg transition-all">
205
+ <i data-lucide="log-out" class="w-4 h-4"></i>
206
+ <span class="text-sm">Sair</span>
207
+ </button>
208
+ </form>
209
+ </div>
210
+ </div>
211
+ </div>
212
+
213
+ <!-- Mobile Overlay -->
214
+ <div class="sidebar-overlay fixed inset-0 bg-black/50 z-40 md:hidden opacity-0 pointer-events-none transition-opacity"></div>
215
+
216
+ <!-- Main Content -->
217
+ <div class="md:ml-64">
218
+ <!-- Header -->
219
+ <header class="bg-slate-900/50 backdrop-blur-xl border-b border-slate-700 p-4 md:p-6">
220
+ <div class="flex items-center justify-between">
221
+ <div class="flex items-center gap-4">
222
+ <button class="md:hidden text-slate-400 hover:text-white p-2" id="sidebarToggle">
223
+ <i data-lucide="menu" class="w-6 h-6"></i>
224
+ </button>
225
+ <div>
226
+ <h1 class="text-2xl font-bold text-white">Dashboard Administrativo</h1>
227
+ <p class="text-slate-400 text-sm">Bem-vindo de volta, <?php echo htmlspecialchars(explode(' ', $sessionUser['name'])[0]); ?>!</p>
228
+ </div>
229
+ </div>
230
+
231
+ <div class="flex items-center gap-4">
232
+ <div class="hidden md:flex items-center gap-2 text-slate-400 text-sm">
233
+ <i data-lucide="clock" class="w-4 h-4"></i>
234
+ <span><?php echo date('d/m/Y H:i'); ?></span>
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </header>
239
+
240
+ <!-- Dashboard Content -->
241
+ <main class="p-4 md:p-6 space-y-6">
242
+ <!-- Stats Cards -->
243
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
244
+ <div class="stat-card glass-card p-6 rounded-xl">
245
+ <div class="flex items-center justify-between">
246
+ <div>
247
+ <p class="text-slate-400 text-sm font-medium">Total de Usuários</p>
248
+ <p class="text-2xl font-bold text-white"><?php echo number_format($stats['total_users'] ?? 0); ?></p>
249
+ </div>
250
+ <div class="w-12 h-12 bg-blue-500/20 rounded-lg flex items-center justify-center">
251
+ <i data-lucide="users" class="w-6 h-6 text-blue-400"></i>
252
+ </div>
253
+ </div>
254
+ </div>
255
+
256
+ <div class="stat-card glass-card p-6 rounded-xl">
257
+ <div class="flex items-center justify-between">
258
+ <div>
259
+ <p class="text-slate-400 text-sm font-medium">Total de Visitas</p>
260
+ <p class="text-2xl font-bold text-white"><?php echo number_format($stats['total_visits'] ?? 0); ?></p>
261
+ </div>
262
+ <div class="w-12 h-12 bg-green-500/20 rounded-lg flex items-center justify-center">
263
+ <i data-lucide="eye" class="w-6 h-6 text-green-400"></i>
264
+ </div>
265
+ </div>
266
+ </div>
267
+
268
+ <div class="stat-card glass-card p-6 rounded-xl">
269
+ <div class="flex items-center justify-between">
270
+ <div>
271
+ <p class="text-slate-400 text-sm font-medium">Visitas (30 dias)</p>
272
+ <p class="text-2xl font-bold text-white"><?php echo number_format($stats['recent_visits'] ?? 0); ?></p>
273
+ </div>
274
+ <div class="w-12 h-12 bg-purple-500/20 rounded-lg flex items-center justify-center">
275
+ <i data-lucide="trending-up" class="w-6 h-6 text-purple-400"></i>
276
+ </div>
277
+ </div>
278
+ </div>
279
+
280
+ <div class="stat-card glass-card p-6 rounded-xl">
281
+ <div class="flex items-center justify-between">
282
+ <div>
283
+ <p class="text-slate-400 text-sm font-medium">Taxa de Conversão</p>
284
+ <p class="text-2xl font-bold text-white">
285
+ <?php
286
+ $conversion = $stats['total_users'] > 0 ? (($stats['total_visits'] ?? 0) / $stats['total_users']) : 0;
287
+ echo number_format($conversion, 1);
288
+ ?>x
289
+ </p>
290
+ </div>
291
+ <div class="w-12 h-12 bg-orange-500/20 rounded-lg flex items-center justify-center">
292
+ <i data-lucide="target" class="w-6 h-6 text-orange-400"></i>
293
+ </div>
294
+ </div>
295
+ </div>
296
+ </div>
297
+
298
+ <!-- Charts and Tables -->
299
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
300
+ <!-- Top Pages Chart -->
301
+ <div class="glass-card p-6 rounded-xl">
302
+ <h3 class="text-lg font-semibold text-white mb-4 flex items-center gap-2">
303
+ <i data-lucide="bar-chart-3" class="w-5 h-5 text-slate-400"></i>
304
+ Páginas Mais Visitadas
305
+ </h3>
306
+ <div class="space-y-3">
307
+ <?php foreach (($stats['top_pages'] ?? []) as $page): ?>
308
+ <div class="flex items-center justify-between p-3 bg-slate-800/50 rounded-lg">
309
+ <span class="text-slate-300 capitalize"><?php echo htmlspecialchars($page['page']); ?></span>
310
+ <span class="text-slate-400 text-sm"><?php echo number_format($page['visits']); ?> visitas</span>
311
+ </div>
312
+ <?php endforeach; ?>
313
+ </div>
314
+ </div>
315
+
316
+ <!-- Recent Users -->
317
+ <div class="glass-card p-6 rounded-xl">
318
+ <h3 class="text-lg font-semibold text-white mb-4 flex items-center gap-2">
319
+ <i data-lucide="user-plus" class="w-5 h-5 text-slate-400"></i>
320
+ Usuários Recentes
321
+ </h3>
322
+ <div class="space-y-3">
323
+ <?php foreach (($stats['recent_users'] ?? []) as $recentUser): ?>
324
+ <div class="flex items-center gap-3 p-3 bg-slate-800/50 rounded-lg">
325
+ <div class="w-8 h-8 rounded-full bg-slate-700 flex items-center justify-center">
326
+ <i data-lucide="user" class="w-4 h-4 text-slate-400"></i>
327
+ </div>
328
+ <div class="flex-1 min-w-0">
329
+ <p class="text-slate-300 text-sm font-medium truncate"><?php echo htmlspecialchars($recentUser['name']); ?></p>
330
+ <p class="text-slate-400 text-xs"><?php echo date('d/m/Y', strtotime($recentUser['created_at'])); ?></p>
331
+ </div>
332
+ </div>
333
+ <?php endforeach; ?>
334
+ </div>
335
+ </div>
336
+ </div>
337
+
338
+ <!-- System Info -->
339
+ <div class="glass-card p-6 rounded-xl">
340
+ <h3 class="text-lg font-semibold text-white mb-4 flex items-center gap-2">
341
+ <i data-lucide="server" class="w-5 h-5 text-slate-400"></i>
342
+ Informações do Sistema
343
+ </h3>
344
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
345
+ <div class="p-4 bg-slate-800/50 rounded-lg">
346
+ <p class="text-slate-400 text-sm">PHP Version</p>
347
+ <p class="text-white font-medium"><?php echo PHP_VERSION; ?></p>
348
+ </div>
349
+ <div class="p-4 bg-slate-800/50 rounded-lg">
350
+ <p class="text-slate-400 text-sm">Database</p>
351
+ <p class="text-white font-medium">MySQL</p>
352
+ </div>
353
+ <div class="p-4 bg-slate-800/50 rounded-lg">
354
+ <p class="text-slate-400 text-sm">Último Backup</p>
355
+ <p class="text-white font-medium"><?php echo date('d/m/Y H:i'); ?></p>
356
+ </div>
357
+ </div>
358
+ </div>
359
+ </main>
360
+ </div>
361
+
362
+ <!-- Scripts -->
363
+ <script src="https://unpkg.com/lucide@latest"></script>
364
+ <script>
365
+ document.addEventListener('DOMContentLoaded', () => {
366
+ // Initialize Lucide icons
367
+ lucide.createIcons();
368
+
369
+ // Sidebar toggle for mobile
370
+ const sidebar = document.querySelector('.sidebar');
371
+ const overlay = document.querySelector('.sidebar-overlay');
372
+ const sidebarToggle = document.getElementById('sidebarToggle');
373
+
374
+ const toggleSidebar = () => {
375
+ sidebar.classList.toggle('open');
376
+ overlay.classList.toggle('opacity-0');
377
+ overlay.classList.toggle('pointer-events-none');
378
+ };
379
+
380
+ sidebarToggle?.addEventListener('click', toggleSidebar);
381
+ overlay?.addEventListener('click', toggleSidebar);
382
+
383
+ // Navigation active state
384
+ const navLinks = document.querySelectorAll('.nav-link');
385
+ navLinks.forEach(link => {
386
+ link.addEventListener('click', function(e) {
387
+ e.preventDefault();
388
+
389
+ // Remove active class from all links
390
+ navLinks.forEach(l => l.classList.remove('active', 'text-white'));
391
+ navLinks.forEach(l => l.classList.add('text-slate-400'));
392
+
393
+ // Add active class to clicked link
394
+ this.classList.add('active', 'text-white');
395
+ this.classList.remove('text-slate-400');
396
+
397
+ // Close sidebar on mobile
398
+ if (window.innerWidth < 768) {
399
+ toggleSidebar();
400
+ }
401
+ });
402
+ });
403
+
404
+ // Auto-refresh stats every 30 seconds
405
+ setInterval(() => {
406
+ // In a real application, you might want to implement AJAX calls here
407
+ // to refresh the statistics without reloading the page
408
+ console.log('Refreshing stats...');
409
+ }, 30000);
410
+ });
411
+ </script>
412
+ </body>
413
+ </html>
api.php ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ declare(strict_types=1);
3
+
4
+ require_once __DIR__ . '/src/Bootstrap.php';
5
+ \SoftEdge\Env::load(__DIR__);
6
+ \SoftEdge\Bootstrap::init();
7
+
8
+ use SoftEdge\Response;
9
+ use SoftEdge\Validation;
10
+ use SoftEdge\AuthService;
11
+ use SoftEdge\RateLimiter;
12
+ use SoftEdge\DB;
13
+ use PDO;
14
+
15
+ // Default JSON header
16
+ if (!headers_sent()) {
17
+ header('Content-Type: application/json; charset=utf-8');
18
+ header('X-Powered-By: SoftEdge');
19
+ }
20
+
21
+ // Handle OPTIONS (CORS preflight for development/SPA usage)
22
+ if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
23
+ header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
24
+ header('Access-Control-Allow-Headers: Content-Type, X-CSRF-Token, Authorization');
25
+ header('Access-Control-Max-Age: 86400');
26
+ http_response_code(204);
27
+ exit;
28
+ }
29
+
30
+ // Very limited CORS allowance if same-origin or configured
31
+ $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
32
+ $host = $_SERVER['HTTP_HOST'] ?? '';
33
+ if ($origin && str_contains($origin, $host)) {
34
+ header('Access-Control-Allow-Origin: ' . $origin);
35
+ header('Vary: Origin');
36
+ header('Access-Control-Allow-Credentials: true');
37
+ }
38
+
39
+ function path(): string {
40
+ $uri = parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH) ?: '/';
41
+ // Support both /api.php?r=... and /api/... styles
42
+ if (isset($_GET['r'])) {
43
+ $r = '/' . ltrim((string)$_GET['r'], '/');
44
+ return $r;
45
+ }
46
+ if (preg_match('#/api(?:\.php)?(.*)$#', $uri, $m)) {
47
+ return $m[1] ? (string)$m[1] : '/';
48
+ }
49
+ return $uri;
50
+ }
51
+
52
+ function json_body(): array {
53
+ $raw = file_get_contents('php://input');
54
+ $data = json_decode((string)$raw, true);
55
+ return is_array($data) ? $data : [];
56
+ }
57
+
58
+ $method = strtoupper($_SERVER['REQUEST_METHOD'] ?? 'GET');
59
+ $route = rtrim(path(), '/') ?: '/';
60
+
61
+ try {
62
+ switch (true) {
63
+ case $method === 'GET' && $route === '/health':
64
+ Response::json([
65
+ 'ok' => true,
66
+ 'time' => date('c'),
67
+ 'app' => 'SoftEdge API',
68
+ 'env' => \SoftEdge\Env::get('APP_ENV', 'production'),
69
+ ]);
70
+ break;
71
+
72
+ case $method === 'POST' && $route === '/auth/login':
73
+ $body = json_body();
74
+ $csrf = (string)($body['csrf'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? ''));
75
+ if (!\SoftEdge\Csrf::validate($csrf)) {
76
+ Response::json(['ok' => false, 'error' => 'CSRF inválido'], 400);
77
+ break;
78
+ }
79
+ $email = trim((string)($body['email'] ?? ''));
80
+ $password = (string)($body['password'] ?? '');
81
+ if (!Validation::email($email)) {
82
+ Response::json(['ok' => false, 'error' => 'Email inválido'], 422);
83
+ break;
84
+ }
85
+ $res = AuthService::login($email, $password);
86
+ Response::json($res, (int)($res['status'] ?? 200));
87
+ break;
88
+
89
+ case $method === 'POST' && $route === '/auth/logout':
90
+ AuthService::logout();
91
+ Response::json(['ok' => true]);
92
+ break;
93
+
94
+ case $method === 'POST' && $route === '/contact':
95
+ $body = json_body();
96
+ $csrf = (string)($body['csrf'] ?? ($_SERVER['HTTP_X_CSRF_TOKEN'] ?? ''));
97
+ if (!\SoftEdge\Csrf::validate($csrf)) {
98
+ Response::json(['ok' => false, 'error' => 'CSRF inválido'], 400);
99
+ break;
100
+ }
101
+ $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
102
+ if (!RateLimiter::allow('contact:' . $ip, \SoftEdge\Env::int('RATE_LIMIT_CONTACT', 3), 3600)) {
103
+ Response::json(['ok' => false, 'error' => 'Muitas solicitações. Tente mais tarde.'], 429);
104
+ break;
105
+ }
106
+ $name = trim((string)($body['name'] ?? ''));
107
+ $email = trim((string)($body['email'] ?? ''));
108
+ $message = trim((string)($body['message'] ?? ''));
109
+ $phone = trim((string)($body['phone'] ?? ''));
110
+ $company = trim((string)($body['company'] ?? ''));
111
+ $subject = trim((string)($body['subject'] ?? ''));
112
+
113
+ $errors = Validation::required(['name' => $name, 'email' => $email, 'message' => $message], ['name','email','message']);
114
+ if (!empty($errors) || !Validation::email($email)) {
115
+ $errors['email'] = $errors['email'] ?? (!Validation::email($email) ? 'Email inválido' : null);
116
+ Response::json(['ok' => false, 'errors' => array_filter($errors)], 422);
117
+ break;
118
+ }
119
+
120
+ $pdo = DB::pdo();
121
+ $stmt = $pdo->prepare('INSERT INTO contact_submissions (name, email, phone, company, subject, message, status) VALUES (:name,:email,:phone,:company,:subject,:message,\'new\')');
122
+ $stmt->execute([
123
+ ':name' => $name,
124
+ ':email' => $email,
125
+ ':phone' => $phone ?: null,
126
+ ':company' => $company ?: null,
127
+ ':subject' => $subject ?: null,
128
+ ':message' => $message,
129
+ ]);
130
+ Response::json(['ok' => true, 'id' => (int)$pdo->lastInsertId()], 201);
131
+ break;
132
+
133
+ default:
134
+ Response::json(['ok' => false, 'error' => 'Rota não encontrada', 'route' => $route], 404);
135
+ break;
136
+ }
137
+ } catch (Throwable $e) {
138
+ Response::json([
139
+ 'ok' => false,
140
+ 'error' => 'Erro interno',
141
+ ], 500);
142
+ }
app.py ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, jsonify, render_template, send_from_directory, redirect, url_for, flash, session, Response
2
+ import os
3
+ import json
4
+ import subprocess
5
+ import sys
6
+ from datetime import datetime, timedelta
7
+ import sqlite3
8
+ from werkzeug.security import generate_password_hash, check_password_hash
9
+ import jwt
10
+ import secrets
11
+ import requests
12
+
13
+ app = Flask(__name__)
14
+ app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', secrets.token_hex(32))
15
+ app.config['JWT_SECRET'] = os.environ.get('JWT_SECRET', secrets.token_hex(32))
16
+
17
+ # Database setup
18
+ def init_db():
19
+ conn = sqlite3.connect('softedge.db')
20
+ c = conn.cursor()
21
+ c.execute('''CREATE TABLE IF NOT EXISTS users
22
+ (id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ email TEXT UNIQUE NOT NULL,
24
+ password TEXT NOT NULL,
25
+ name TEXT,
26
+ role TEXT DEFAULT 'user',
27
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
28
+ c.execute('''CREATE TABLE IF NOT EXISTS contact_submissions
29
+ (id INTEGER PRIMARY KEY AUTOINCREMENT,
30
+ name TEXT NOT NULL,
31
+ email TEXT NOT NULL,
32
+ message TEXT NOT NULL,
33
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
34
+ c.execute('''CREATE TABLE IF NOT EXISTS projects
35
+ (id INTEGER PRIMARY KEY AUTOINCREMENT,
36
+ title TEXT NOT NULL,
37
+ description TEXT NOT NULL,
38
+ status TEXT DEFAULT 'active',
39
+ technologies TEXT,
40
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''')
41
+ conn.commit()
42
+ conn.close()
43
+
44
+ init_db()
45
+
46
+ # Helper functions
47
+ def get_db_connection():
48
+ conn = sqlite3.connect('softedge.db')
49
+ conn.row_factory = sqlite3.Row
50
+ return conn
51
+
52
+ def create_token(user_id):
53
+ payload = {
54
+ 'user_id': user_id,
55
+ 'exp': datetime.utcnow() + timedelta(hours=24)
56
+ }
57
+ return jwt.encode(payload, app.config['JWT_SECRET'], algorithm='HS256')
58
+
59
+ # PHP Integration
60
+ def call_php_script(script_name, method='GET', data=None):
61
+ """Call PHP script and return response"""
62
+ try:
63
+ php_path = os.path.join(os.getcwd(), script_name)
64
+ if not os.path.exists(php_path):
65
+ return None
66
+
67
+ # For simple GET requests, we can execute PHP directly
68
+ if method == 'GET':
69
+ result = subprocess.run(['php', php_path],
70
+ capture_output=True, text=True, timeout=30)
71
+ if result.returncode == 0:
72
+ return result.stdout
73
+ return None
74
+ except Exception as e:
75
+ print(f"PHP execution error: {e}")
76
+ return None
77
+
78
+ # Routes
79
+ @app.route('/')
80
+ def home():
81
+ # Get dynamic stats
82
+ stats = {'projects': 0, 'contacts': 0, 'satisfaction': 4.9}
83
+ try:
84
+ conn = get_db_connection()
85
+ stats['projects'] = conn.execute('SELECT COUNT(*) as count FROM projects').fetchone()['count']
86
+ stats['contacts'] = conn.execute('SELECT COUNT(*) as count FROM contact_submissions').fetchone()['count']
87
+ conn.close()
88
+ except Exception as e:
89
+ print(f"Stats error: {e}")
90
+
91
+ return render_template('index.html', stats=stats)
92
+
93
+ @app.route('/sobre')
94
+ def sobre():
95
+ return render_template('sobre.html')
96
+
97
+ @app.route('/servicos')
98
+ def servicos():
99
+ return render_template('servicos.html')
100
+
101
+ @app.route('/projetos')
102
+ def projetos():
103
+ # Get projects from database
104
+ projects = []
105
+ try:
106
+ conn = get_db_connection()
107
+ projects = conn.execute('SELECT * FROM projects ORDER BY created_at DESC').fetchall()
108
+ conn.close()
109
+ projects = [dict(project) for project in projects]
110
+ except Exception as e:
111
+ print(f"Projects error: {e}")
112
+
113
+ return render_template('projetos.html', projects=projects)
114
+
115
+ @app.route('/contato')
116
+ def contato():
117
+ return render_template('contato.html')
118
+
119
+ @app.route('/login')
120
+ def login():
121
+ return render_template('login.html')
122
+
123
+ @app.route('/register')
124
+ def register():
125
+ return render_template('register.html')
126
+
127
+ @app.route('/admin')
128
+ def admin():
129
+ # Check authentication
130
+ if 'user_id' not in session:
131
+ return redirect(url_for('login'))
132
+
133
+ # Get admin stats
134
+ stats = {'total_users': 0, 'total_contacts': 0, 'recent_users': [], 'recent_contacts': []}
135
+ try:
136
+ conn = get_db_connection()
137
+ stats['total_users'] = conn.execute('SELECT COUNT(*) as count FROM users').fetchone()['count']
138
+ stats['total_contacts'] = conn.execute('SELECT COUNT(*) as count FROM contact_submissions').fetchone()['count']
139
+
140
+ # Recent users
141
+ stats['recent_users'] = conn.execute(
142
+ 'SELECT name, email, created_at FROM users ORDER BY created_at DESC LIMIT 5'
143
+ ).fetchall()
144
+
145
+ # Recent contacts
146
+ stats['recent_contacts'] = conn.execute(
147
+ 'SELECT name, email, message, created_at FROM contact_submissions ORDER BY created_at DESC LIMIT 5'
148
+ ).fetchall()
149
+
150
+ conn.close()
151
+ stats['recent_users'] = [dict(user) for user in stats['recent_users']]
152
+ stats['recent_contacts'] = [dict(contact) for contact in stats['recent_contacts']]
153
+ except Exception as e:
154
+ print(f"Admin stats error: {e}")
155
+
156
+ return render_template('admin.html', stats=stats)
157
+
158
+ # API Routes
159
+ @app.route('/api/health')
160
+ def health():
161
+ return jsonify({
162
+ 'status': 'ok',
163
+ 'timestamp': datetime.now().isoformat(),
164
+ 'service': 'SoftEdge Hybrid API',
165
+ 'version': '3.0.0',
166
+ 'technologies': ['Flask', 'PHP', 'Node.js', 'MySQL']
167
+ })
168
+
169
+ @app.route('/api/stats')
170
+ def stats():
171
+ try:
172
+ conn = get_db_connection()
173
+ projects_count = conn.execute('SELECT COUNT(*) as count FROM projects').fetchone()['count']
174
+ contact_count = conn.execute('SELECT COUNT(*) as count FROM contact_submissions').fetchone()['count']
175
+ conn.close()
176
+
177
+ return jsonify({
178
+ 'projects': projects_count,
179
+ 'contacts': contact_count,
180
+ 'satisfaction': 4.9,
181
+ 'uptime': '99.9%'
182
+ })
183
+ except Exception as e:
184
+ return jsonify({'error': 'Database error'}), 500
185
+
186
+ @app.route('/api/contact', methods=['POST'])
187
+ def contact():
188
+ data = request.get_json()
189
+
190
+ if not data or not all(k in data for k in ['name', 'email', 'message']):
191
+ return jsonify({'error': 'Missing required fields'}), 400
192
+
193
+ try:
194
+ conn = get_db_connection()
195
+ conn.execute('INSERT INTO contact_submissions (name, email, message) VALUES (?, ?, ?)',
196
+ (data['name'], data['email'], data['message']))
197
+ conn.commit()
198
+ conn.close()
199
+
200
+ return jsonify({'message': 'Message sent successfully', 'status': 'success'}), 200
201
+ except Exception as e:
202
+ return jsonify({'error': 'Database error'}), 500
203
+
204
+ @app.route('/api/auth/login', methods=['POST'])
205
+ def api_login():
206
+ data = request.get_json()
207
+
208
+ if not data or not all(k in data for k in ['email', 'password']):
209
+ return jsonify({'error': 'Missing credentials'}), 400
210
+
211
+ try:
212
+ conn = get_db_connection()
213
+ user = conn.execute('SELECT * FROM users WHERE email = ?', (data['email'],)).fetchone()
214
+ conn.close()
215
+
216
+ if user and check_password_hash(user['password'], data['password']):
217
+ session['user_id'] = user['id']
218
+ session['user_email'] = user['email']
219
+ session['user_name'] = user['name']
220
+ session['user_role'] = user['role']
221
+ token = create_token(user['id'])
222
+
223
+ return jsonify({
224
+ 'message': 'Login successful',
225
+ 'token': token,
226
+ 'user': {
227
+ 'id': user['id'],
228
+ 'email': user['email'],
229
+ 'name': user['name'],
230
+ 'role': user['role']
231
+ }
232
+ }), 200
233
+ else:
234
+ return jsonify({'error': 'Invalid credentials'}), 401
235
+ except Exception as e:
236
+ return jsonify({'error': 'Database error'}), 500
237
+
238
+ @app.route('/api/auth/register', methods=['POST'])
239
+ def api_register():
240
+ data = request.get_json()
241
+
242
+ if not data or not all(k in data for k in ['email', 'password', 'name']):
243
+ return jsonify({'error': 'Missing required fields'}), 400
244
+
245
+ try:
246
+ hashed_password = generate_password_hash(data['password'])
247
+
248
+ conn = get_db_connection()
249
+ conn.execute('INSERT INTO users (email, password, name) VALUES (?, ?, ?)',
250
+ (data['email'], hashed_password, data['name']))
251
+ conn.commit()
252
+ user_id = conn.execute('SELECT last_insert_rowid()').fetchone()[0]
253
+ conn.close()
254
+
255
+ token = create_token(user_id)
256
+ return jsonify({
257
+ 'message': 'Registration successful',
258
+ 'token': token,
259
+ 'user': {
260
+ 'id': user_id,
261
+ 'email': data['email'],
262
+ 'name': data['name']
263
+ }
264
+ }), 201
265
+ except sqlite3.IntegrityError:
266
+ return jsonify({'error': 'Email already exists'}), 409
267
+ except Exception as e:
268
+ return jsonify({'error': 'Database error'}), 500
269
+
270
+ @app.route('/api/auth/logout')
271
+ def logout():
272
+ session.clear()
273
+ return jsonify({'message': 'Logged out successfully'})
274
+
275
+ # PHP Integration Routes
276
+ @app.route('/php/<path:script>')
277
+ def php_route(script):
278
+ """Route to execute PHP scripts"""
279
+ result = call_php_script(f'{script}.php')
280
+ if result:
281
+ return Response(result, mimetype='text/html')
282
+ return jsonify({'error': 'PHP script not found'}), 404
283
+
284
+ # Static files
285
+ @app.route('/assets/<path:filename>')
286
+ def assets(filename):
287
+ return send_from_directory('assets', filename)
288
+
289
+ @app.route('/css/<path:filename>')
290
+ def css_files(filename):
291
+ return send_from_directory('css', filename)
292
+
293
+ @app.route('/js/<path:filename>')
294
+ def js_files(filename):
295
+ return send_from_directory('js', filename)
296
+
297
+ # React integration
298
+ @app.route('/react-app')
299
+ def react_app():
300
+ return render_template('react-app.html')
301
+
302
+ if __name__ == '__main__':
303
+ # Seed initial data
304
+ conn = get_db_connection()
305
+ if not conn.execute('SELECT COUNT(*) FROM projects').fetchone()[0]:
306
+ projects = [
307
+ ('AKIRA IA', 'Assistente virtual angolano com processamento de linguagem natural', 'Concluído', 'Python, TensorFlow, FastAPI'),
308
+ ('ERP Gestão Total', 'Sistema completo de gestão empresarial', 'Concluído', 'Laravel, Vue.js, MySQL'),
309
+ ('E-commerce ShopFast', 'Plataforma de vendas online de alta performance', 'Concluído', 'Next.js, Stripe, Prisma'),
310
+ ('Sistema de Gestão Escolar', 'Plataforma completa para gestão educacional', 'Em desenvolvimento', 'React, Node.js, PostgreSQL'),
311
+ ('App Mobile Delivery', 'Aplicativo de delivery com geolocalização', 'Em desenvolvimento', 'Flutter, Firebase, Google Maps')
312
+ ]
313
+ conn.executemany('INSERT INTO projects (title, description, status, technologies) VALUES (?, ?, ?, ?)', projects)
314
+ conn.commit()
315
+
316
+ # Create admin user
317
+ admin_email = os.environ.get('ADMIN_EMAIL', 'admin@softedge.com')
318
+ admin_password = os.environ.get('ADMIN_PASSWORD', 'Admin@123456')
319
+ admin_name = os.environ.get('ADMIN_NAME', 'Isaac Quarenta')
320
+
321
+ if not conn.execute('SELECT id FROM users WHERE email = ?', (admin_email,)).fetchone():
322
+ hashed_password = generate_password_hash(admin_password)
323
+ conn.execute('INSERT INTO users (email, password, name, role) VALUES (?, ?, ?, ?)',
324
+ (admin_email, hashed_password, admin_name, 'super_admin'))
325
+ conn.commit()
326
+
327
+ conn.close()
328
+
329
+ print("🚀 SoftEdge Corporation - Hybrid Architecture Started!")
330
+ print("Technologies: Flask (Python) + PHP + Node.js + MySQL")
331
+ print("Server running on http://localhost:7860")
332
+
333
+ app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 7860)))
composer-schema.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "name": { "type": "string" },
6
+ "description": { "type": "string" },
7
+ "type": { "type": "string" },
8
+ "license": { "type": "string" },
9
+ "authors": {
10
+ "type": "array",
11
+ "items": {
12
+ "type": "object",
13
+ "properties": {
14
+ "name": { "type": "string" },
15
+ "email": { "type": "string" }
16
+ }
17
+ }
18
+ },
19
+ "require": { "type": "object" },
20
+ "require-dev": { "type": "object" },
21
+ "autoload": { "type": "object" },
22
+ "config": { "type": "object" },
23
+ "minimum-stability": { "type": "string" }
24
+ }
25
+ }
composer.json ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "./composer-schema.json",
3
+ "name": "softedge/softedge-corporation",
4
+ "description": "Professional website for SoftEdge Corporation - Modern web solutions with user management",
5
+ "type": "project",
6
+ "license": "MIT",
7
+ "authors": [
8
+ {
9
+ "name": "SoftEdge Corporation",
10
+ "email": "softedgecorporation@gmail.com"
11
+ }
12
+ ],
13
+ "require": {
14
+ "php": ">=8.1",
15
+ "phpmailer/phpmailer": "^6.8",
16
+ "monolog/monolog": "^3.0",
17
+ "vlucas/phpdotenv": "^5.5",
18
+ "firebase/php-jwt": "^6.4"
19
+ },
20
+ "require-dev": {
21
+ "phpunit/phpunit": "^10.0"
22
+ },
23
+ "autoload": {
24
+ "psr-4": {
25
+ "SoftEdge\\": "src/"
26
+ }
27
+ },
28
+ "config": {
29
+ "optimize-autoloader": true,
30
+ "prefer-stable": true,
31
+ "sort-packages": true
32
+ },
33
+ "minimum-stability": "stable"
34
+ }
contato.php ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__ . '/src/Bootstrap.php';
3
+ \SoftEdge\Env::load(__DIR__);
4
+ \SoftEdge\Bootstrap::init();
5
+ include 'components/header.php';
6
+ ?>
7
+
8
+ <!-- HERO SECTION -->
9
+ <section class="relative min-h-screen flex items-center justify-center overflow-hidden">
10
+ <!-- Background -->
11
+ <div class="absolute inset-0 -z-10">
12
+ <div class="absolute inset-0 bg-linear-to-br from-slate-950 via-slate-900 to-slate-950"></div>
13
+ <div class="absolute inset-0 opacity-30">
14
+ <div class="absolute top-1/4 left-1/4 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl animate-pulse"></div>
15
+ <div class="absolute bottom-1/4 right-1/4 w-96 h-96 bg-blue-500/20 rounded-full blur-3xl animate-pulse" style="animation-delay: 2s;"></div>
16
+ <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[600px] h-[600px] bg-purple-500/10 rounded-full blur-3xl"></div>
17
+ </div>
18
+ </div>
19
+
20
+ <!-- Content -->
21
+ <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20">
22
+ <div class="text-center space-y-12">
23
+
24
+ <!-- Badge -->
25
+ <div class="inline-block px-4 py-2 bg-cyan-500/10 rounded-full border border-cyan-500/20 backdrop-blur-sm">
26
+ <span class="text-cyan-400 text-xs sm:text-sm font-semibold uppercase tracking-wider">
27
+ 💬 Entre em Contato
28
+ </span>
29
+ </div>
30
+
31
+ <!-- Main Heading -->
32
+ <div class="space-y-6">
33
+ <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl xl:text-8xl font-bold leading-tight">
34
+ <span class="block text-white mb-2">Vamos conversar</span>
35
+ <span class="block bg-linear-to-r from-cyan-400 via-blue-500 to-purple-500 bg-clip-text text-transparent">
36
+ sobre seu projeto?
37
+ </span>
38
+ </h1>
39
+
40
+ <p class="text-base sm:text-lg md:text-xl text-gray-300 max-w-2xl mx-auto leading-relaxed">
41
+ Estamos prontos para transformar suas ideias em realidade.<br class="hidden sm:block">
42
+ Escolha o melhor canal para falar conosco.
43
+ </p>
44
+ </div>
45
+
46
+ <!-- Contact Cards Grid -->
47
+ <div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-6 lg:gap-8 mt-16 max-w-5xl mx-auto">
48
+
49
+ <!-- Card 1: Email -->
50
+ <a href="mailto:softedgecorporation@gmail.com"
51
+ class="group relative">
52
+ <div class="absolute inset-0 bg-linear-to-br from-cyan-500/20 to-blue-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
53
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 hover:border-cyan-500/50 rounded-2xl p-8 transition-all duration-300 group-hover:scale-105 h-full flex flex-col items-center text-center">
54
+ <div class="w-16 h-16 bg-cyan-500/20 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
55
+ <i data-lucide="mail" class="w-8 h-8 text-cyan-400"></i>
56
+ </div>
57
+ <h3 class="text-xl font-bold text-white mb-3">Email Direto</h3>
58
+ <p class="text-gray-400 text-sm mb-4 grow">
59
+ Envie sua mensagem e receba resposta em até 24 horas
60
+ </p>
61
+ <div class="text-cyan-400 font-medium text-sm break-all">
62
+ softedgecorporation@gmail.com
63
+ </div>
64
+ <div class="mt-4 inline-flex items-center gap-2 text-cyan-400 text-sm font-medium">
65
+ <span>Enviar email</span>
66
+ <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform"></i>
67
+ </div>
68
+ </div>
69
+ </a>
70
+
71
+ <!-- Card 2: WhatsApp -->
72
+ <a href="https://whatsapp.com/channel/0029VawQLpGHltY2Y87fR83m"
73
+ target="_blank"
74
+ rel="noopener noreferrer"
75
+ class="group relative">
76
+ <div class="absolute inset-0 bg-linear-to-br from-green-500/20 to-emerald-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
77
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 hover:border-green-500/50 rounded-2xl p-8 transition-all duration-300 group-hover:scale-105 h-full flex flex-col items-center text-center">
78
+ <div class="w-16 h-16 bg-green-500/20 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
79
+ <i data-lucide="message-circle" class="w-8 h-8 text-green-400"></i>
80
+ </div>
81
+ <h3 class="text-xl font-bold text-white mb-3">Canal WhatsApp</h3>
82
+ <p class="text-gray-400 text-sm mb-4 grow">
83
+ Junte-se ao nosso canal e receba novidades em primeira mão
84
+ </p>
85
+ <div class="inline-flex items-center gap-2 px-4 py-2 bg-green-500/20 border border-green-500/30 rounded-lg">
86
+ <i data-lucide="users" class="w-4 h-4 text-green-400"></i>
87
+ <span class="text-green-400 font-medium text-sm">Canal Oficial</span>
88
+ </div>
89
+ <div class="mt-4 inline-flex items-center gap-2 text-green-400 text-sm font-medium">
90
+ <span>Entrar agora</span>
91
+ <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform"></i>
92
+ </div>
93
+ </div>
94
+ </a>
95
+
96
+ <!-- Card 3: Twitter/X -->
97
+ <a href="https://x.com/softedge40"
98
+ target="_blank"
99
+ rel="noopener noreferrer"
100
+ class="group relative sm:col-span-2 lg:col-span-1">
101
+ <div class="absolute inset-0 bg-linear-to-br from-blue-500/20 to-purple-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
102
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 hover:border-blue-500/50 rounded-2xl p-8 transition-all duration-300 group-hover:scale-105 h-full flex flex-col items-center text-center">
103
+ <div class="w-16 h-16 bg-blue-500/20 rounded-2xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
104
+ <i data-lucide="twitter" class="w-8 h-8 text-blue-400"></i>
105
+ </div>
106
+ <h3 class="text-xl font-bold text-white mb-3">Twitter / X</h3>
107
+ <p class="text-gray-400 text-sm mb-4 grow">
108
+ Siga-nos para dicas, projetos e conteúdo sobre tecnologia
109
+ </p>
110
+ <div class="text-blue-400 font-medium text-sm">
111
+ @softedge40
112
+ </div>
113
+ <div class="mt-4 inline-flex items-center gap-2 text-blue-400 text-sm font-medium">
114
+ <span>Seguir agora</span>
115
+ <i data-lucide="arrow-right" class="w-4 h-4 group-hover:translate-x-1 transition-transform"></i>
116
+ </div>
117
+ </div>
118
+ </a>
119
+ </div>
120
+
121
+ <!-- Divider -->
122
+ <div class="relative py-12">
123
+ <div class="absolute inset-0 flex items-center">
124
+ <div class="w-full border-t border-white/10"></div>
125
+ </div>
126
+ <div class="relative flex justify-center">
127
+ <span class="px-6 bg-slate-950 text-gray-400 text-sm uppercase tracking-wider">Ou</span>
128
+ </div>
129
+ </div>
130
+
131
+ <!-- CTA Section -->
132
+ <div class="max-w-3xl mx-auto">
133
+ <div class="relative">
134
+ <div class="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 rounded-3xl blur-2xl"></div>
135
+
136
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-3xl p-8 lg:p-12">
137
+ <div class="space-y-6">
138
+ <div class="w-14 h-14 bg-linear-to-br from-cyan-500 to-blue-600 rounded-xl flex items-center justify-center mx-auto">
139
+ <i data-lucide="send" class="w-7 h-7 text-white"></i>
140
+ </div>
141
+
142
+ <h2 class="text-2xl sm:text-3xl md:text-4xl font-bold text-white">
143
+ Prefere um formulário completo?
144
+ </h2>
145
+
146
+ <p class="text-gray-300 text-base sm:text-lg">
147
+ Preencha nosso formulário de contato com todos os detalhes do seu projeto e receba uma resposta personalizada em até 24 horas.
148
+ </p>
149
+
150
+ <a href="feedback.php"
151
+ class="inline-flex items-center justify-center gap-3 bg-slate-700 hover:bg-slate-600 border border-slate-600 text-slate-200 font-medium text-lg px-8 py-4 rounded-lg transition-all duration-300">
152
+ Preencher Formulário
153
+ <i data-lucide="arrow-right" class="w-5 h-5"></i>
154
+ </a>
155
+ </div>
156
+ </div>
157
+ </div>
158
+ </div>
159
+
160
+ <!-- Info Section -->
161
+ <div class="grid sm:grid-cols-3 gap-6 lg:gap-8 mt-16 max-w-4xl mx-auto">
162
+ <!-- Info 1 -->
163
+ <div class="text-center">
164
+ <div class="w-12 h-12 bg-cyan-500/10 rounded-xl flex items-center justify-center mx-auto mb-4">
165
+ <i data-lucide="clock" class="w-6 h-6 text-cyan-400"></i>
166
+ </div>
167
+ <h3 class="text-white font-semibold mb-2">Resposta Rápida</h3>
168
+ <p class="text-gray-400 text-sm">Até 24 horas úteis</p>
169
+ </div>
170
+
171
+ <!-- Info 2 -->
172
+ <div class="text-center">
173
+ <div class="w-12 h-12 bg-blue-500/10 rounded-xl flex items-center justify-center mx-auto mb-4">
174
+ <i data-lucide="shield-check" class="w-6 h-6 text-blue-400"></i>
175
+ </div>
176
+ <h3 class="text-white font-semibold mb-2">100% Seguro</h3>
177
+ <p class="text-gray-400 text-sm">Seus dados protegidos</p>
178
+ </div>
179
+
180
+ <!-- Info 3 -->
181
+ <div class="text-center">
182
+ <div class="w-12 h-12 bg-purple-500/10 rounded-xl flex items-center justify-center mx-auto mb-4">
183
+ <i data-lucide="headphones" class="w-6 h-6 text-purple-400"></i>
184
+ </div>
185
+ <h3 class="text-white font-semibold mb-2">Suporte 24/7</h3>
186
+ <p class="text-gray-400 text-sm">Sempre disponível</p>
187
+ </div>
188
+ </div>
189
+
190
+ <!-- Location -->
191
+ <div class="pt-12">
192
+ <div class="inline-flex items-center gap-2 text-gray-400">
193
+ <i data-lucide="map-pin" class="w-5 h-5"></i>
194
+ <span>Localizado em Luanda, Angola 🇦🇴</span>
195
+ </div>
196
+ </div>
197
+
198
+ </div>
199
+ </div>
200
+ </section>
201
+
202
+ <?php include 'components/footer.php'; ?>
203
+
204
+ <!-- SCRIPTS -->
205
+ <script src="https://unpkg.com/lucide@latest"></script>
206
+ <script>
207
+ document.addEventListener('DOMContentLoaded', () => {
208
+ // Initialize Lucide icons
209
+ lucide.createIcons();
210
+
211
+ // Fade in animations on scroll
212
+ const observerOptions = {
213
+ threshold: 0.1,
214
+ rootMargin: '0px 0px -50px 0px'
215
+ };
216
+
217
+ const observer = new IntersectionObserver((entries) => {
218
+ entries.forEach(entry => {
219
+ if (entry.isIntersecting) {
220
+ entry.target.style.opacity = '1';
221
+ entry.target.style.transform = 'translateY(0)';
222
+ }
223
+ });
224
+ }, observerOptions);
225
+
226
+ // Observe all cards and sections
227
+ document.querySelectorAll('.group, section > div > div').forEach((el, index) => {
228
+ el.style.opacity = '0';
229
+ el.style.transform = 'translateY(20px)';
230
+ el.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`;
231
+ observer.observe(el);
232
+ });
233
+
234
+ // Add click tracking (optional)
235
+ document.querySelectorAll('a[href^="mailto:"], a[href*="whatsapp"], a[href*="twitter"]').forEach(link => {
236
+ link.addEventListener('click', function(e) {
237
+ const channel = this.href.includes('mailto') ? 'Email' :
238
+ this.href.includes('whatsapp') ? 'WhatsApp' : 'Twitter';
239
+ console.log(`Usuário clicou em: ${channel}`);
240
+ });
241
+ });
242
+ });
243
+ </script>
244
+
245
+ <style>
246
+ /* Gradient animation */
247
+ @keyframes gradient-shift {
248
+ 0%, 100% {
249
+ background-position: 0% 50%;
250
+ }
251
+ 50% {
252
+ background-position: 100% 50%;
253
+ }
254
+ }
255
+
256
+ .bg-linear-to-r,
257
+ .bg-linear-to-br {
258
+ background-size: 200% 200%;
259
+ animation: gradient-shift 8s ease infinite;
260
+ }
261
+
262
+ /* Pulse animation for background orbs */
263
+ @keyframes pulse-slow {
264
+ 0%, 100% {
265
+ opacity: 0.3;
266
+ transform: scale(1);
267
+ }
268
+ 50% {
269
+ opacity: 0.5;
270
+ transform: scale(1.1);
271
+ }
272
+ }
273
+
274
+ .animate-pulse {
275
+ animation: pulse-slow 8s ease-in-out infinite;
276
+ }
277
+
278
+ /* Smooth hover transitions */
279
+ .group {
280
+ will-change: transform;
281
+ }
282
+
283
+ /* Custom scrollbar */
284
+ ::-webkit-scrollbar {
285
+ width: 10px;
286
+ }
287
+
288
+ ::-webkit-scrollbar-track {
289
+ background: #0f172a;
290
+ }
291
+
292
+ ::-webkit-scrollbar-thumb {
293
+ background: linear-gradient(180deg, #06b6d4, #3b82f6);
294
+ border-radius: 5px;
295
+ }
296
+
297
+ ::-webkit-scrollbar-thumb:hover {
298
+ background: linear-gradient(180deg, #0891b2, #2563eb);
299
+ }
300
+ </style>
database.sql ADDED
Binary file (44.4 kB). View file
 
dev.sh ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # SoftEdge Corporation - Development Script
4
+ # This script sets up the development environment for React integration
5
+
6
+ echo "🚀 Starting SoftEdge Corporation Development Environment"
7
+ echo "======================================================"
8
+
9
+ # Check if Node.js is installed
10
+ if ! command -v node &> /dev/null; then
11
+ echo "❌ Node.js is not installed. Please install Node.js first."
12
+ exit 1
13
+ fi
14
+
15
+ # Check if npm is installed
16
+ if ! command -v npm &> /dev/null; then
17
+ echo "❌ npm is not installed. Please install npm first."
18
+ exit 1
19
+ fi
20
+
21
+ echo "✅ Node.js version: $(node --version)"
22
+ echo "✅ npm version: $(npm --version)"
23
+
24
+ # Install dependencies
25
+ echo ""
26
+ echo "📦 Installing dependencies..."
27
+ npm install
28
+
29
+ if [ $? -ne 0 ]; then
30
+ echo "❌ Failed to install dependencies"
31
+ exit 1
32
+ fi
33
+
34
+ echo "✅ Dependencies installed successfully"
35
+
36
+ # Build React app
37
+ echo ""
38
+ echo "🔨 Building React application..."
39
+ npm run build
40
+
41
+ if [ $? -ne 0 ]; then
42
+ echo "❌ Failed to build React application"
43
+ exit 1
44
+ fi
45
+
46
+ echo "✅ React application built successfully"
47
+
48
+ # Start development server (optional)
49
+ echo ""
50
+ echo "💡 Development environment ready!"
51
+ echo ""
52
+ echo "To start the development server, run:"
53
+ echo " npm run dev"
54
+ echo ""
55
+ echo "To build for production:"
56
+ echo " npm run build"
57
+ echo ""
58
+ echo "The built files are in the 'dist/' directory and can be served by your PHP application."
feedback.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Autoload Composer dependencies
3
+ require_once __DIR__ . '/vendor/autoload.php';
4
+
5
+ // Load environment variables if .env exists
6
+ if (file_exists(__DIR__ . '/.env')) {
7
+ $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
8
+ $dotenv->load();
9
+ }
10
+
11
+ // Generate CSRF token for the form (must be before any output)
12
+ if (session_status() === PHP_SESSION_NONE) {
13
+ session_start();
14
+ }
15
+ $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
16
+
17
+ // PROCESSAMENTO DO ENVIO DE EMAIL
18
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
19
+ header('Content-Type: application/json');
20
+ header('X-Content-Type-Options: nosniff');
21
+ header('X-Frame-Options: DENY');
22
+ header('X-XSS-Protection: 1; mode=block');
23
+
24
+ try {
25
+ // Rate limiting - prevent spam
26
+ $rateLimitFile = __DIR__ . '/logs/rate_limit_' . md5($_SERVER['REMOTE_ADDR'] ?? 'unknown') . '.txt';
27
+ $currentTime = time();
28
+
29
+ if (file_exists($rateLimitFile)) {
30
+ $lastRequest = (int)file_get_contents($rateLimitFile);
31
+ if ($currentTime - $lastRequest < 60) { // 1 minute cooldown
32
+ echo json_encode(['success' => false, 'error' => 'Aguarde um momento antes de enviar outra mensagem.']);
33
+ exit;
34
+ }
35
+ }
36
+
37
+ // Update rate limit
38
+ file_put_contents($rateLimitFile, $currentTime);
39
+
40
+ // Sanitize and validate input
41
+ $nome = trim($_POST['nome'] ?? '');
42
+ $email = trim($_POST['email'] ?? '');
43
+ $empresa = trim($_POST['empresa'] ?? '(não informado)');
44
+ $mensagem = trim($_POST['mensagem'] ?? '');
45
+
46
+ // CSRF protection (basic)
47
+ $csrfToken = $_POST['csrf_token'] ?? '';
48
+ $sessionToken = $_SESSION['csrf_token'] ?? '';
49
+
50
+ if (empty($csrfToken) || $csrfToken !== $sessionToken) {
51
+ echo json_encode(['success' => false, 'error' => 'Erro de segurança. Recarregue a página e tente novamente.']);
52
+ exit;
53
+ }
54
+
55
+ // Prepare data for email service
56
+ $contactData = [
57
+ 'nome' => $nome,
58
+ 'email' => $email,
59
+ 'empresa' => $empresa,
60
+ 'mensagem' => $mensagem
61
+ ];
62
+
63
+ // Use professional email service
64
+ $emailService = new \SoftEdge\EmailService();
65
+
66
+ if ($emailService->sendContactEmail($contactData)) {
67
+ echo json_encode(['success' => true]);
68
+ } else {
69
+ echo json_encode(['success' => false, 'error' => 'Erro ao enviar mensagem. Por favor, tente novamente ou entre em contato via WhatsApp.']);
70
+ }
71
+
72
+ } catch (\InvalidArgumentException $e) {
73
+ echo json_encode(['success' => false, 'error' => $e->getMessage()]);
74
+ } catch (\Exception $e) {
75
+ error_log('Contact form error: ' . $e->getMessage());
76
+ echo json_encode(['success' => false, 'error' => 'Erro interno do servidor. Nossa equipe foi notificada.']);
77
+ }
78
+
79
+ exit;
80
+ }
81
+ ?>
82
+ =======
83
+ <?php
84
+ // Autoload Composer dependencies
85
+ require_once __DIR__ . '/vendor/autoload.php';
86
+
87
+ // Load environment variables if .env exists
88
+ if (file_exists(__DIR__ . '/.env')) {
89
+ $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
90
+ $dotenv->load();
91
+ }
92
+
93
+ // PROCESSAMENTO DO ENVIO DE EMAIL
94
+ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
95
+ header('Content-Type: application/json');
96
+ header('X-Content-Type-Options: nosniff');
97
+ header('X-Frame-Options: DENY');
98
+ header('X-XSS-Protection: 1; mode=block');
99
+
100
+ try {
101
+ // Rate limiting - prevent spam
102
+ $rateLimitFile = __DIR__ . '/logs/rate_limit_' . md5($_SERVER['REMOTE_ADDR'] ?? 'unknown') . '.txt';
103
+ $currentTime = time();
104
+
105
+ if (file_exists($rateLimitFile)) {
106
+ $lastRequest = (int)file_get_contents($rateLimitFile);
107
+ if ($currentTime - $lastRequest < 60) { // 1 minute cooldown
108
+ echo json_encode(['success' => false, 'error' => 'Aguarde um momento antes de enviar outra mensagem.']);
109
+ exit;
110
+ }
111
+ }
112
+
113
+ // Update rate limit
114
+ file_put_contents($rateLimitFile, $currentTime);
115
+
116
+ // Sanitize and validate input
117
+ $nome = trim($_POST['nome'] ?? '');
118
+ $email = trim($_POST['email'] ?? '');
119
+ $empresa = trim($_POST['empresa'] ?? '(não informado)');
120
+ $mensagem = trim($_POST['mensagem'] ?? '');
121
+
122
+ // CSRF protection (basic)
123
+ $csrfToken = $_POST['csrf_token'] ?? '';
124
+ $sessionToken = $_SESSION['csrf_token'] ?? '';
125
+
126
+ if (empty($csrfToken) || $csrfToken !== $sessionToken) {
127
+ echo json_encode(['success' => false, 'error' => 'Erro de segurança. Recarregue a página e tente novamente.']);
128
+ exit;
129
+ }
130
+
131
+ // Prepare data for email service
132
+ $contactData = [
133
+ 'nome' => $nome,
134
+ 'email' => $email,
135
+ 'empresa' => $empresa,
136
+ 'mensagem' => $mensagem
137
+ ];
138
+
139
+ // Use professional email service
140
+ $emailService = new \SoftEdge\EmailService();
141
+
142
+ if ($emailService->sendContactEmail($contactData)) {
143
+ echo json_encode(['success' => true]);
144
+ } else {
145
+ echo json_encode(['success' => false, 'error' => 'Erro ao enviar mensagem. Por favor, tente novamente ou entre em contato via WhatsApp.']);
146
+ }
147
+
148
+ } catch (\InvalidArgumentException $e) {
149
+ echo json_encode(['success' => false, 'error' => $e->getMessage()]);
150
+ } catch (\Exception $e) {
151
+ error_log('Contact form error: ' . $e->getMessage());
152
+ echo json_encode(['success' => false, 'error' => 'Erro interno do servidor. Nossa equipe foi notificada.']);
153
+ }
154
+
155
+ exit;
156
+ }
157
+
158
+ // Generate CSRF token for the form
159
+ if (session_status() === PHP_SESSION_NONE) {
160
+ session_start();
161
+ }
162
+ $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
163
+ ?>
health.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Health Check Endpoint for Render.com
3
+ // This keeps the service active by preventing sleep mode
4
+
5
+ header('Content-Type: application/json');
6
+ header('Cache-Control: no-cache, no-store, must-revalidate');
7
+ header('Pragma: no-cache');
8
+ header('Expires: 0');
9
+
10
+ // Basic health check
11
+ $health = [
12
+ 'status' => 'healthy',
13
+ 'timestamp' => date('c'),
14
+ 'service' => 'SoftEdge Corporation Website',
15
+ 'version' => '2.0.0',
16
+ 'uptime' => time() - ($_SERVER['REQUEST_TIME'] ?? time()),
17
+ 'checks' => [
18
+ 'database' => 'not_required',
19
+ 'filesystem' => is_writable(__DIR__) ? 'writable' : 'read_only',
20
+ 'php' => PHP_VERSION,
21
+ 'memory' => memory_get_peak_usage(true) . ' bytes',
22
+ 'server' => $_SERVER['SERVER_SOFTWARE'] ?? 'unknown'
23
+ ]
24
+ ];
25
+
26
+ // Check if critical files exist
27
+ $criticalFiles = [
28
+ 'index.php',
29
+ 'composer.json',
30
+ 'vendor/autoload.php',
31
+ 'assets/logo.jpeg'
32
+ ];
33
+
34
+ foreach ($criticalFiles as $file) {
35
+ if (!file_exists(__DIR__ . '/' . $file)) {
36
+ $health['status'] = 'degraded';
37
+ $health['checks']['missing_files'][] = $file;
38
+ }
39
+ }
40
+
41
+ // Check if email service is configured
42
+ $emailConfigured = false;
43
+ if (file_exists(__DIR__ . '/.env')) {
44
+ $envContent = file_get_contents(__DIR__ . '/.env');
45
+ $emailConfigured = strpos($envContent, 'SMTP_HOST=') !== false;
46
+ }
47
+ $health['checks']['email_configured'] = $emailConfigured;
48
+
49
+ // Return appropriate HTTP status
50
+ if ($health['status'] === 'healthy') {
51
+ http_response_code(200);
52
+ } elseif ($health['status'] === 'degraded') {
53
+ http_response_code(200); // Still return 200 for uptime monitors
54
+ } else {
55
+ http_response_code(503);
56
+ }
57
+
58
+ echo json_encode($health, JSON_PRETTY_PRINT);
59
+ ?>
index.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // PHP Component - Can be called by Flask or run standalone
3
+ require_once __DIR__ . '/src/Bootstrap.php';
4
+ \SoftEdge\Env::load(__DIR__);
5
+ \SoftEdge\Bootstrap::init();
6
+
7
+ // If called directly (not by Flask), redirect to Flask server
8
+ if (!isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !isset($_GET['direct'])) {
9
+ header('Location: http://localhost:7860/');
10
+ exit;
11
+ }
12
+
13
+ // Track page visit
14
+ try {
15
+ \SoftEdge\Database::execute(
16
+ "INSERT INTO page_visits (page_url, page_title, ip_address, user_agent, device_type, referrer_url) VALUES (?, ?, ?, ?, ?, ?)",
17
+ [
18
+ '/',
19
+ 'SoftEdge Corporation - Soluções em Tecnologia',
20
+ $_SERVER['REMOTE_ADDR'] ?? '',
21
+ $_SERVER['HTTP_USER_AGENT'] ?? '',
22
+ 'desktop', // Simplified detection
23
+ $_SERVER['HTTP_REFERER'] ?? ''
24
+ ]
25
+ );
26
+ } catch (Exception $e) {
27
+ // Log error but don't break page
28
+ error_log("Page visit tracking failed: " . $e->getMessage());
29
+ }
30
+
31
+ // Get dynamic stats
32
+ $stats = ['projects' => 0, 'contacts' => 0, 'satisfaction' => 4.9];
33
+ try {
34
+ $statsData = \SoftEdge\Database::queryOne("SELECT COUNT(*) as projects FROM projects");
35
+ $contactsData = \SoftEdge\Database::queryOne("SELECT COUNT(*) as contacts FROM contact_submissions");
36
+ $stats['projects'] = $statsData['projects'] ?? 0;
37
+ $stats['contacts'] = $contactsData['contacts'] ?? 0;
38
+ } catch (Exception $e) {
39
+ // Use defaults if DB fails
40
+ }
41
+
42
+ // If called with JSON request, return data for Flask
43
+ if (isset($_GET['json'])) {
44
+ header('Content-Type: application/json');
45
+ echo json_encode($stats);
46
+ exit;
47
+ }
48
+
49
+ // Otherwise, render the component HTML
50
+ ?>
51
+ <!-- PHP Component: Homepage Stats -->
52
+ <div class="grid grid-cols-1 sm:grid-cols-3 gap-8 max-w-2xl mx-auto mt-12">
53
+ <div class="text-center">
54
+ <div class="text-4xl font-bold text-cyan-400"><?php echo number_format($stats['projects']); ?>+</div>
55
+ <div class="text-slate-400">Projetos Entregues</div>
56
+ </div>
57
+ <div class="text-center">
58
+ <div class="text-4xl font-bold text-blue-400"><?php echo number_format($stats['contacts']); ?>+</div>
59
+ <div class="text-slate-400">Clientes Satisfeitos</div>
60
+ </div>
61
+ <div class="text-center">
62
+ <div class="text-4xl font-bold text-purple-400"><?php echo $stats['satisfaction']; ?>★</div>
63
+ <div class="text-slate-400">Avaliação Média</div>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mt-16">
68
+ <!-- Desenvolvimento Web -->
69
+ <div class="glass-card p-8 rounded-2xl hover:scale-105 transition-transform">
70
+ <div class="w-16 h-16 bg-cyan-500/20 rounded-2xl flex items-center justify-center mb-6">
71
+ <i data-lucide="code" class="w-8 h-8 text-cyan-400"></i>
72
+ </div>
73
+ <h3 class="text-2xl font-bold text-white mb-4">Desenvolvimento Web</h3>
74
+ <p class="text-slate-400 leading-relaxed">
75
+ Aplicações web modernas e responsivas com as melhores tecnologias do mercado.
76
+ </p>
77
+ </div>
78
+
79
+ <!-- Mobile Apps -->
80
+ <div class="glass-card p-8 rounded-2xl hover:scale-105 transition-transform">
81
+ <div class="w-16 h-16 bg-blue-500/20 rounded-2xl flex items-center justify-center mb-6">
82
+ <i data-lucide="smartphone" class="w-8 h-8 text-blue-400"></i>
83
+ </div>
84
+ <h3 class="text-2xl font-bold text-white mb-4">Aplicativos Mobile</h3>
85
+ <p class="text-slate-400 leading-relaxed">
86
+ Apps nativos e multiplataforma para iOS e Android com experiência excepcional.
87
+ </p>
88
+ </div>
89
+
90
+ <!-- IA & Automação -->
91
+ <div class="glass-card p-8 rounded-2xl hover:scale-105 transition-transform">
92
+ <div class="w-16 h-16 bg-purple-500/20 rounded-2xl flex items-center justify-center mb-6">
93
+ <i data-lucide="brain" class="w-8 h-8 text-purple-400"></i>
94
+ </div>
95
+ <h3 class="text-2xl font-bold text-white mb-4">IA & Automação</h3>
96
+ <p class="text-slate-400 leading-relaxed">
97
+ Soluções de inteligência artificial e automação para otimizar processos.
98
+ </p>
99
+ </div>
100
+ </div>
keep-alive.js ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Keep-Alive Script for Render.com
2
+ // Prevents sleep mode by pinging health endpoint every 4 minutes
3
+
4
+ const https = require('https');
5
+ const http = require('http');
6
+
7
+ const SITE_URL = process.env.SITE_URL || 'https://softedge.onrender.com';
8
+ const HEALTH_ENDPOINT = '/health.php';
9
+ const INTERVAL_MINUTES = 4; // Ping every 4 minutes (under Render's 5-minute limit)
10
+
11
+ function pingHealthEndpoint() {
12
+ const url = new URL(HEALTH_ENDPOINT, SITE_URL);
13
+ const client = url.protocol === 'https:' ? https : http;
14
+
15
+ const options = {
16
+ hostname: url.hostname,
17
+ port: url.port,
18
+ path: url.pathname,
19
+ method: 'GET',
20
+ headers: {
21
+ 'User-Agent': 'SoftEdge-KeepAlive/1.0',
22
+ 'Accept': 'application/json'
23
+ }
24
+ };
25
+
26
+ const req = client.request(options, (res) => {
27
+ let data = '';
28
+
29
+ res.on('data', (chunk) => {
30
+ data += chunk;
31
+ });
32
+
33
+ res.on('end', () => {
34
+ try {
35
+ const health = JSON.parse(data);
36
+ console.log(`[${new Date().toISOString()}] Health check: ${health.status} - Uptime: ${health.uptime}s`);
37
+ } catch (e) {
38
+ console.log(`[${new Date().toISOString()}] Health check response received`);
39
+ }
40
+ });
41
+ });
42
+
43
+ req.on('error', (err) => {
44
+ console.error(`[${new Date().toISOString()}] Health check failed:`, err.message);
45
+ });
46
+
47
+ req.setTimeout(10000, () => {
48
+ req.destroy();
49
+ console.error(`[${new Date().toISOString()}] Health check timeout`);
50
+ });
51
+
52
+ req.end();
53
+ }
54
+
55
+ // Start the keep-alive process
56
+ console.log(`Starting SoftEdge Keep-Alive service`);
57
+ console.log(`Pinging ${SITE_URL}${HEALTH_ENDPOINT} every ${INTERVAL_MINUTES} minutes`);
58
+ console.log(`Press Ctrl+C to stop`);
59
+
60
+ // Initial ping
61
+ pingHealthEndpoint();
62
+
63
+ // Set up interval
64
+ const intervalMs = INTERVAL_MINUTES * 60 * 1000;
65
+ setInterval(pingHealthEndpoint, intervalMs);
66
+
67
+ // Handle graceful shutdown
68
+ process.on('SIGINT', () => {
69
+ console.log(`\n[${new Date().toISOString()}] SoftEdge Keep-Alive service stopped`);
70
+ process.exit(0);
71
+ });
72
+
73
+ process.on('SIGTERM', () => {
74
+ console.log(`\n[${new Date().toISOString()}] SoftEdge Keep-Alive service terminated`);
75
+ process.exit(0);
76
+ });
login.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <?php
2
+ // Redirect to Flask authentication
3
+ header('Location: /admin');
4
+ exit;
5
+ ?>
package.json ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "softedge-corporation",
3
+ "version": "2.0.0",
4
+ "description": "Website institucional da SoftEdge Corporation com integração React + PHP",
5
+ "main": "src/react/index.js",
6
+ "scripts": {
7
+ "start": "webpack serve --mode development --open",
8
+ "build": "webpack --mode production",
9
+ "dev": "webpack --mode development --watch",
10
+ "full-dev": "concurrently \"npm run dev\" \"cd .. && php -S localhost:8080\"",
11
+ "lint": "eslint src/react --ext .js,.jsx",
12
+ "test": "jest",
13
+ "analyze": "webpack-bundle-analyzer dist/static/js/*.js"
14
+ },
15
+ "keywords": [
16
+ "softedge",
17
+ "corporation",
18
+ "react",
19
+ "php",
20
+ "web-development",
21
+ "full-stack"
22
+ ],
23
+ "author": "SoftEdge Corporation",
24
+ "license": "MIT",
25
+ "dependencies": {
26
+ "react": "^18.2.0",
27
+ "react-dom": "^18.2.0",
28
+ "react-router-dom": "^6.8.0",
29
+ "axios": "^1.3.0",
30
+ "lucide-react": "^0.144.0",
31
+ "framer-motion": "^10.12.0",
32
+ "react-intersection-observer": "^9.5.0",
33
+ "react-helmet-async": "^1.3.0"
34
+ },
35
+ "devDependencies": {
36
+ "@babel/core": "^7.21.0",
37
+ "@babel/preset-env": "^7.20.0",
38
+ "@babel/preset-react": "^7.18.0",
39
+ "@babel/plugin-proposal-class-properties": "^7.18.0",
40
+ "@babel/plugin-proposal-object-rest-spread": "^7.20.0",
41
+ "babel-loader": "^9.1.0",
42
+ "webpack": "^5.75.0",
43
+ "webpack-cli": "^5.0.0",
44
+ "webpack-dev-server": "^4.11.0",
45
+ "html-webpack-plugin": "^5.5.0",
46
+ "mini-css-extract-plugin": "^2.7.0",
47
+ "css-loader": "^6.7.0",
48
+ "style-loader": "^3.3.0",
49
+ "postcss-loader": "^7.0.0",
50
+ "autoprefixer": "^10.4.0",
51
+ "cssnano": "^6.0.0",
52
+ "terser-webpack-plugin": "^5.3.0",
53
+ "css-minimizer-webpack-plugin": "^4.2.0",
54
+ "webpack-bundle-analyzer": "^4.7.0",
55
+ "concurrently": "^7.6.0",
56
+ "eslint": "^8.34.0",
57
+ "eslint-plugin-react": "^7.32.0",
58
+ "eslint-plugin-react-hooks": "^4.6.0",
59
+ "jest": "^29.4.0",
60
+ "@testing-library/react": "^13.4.0",
61
+ "@testing-library/jest-dom": "^5.16.0",
62
+ "postcss": "^8.4.0"
63
+ },
64
+ "browserslist": {
65
+ "production": [
66
+ ">0.2%",
67
+ "not dead",
68
+ "not op_mini all"
69
+ ],
70
+ "development": [
71
+ "last 1 chrome version",
72
+ "last 1 firefox version",
73
+ "last 1 safari version"
74
+ ]
75
+ },
76
+ "engines": {
77
+ "node": ">=16.0.0",
78
+ "npm": ">=8.0.0"
79
+ },
80
+ "repository": {
81
+ "type": "git",
82
+ "url": "https://github.com/akira40-soft/Softedge.git"
83
+ },
84
+ "homepage": "https://softedge-corporation.up.railway.app"
85
+ }
php.ini ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ; SoftEdge Corporation - PHP Configuration
2
+ ; This file contains PHP settings optimized for production
3
+
4
+ ; Error Handling
5
+ display_errors = Off
6
+ display_startup_errors = Off
7
+ error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
8
+ log_errors = On
9
+ error_log = /var/www/html/logs/php_errors.log
10
+
11
+ ; Performance
12
+ max_execution_time = 300
13
+ max_input_time = 60
14
+ memory_limit = 256M
15
+ post_max_size = 10M
16
+ upload_max_filesize = 10M
17
+ max_file_uploads = 20
18
+
19
+ ; Security
20
+ expose_php = Off
21
+ allow_url_fopen = On
22
+ allow_url_include = Off
23
+ disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
24
+ open_basedir = /var/www/html:/tmp
25
+
26
+ ; Sessions
27
+ session.save_path = /tmp
28
+ session.gc_probability = 1
29
+ session.gc_divisor = 1000
30
+ session.gc_maxlifetime = 1440
31
+ session.cookie_httponly = 1
32
+ session.cookie_secure = 1
33
+ session.use_only_cookies = 1
34
+ session.cookie_samesite = "Lax"
35
+
36
+ ; File Uploads
37
+ file_uploads = On
38
+ upload_tmp_dir = /tmp
39
+
40
+ ; Date/Time
41
+ date.timezone = "Africa/Luanda"
42
+
43
+ ; Mail
44
+ SMTP = localhost
45
+ smtp_port = 25
46
+ mail.add_x_header = On
47
+
48
+ ; Extensions
49
+ extension=mbstring
50
+ extension=exif
51
+ extension=pdo
52
+ extension=pdo_mysql
53
+ extension=gd
54
+ extension=zip
55
+ extension=xml
56
+ extension=curl
57
+ extension=intl
58
+ extension=bcmath
59
+
60
+ ; OPcache (if available)
61
+ opcache.enable=1
62
+ opcache.memory_consumption=256
63
+ opcache.max_accelerated_files=7963
64
+ opcache.revalidate_freq=0
65
+ opcache.validate_timestamps=0
66
+ opcache.consistency_checks=0
67
+ opcache.error_log=/var/www/html/logs/opcache.log
projetos.php ADDED
@@ -0,0 +1,444 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__ . '/src/Bootstrap.php';
3
+ \SoftEdge\Env::load(__DIR__);
4
+ \SoftEdge\Bootstrap::init();
5
+ include 'components/header.php';
6
+ ?>
7
+
8
+ <!-- HERO SECTION -->
9
+ <section class="relative pt-32 pb-20 overflow-hidden">
10
+ <!-- Background -->
11
+ <div class="absolute inset-0 -z-10">
12
+ <div class="absolute inset-0 bg-linear-to-br from-slate-950 via-slate-900 to-slate-950"></div>
13
+ <div class="absolute inset-0 opacity-30">
14
+ <div class="absolute top-20 left-20 w-96 h-96 bg-purple-500/20 rounded-full blur-3xl"></div>
15
+ <div class="absolute bottom-20 right-20 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl"></div>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- Content -->
20
+ <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
21
+ <div class="space-y-6">
22
+ <div class="inline-block px-4 py-2 bg-purple-500/10 rounded-full border border-purple-500/20 mb-4">
23
+ <span class="text-purple-400 text-sm font-semibold uppercase tracking-wider">Portfolio</span>
24
+ </div>
25
+
26
+ <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold leading-tight">
27
+ Projetos que
28
+ <span class="block bg-linear-to-r from-cyan-400 via-blue-500 to-purple-500 bg-clip-text text-transparent">
29
+ transformam negócios
30
+ </span>
31
+ </h1>
32
+
33
+ <p class="text-base sm:text-lg md:text-xl text-gray-300 max-w-3xl mx-auto leading-relaxed">
34
+ Conheça algumas das soluções que desenvolvemos e que já estão transformando negócios reais.
35
+ </p>
36
+ </div>
37
+ </div>
38
+ </section>
39
+
40
+ <!-- MAIN CONTENT -->
41
+ <main class="relative py-20 lg:py-32">
42
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
43
+
44
+ <!-- PROJETO DESTAQUE: AKIRA IA -->
45
+ <div class="mb-20 lg:mb-32">
46
+ <div class="relative">
47
+ <div class="absolute inset-0 bg-linear-to-r from-purple-500/20 via-pink-500/20 to-cyan-500/20 rounded-3xl blur-3xl"></div>
48
+
49
+ <div class="relative bg-slate-900/80 backdrop-blur-xl border border-purple-500/30 rounded-3xl overflow-hidden">
50
+ <!-- Badge Destaque -->
51
+ <div class="absolute top-6 right-6 z-10 px-4 py-2 bg-purple-500 rounded-full border border-purple-400 shadow-lg">
52
+ <span class="text-white text-sm font-bold uppercase tracking-wider flex items-center gap-2">
53
+ <i data-lucide="star" class="w-4 h-4"></i>
54
+ Projeto Destaque
55
+ </span>
56
+ </div>
57
+
58
+ <div class="grid lg:grid-cols-2 gap-8 lg:gap-12 p-8 lg:p-12">
59
+
60
+ <!-- Left: Info -->
61
+ <div class="flex flex-col justify-center space-y-6">
62
+ <div>
63
+ <div class="inline-flex items-center gap-2 px-3 py-1 bg-purple-500/20 border border-purple-500/30 rounded-full mb-4">
64
+ <i data-lucide="brain" class="w-4 h-4 text-purple-400"></i>
65
+ <span class="text-purple-400 text-xs font-semibold uppercase">Inteligência Artificial</span>
66
+ </div>
67
+
68
+ <h2 class="text-3xl sm:text-4xl md:text-5xl font-bold text-white mb-4">
69
+ AKIRA IA
70
+ <span class="block text-2xl sm:text-3xl text-gray-400 mt-2">🇦🇴 100% Angolana</span>
71
+ </h2>
72
+ </div>
73
+
74
+ <p class="text-gray-300 text-lg leading-relaxed">
75
+ Uma inteligência artificial autônoma desenvolvida inteiramente pela SoftEdge, projetada para conversar naturalmente com usuários, entender contexto e fornecer respostas precisas e humanizadas.
76
+ </p>
77
+
78
+ <!-- Features -->
79
+ <div class="space-y-3">
80
+ <div class="flex items-start gap-3">
81
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-1"></i>
82
+ <span class="text-gray-300">Processamento de linguagem natural (NLP)</span>
83
+ </div>
84
+ <div class="flex items-start gap-3">
85
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-1"></i>
86
+ <span class="text-gray-300">Aprendizado contínuo com conversas</span>
87
+ </div>
88
+ <div class="flex items-start gap-3">
89
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-1"></i>
90
+ <span class="text-gray-300">Integração com WhatsApp e plataformas web</span>
91
+ </div>
92
+ <div class="flex items-start gap-3">
93
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-1"></i>
94
+ <span class="text-gray-300">Personalidade única e respostas contextualizadas</span>
95
+ </div>
96
+ </div>
97
+
98
+ <!-- Tech Stack -->
99
+ <div>
100
+ <p class="text-sm text-gray-400 mb-3 font-medium">Tecnologias:</p>
101
+ <div class="flex flex-wrap gap-2">
102
+ <span class="px-4 py-2 bg-purple-500/20 border border-purple-500/30 rounded-lg text-purple-400 text-sm font-medium">Python</span>
103
+ <span class="px-4 py-2 bg-pink-500/20 border border-pink-500/30 rounded-lg text-pink-400 text-sm font-medium">TensorFlow</span>
104
+ <span class="px-4 py-2 bg-cyan-500/20 border border-cyan-500/30 rounded-lg text-cyan-400 text-sm font-medium">OpenAI API</span>
105
+ <span class="px-4 py-2 bg-blue-500/20 border border-blue-500/30 rounded-lg text-blue-400 text-sm font-medium">FastAPI</span>
106
+ </div>
107
+ </div>
108
+ </div>
109
+
110
+ <!-- Right: Main Image -->
111
+ <div class="relative group">
112
+ <div class="absolute inset-0 bg-linear-to-br from-purple-500/30 to-pink-500/30 rounded-2xl blur-xl opacity-50 group-hover:opacity-100 transition-opacity"></div>
113
+ <div class="relative overflow-hidden rounded-2xl border border-white/10 shadow-2xl">
114
+ <img src="/assets/akira.jpg"
115
+ alt="AKIRA IA - Interface Principal"
116
+ class="w-full h-auto object-cover transition-transform duration-700 group-hover:scale-105">
117
+ <div class="absolute inset-0 bg-linear-to-t from-black/60 to-transparent"></div>
118
+ <div class="absolute bottom-4 left-4 right-4">
119
+ <p class="text-white font-semibold text-lg">Interface Principal da AKIRA</p>
120
+ <p class="text-gray-300 text-sm">Conversando com usuários em tempo real</p>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ </div>
125
+
126
+ <!-- Gallery Section -->
127
+ <div class="border-t border-white/10 p-8 lg:p-12 bg-black/20">
128
+ <h3 class="text-2xl font-bold text-white mb-6 flex items-center gap-3">
129
+ <i data-lucide="image" class="w-6 h-6 text-purple-400"></i>
130
+ Galeria de Conversas
131
+ </h3>
132
+
133
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
134
+ <!-- Gallery Image 1 -->
135
+ <div class="group relative overflow-hidden rounded-xl border border-white/10 hover:border-purple-500/50 transition-all cursor-pointer">
136
+ <img src="/assets/akira1.jpg"
137
+ alt="AKIRA IA - Conversa 1"
138
+ class="w-full h-48 object-cover transition-transform duration-500 group-hover:scale-110">
139
+ <div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
140
+ <i data-lucide="maximize-2" class="w-8 h-8 text-white"></i>
141
+ </div>
142
+ </div>
143
+
144
+ <!-- Gallery Image 2 -->
145
+ <div class="group relative overflow-hidden rounded-xl border border-white/10 hover:border-purple-500/50 transition-all cursor-pointer">
146
+ <img src="/assets/akira2.jpg"
147
+ alt="AKIRA IA - Conversa 2"
148
+ class="w-full h-48 object-cover transition-transform duration-500 group-hover:scale-110">
149
+ <div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
150
+ <i data-lucide="maximize-2" class="w-8 h-8 text-white"></i>
151
+ </div>
152
+ </div>
153
+
154
+ <!-- Gallery Image 3 -->
155
+ <div class="group relative overflow-hidden rounded-xl border border-white/10 hover:border-purple-500/50 transition-all cursor-pointer">
156
+ <img src="/assets/akira3.jpg"
157
+ alt="AKIRA IA - Conversa 3"
158
+ class="w-full h-48 object-cover transition-transform duration-500 group-hover:scale-110">
159
+ <div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
160
+ <i data-lucide="maximize-2" class="w-8 h-8 text-white"></i>
161
+ </div>
162
+ </div>
163
+
164
+ <!-- Gallery Image 4 -->
165
+ <div class="group relative overflow-hidden rounded-xl border border-white/10 hover:border-purple-500/50 transition-all cursor-pointer">
166
+ <img src="/assets/akira4.jpg"
167
+ alt="AKIRA IA - Conversa 4"
168
+ class="w-full h-48 object-cover transition-transform duration-500 group-hover:scale-110">
169
+ <div class="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
170
+ <i data-lucide="maximize-2" class="w-8 h-8 text-white"></i>
171
+ </div>
172
+ </div>
173
+ </div>
174
+
175
+ <p class="text-gray-400 text-sm mt-4 text-center italic">
176
+ Clique nas imagens para ampliar e ver detalhes das conversas
177
+ </p>
178
+ </div>
179
+ </div>
180
+ </div>
181
+ </div>
182
+
183
+ <!-- OUTROS PROJETOS -->
184
+ <div>
185
+ <div class="text-center mb-12 lg:mb-16">
186
+ <div class="inline-block px-4 py-2 bg-cyan-500/10 rounded-full border border-cyan-500/20 mb-4">
187
+ <span class="text-cyan-400 text-sm font-semibold uppercase tracking-wider">Mais Projetos</span>
188
+ </div>
189
+ <h2 class="text-3xl sm:text-4xl md:text-5xl font-bold text-white">
190
+ Outros projetos desenvolvidos
191
+ </h2>
192
+ </div>
193
+
194
+ <div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-6 lg:gap-8">
195
+
196
+ <!-- PROJETO 1: ERP -->
197
+ <div class="group relative">
198
+ <div class="absolute inset-0 bg-linear-to-br from-cyan-500/20 to-blue-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity"></div>
199
+ <div class="relative bg-linear-to-br from-cyan-600/20 to-blue-600/20 rounded-2xl overflow-hidden border border-white/10 hover:border-cyan-500/30 transition-all h-full">
200
+ <div class="p-8 h-80 flex flex-col justify-between">
201
+ <div>
202
+ <div class="w-14 h-14 bg-cyan-500/20 rounded-xl flex items-center justify-center mb-4">
203
+ <i data-lucide="layout-dashboard" class="w-7 h-7 text-cyan-400"></i>
204
+ </div>
205
+ <h3 class="text-2xl font-bold text-white mb-3">Gestão Total ERP</h3>
206
+ <p class="text-gray-300 leading-relaxed mb-4">
207
+ Sistema completo de gestão empresarial com controle financeiro, estoque e CRM integrado.
208
+ </p>
209
+ </div>
210
+
211
+ <div class="space-y-3">
212
+ <div class="flex flex-wrap gap-2">
213
+ <span class="px-3 py-1 bg-cyan-500/20 rounded-full text-cyan-400 text-xs font-medium">Laravel</span>
214
+ <span class="px-3 py-1 bg-blue-500/20 rounded-full text-blue-400 text-xs font-medium">Vue.js</span>
215
+ <span class="px-3 py-1 bg-purple-500/20 rounded-full text-purple-400 text-xs font-medium">MySQL</span>
216
+ </div>
217
+ <div class="flex items-center gap-2 text-gray-400 text-sm">
218
+ <i data-lucide="calendar" class="w-4 h-4"></i>
219
+ <span>Concluído em 2024</span>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+
226
+ <!-- PROJETO 2: E-commerce -->
227
+ <div class="group relative">
228
+ <div class="absolute inset-0 bg-linear-to-br from-purple-500/20 to-pink-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity"></div>
229
+ <div class="relative bg-linear-to-br from-purple-600/20 to-pink-600/20 rounded-2xl overflow-hidden border border-white/10 hover:border-purple-500/30 transition-all h-full">
230
+ <div class="p-8 h-80 flex flex-col justify-between">
231
+ <div>
232
+ <div class="w-14 h-14 bg-purple-500/20 rounded-xl flex items-center justify-center mb-4">
233
+ <i data-lucide="shopping-cart" class="w-7 h-7 text-purple-400"></i>
234
+ </div>
235
+ <h3 class="text-2xl font-bold text-white mb-3">ShopFast E-commerce</h3>
236
+ <p class="text-gray-300 leading-relaxed mb-4">
237
+ Plataforma de vendas online com checkout rápido, pagamentos integrados e painel administrativo completo.
238
+ </p>
239
+ </div>
240
+
241
+ <div class="space-y-3">
242
+ <div class="flex flex-wrap gap-2">
243
+ <span class="px-3 py-1 bg-purple-500/20 rounded-full text-purple-400 text-xs font-medium">Next.js</span>
244
+ <span class="px-3 py-1 bg-pink-500/20 rounded-full text-pink-400 text-xs font-medium">Stripe</span>
245
+ <span class="px-3 py-1 bg-green-500/20 rounded-full text-green-400 text-xs font-medium">Prisma</span>
246
+ </div>
247
+ <div class="flex items-center gap-2 text-gray-400 text-sm">
248
+ <i data-lucide="calendar" class="w-4 h-4"></i>
249
+ <span>Concluído em 2024</span>
250
+ </div>
251
+ </div>
252
+ </div>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- PROJETO 3: Dashboard Analytics -->
257
+ <div class="group relative">
258
+ <div class="absolute inset-0 bg-linear-to-br from-green-500/20 to-emerald-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity"></div>
259
+ <div class="relative bg-linear-to-br from-green-600/20 to-emerald-600/20 rounded-2xl overflow-hidden border border-white/10 hover:border-green-500/30 transition-all h-full">
260
+ <div class="p-8 h-80 flex flex-col justify-between">
261
+ <div>
262
+ <div class="w-14 h-14 bg-green-500/20 rounded-xl flex items-center justify-center mb-4">
263
+ <i data-lucide="bar-chart-3" class="w-7 h-7 text-green-400"></i>
264
+ </div>
265
+ <h3 class="text-2xl font-bold text-white mb-3">DataMind Analytics</h3>
266
+ <p class="text-gray-300 leading-relaxed mb-4">
267
+ Dashboard inteligente com análise em tempo real, previsões e insights automatizados para decisões estratégicas.
268
+ </p>
269
+ </div>
270
+
271
+ <div class="space-y-3">
272
+ <div class="flex flex-wrap gap-2">
273
+ <span class="px-3 py-1 bg-green-500/20 rounded-full text-green-400 text-xs font-medium">React</span>
274
+ <span class="px-3 py-1 bg-yellow-500/20 rounded-full text-yellow-400 text-xs font-medium">Python</span>
275
+ <span class="px-3 py-1 bg-red-500/20 rounded-full text-red-400 text-xs font-medium">Redis</span>
276
+ </div>
277
+ <div class="flex items-center gap-2 text-gray-400 text-sm">
278
+ <i data-lucide="calendar" class="w-4 h-4"></i>
279
+ <span>Concluído em 2024</span>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ </div>
284
+ </div>
285
+
286
+ <!-- PROJETO 4: App Mobile -->
287
+ <div class="group relative">
288
+ <div class="absolute inset-0 bg-linear-to-br from-orange-500/20 to-red-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity"></div>
289
+ <div class="relative bg-linear-to-br from-orange-600/20 to-red-600/20 rounded-2xl overflow-hidden border border-white/10 hover:border-orange-500/30 transition-all h-full">
290
+ <div class="p-8 h-80 flex flex-col justify-between">
291
+ <div>
292
+ <div class="w-14 h-14 bg-orange-500/20 rounded-xl flex items-center justify-center mb-4">
293
+ <i data-lucide="smartphone" class="w-7 h-7 text-orange-400"></i>
294
+ </div>
295
+ <h3 class="text-2xl font-bold text-white mb-3">ConnectPro Mobile</h3>
296
+ <p class="text-gray-300 leading-relaxed mb-4">
297
+ Aplicativo multiplataforma para iOS e Android com sincronização em nuvem e notificações em tempo real.
298
+ </p>
299
+ </div>
300
+
301
+ <div class="space-y-3">
302
+ <div class="flex flex-wrap gap-2">
303
+ <span class="px-3 py-1 bg-orange-500/20 rounded-full text-orange-400 text-xs font-medium">Flutter</span>
304
+ <span class="px-3 py-1 bg-blue-500/20 rounded-full text-blue-400 text-xs font-medium">Firebase</span>
305
+ </div>
306
+ <div class="flex items-center gap-2 text-gray-400 text-sm">
307
+ <i data-lucide="calendar" class="w-4 h-4"></i>
308
+ <span>Concluído em 2024</span>
309
+ </div>
310
+ </div>
311
+ </div>
312
+ </div>
313
+ </div>
314
+
315
+ <!-- PROJETO EM ANDAMENTO -->
316
+ <div class="sm:col-span-2 lg:col-span-2 group relative">
317
+ <div class="absolute inset-0 bg-linear-to-r from-blue-500/10 to-cyan-500/10 rounded-2xl blur-xl"></div>
318
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-2xl p-8 lg:p-12 text-center h-full flex flex-col justify-center">
319
+ <div class="w-16 h-16 bg-blue-500/20 rounded-full flex items-center justify-center mx-auto mb-6">
320
+ <i data-lucide="code-2" class="w-8 h-8 text-blue-400 animate-pulse"></i>
321
+ </div>
322
+ <h3 class="text-2xl sm:text-3xl font-bold text-white mb-4">
323
+ Mais projetos em desenvolvimento...
324
+ </h3>
325
+ <p class="text-gray-300 text-lg mb-6 max-w-xl mx-auto">
326
+ Estamos trabalhando em novas soluções inovadoras. Em breve, mais projetos serão adicionados ao nosso portfolio.
327
+ </p>
328
+ <div class="flex items-center justify-center gap-2 text-gray-400">
329
+ <i data-lucide="clock" class="w-5 h-5"></i>
330
+ <span>2025 - Em andamento</span>
331
+ </div>
332
+ </div>
333
+ </div>
334
+
335
+ </div>
336
+ </div>
337
+
338
+ <!-- CTA FINAL -->
339
+ <div class="text-center mt-20 lg:mt-32">
340
+ <div class="relative">
341
+ <div class="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 rounded-3xl blur-3xl"></div>
342
+
343
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-3xl p-8 lg:p-12">
344
+ <h2 class="text-3xl sm:text-4xl md:text-5xl font-bold text-white mb-6 leading-tight">
345
+ Quer ver seu projeto
346
+ <span class="block bg-linear-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
347
+ aqui no nosso portfolio?
348
+ </span>
349
+ </h2>
350
+
351
+ <p class="text-base sm:text-lg text-gray-300 max-w-2xl mx-auto mb-8 lg:mb-10">
352
+ Vamos criar algo incrível juntos. Entre em contato e transforme sua ideia em realidade.
353
+ </p>
354
+
355
+ <a href="feedback.php"
356
+ class="inline-flex items-center justify-center gap-3 bg-linear-to-r from-cyan-500 to-blue-600 text-white font-semibold text-lg px-10 py-4 rounded-full shadow-lg hover:shadow-cyan-500/50 hover:scale-105 transition-all duration-300 group">
357
+ Iniciar Meu Projeto
358
+ <i data-lucide="arrow-right" class="w-5 h-5 group-hover:translate-x-1 transition-transform"></i>
359
+ </a>
360
+ </div>
361
+ </div>
362
+ </div>
363
+
364
+ </div>
365
+ </main>
366
+
367
+ <?php include 'components/footer.php'; ?>
368
+
369
+ <!-- SCRIPTS -->
370
+ <script src="https://unpkg.com/lucide@latest"></script>
371
+ <script>
372
+ document.addEventListener('DOMContentLoaded', () => {
373
+ // Initialize Lucide icons
374
+ lucide.createIcons();
375
+
376
+ // Fade in animations on scroll
377
+ const observerOptions = {
378
+ threshold: 0.1,
379
+ rootMargin: '0px 0px -50px 0px'
380
+ };
381
+
382
+ const observer = new IntersectionObserver((entries) => {
383
+ entries.forEach(entry => {
384
+ if (entry.isIntersecting) {
385
+ entry.target.style.opacity = '1';
386
+ entry.target.style.transform = 'translateY(0)';
387
+ }
388
+ });
389
+ }, observerOptions);
390
+
391
+ // Observe all project cards
392
+ document.querySelectorAll('.group, section').forEach((el, index) => {
393
+ el.style.opacity = '0';
394
+ el.style.transform = 'translateY(20px)';
395
+ el.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`;
396
+ observer.observe(el);
397
+ });
398
+
399
+ // Gallery lightbox effect (opcional)
400
+ document.querySelectorAll('[src*="akira"]').forEach(img => {
401
+ img.addEventListener('click', function() {
402
+ // Aqui você pode adicionar um lightbox modal se quiser
403
+ console.log('Imagem clicada:', this.src);
404
+ });
405
+ });
406
+ });
407
+ </script>
408
+
409
+ <style>
410
+ /* Gradient animation */
411
+ @keyframes gradient-shift {
412
+ 0%, 100% {
413
+ background-position: 0% 50%;
414
+ }
415
+ 50% {
416
+ background-position: 100% 50%;
417
+ }
418
+ }
419
+
420
+ .bg-linear-to-r,
421
+ .bg-linear-to-br {
422
+ background-size: 200% 200%;
423
+ animation: gradient-shift 8s ease infinite;
424
+ }
425
+
426
+ /* Image hover effects */
427
+ img {
428
+ will-change: transform;
429
+ }
430
+
431
+ /* Pulse animation for "em desenvolvimento" */
432
+ @keyframes pulse {
433
+ 0%, 100% {
434
+ opacity: 1;
435
+ }
436
+ 50% {
437
+ opacity: 0.5;
438
+ }
439
+ }
440
+
441
+ .animate-pulse {
442
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
443
+ }
444
+ </style>
react-demo.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__ . '/src/Bootstrap.php';
3
+ \SoftEdge\Env::load(__DIR__);
4
+ \SoftEdge\Bootstrap::init();
5
+ include 'components/header.php';
6
+ ?>
7
+
8
+ <!-- REACT DEMO PAGE -->
9
+ <section class="relative min-h-screen flex items-center justify-center overflow-hidden">
10
+ <!-- Background -->
11
+ <div class="absolute inset-0 -z-10">
12
+ <div class="absolute inset-0 bg-linear-to-br from-slate-950 via-slate-900 to-slate-950"></div>
13
+ <div class="absolute inset-0 opacity-30">
14
+ <div class="absolute top-20 left-20 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl"></div>
15
+ <div class="absolute bottom-20 right-20 w-96 h-96 bg-blue-500/20 rounded-full blur-3xl"></div>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- Content -->
20
+ <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-20">
21
+ <div class="text-center space-y-12">
22
+
23
+ <!-- Badge -->
24
+ <div class="inline-block px-4 py-2 bg-cyan-500/10 rounded-full border border-cyan-500/20 backdrop-blur-sm">
25
+ <span class="text-cyan-400 text-sm font-semibold uppercase tracking-wider">
26
+ ⚛️ React Integration Demo
27
+ </span>
28
+ </div>
29
+
30
+ <!-- Title -->
31
+ <div class="space-y-6">
32
+ <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold leading-tight">
33
+ <span class="block text-white mb-2">React + PHP</span>
34
+ <span class="block bg-linear-to-r from-cyan-400 via-blue-500 to-purple-500 bg-clip-text text-transparent">
35
+ Integração Completa
36
+ </span>
37
+ </h1>
38
+
39
+ <p class="text-base sm:text-lg md:text-xl text-gray-300 max-w-2xl mx-auto leading-relaxed">
40
+ Demonstração da integração perfeita entre React e PHP no SoftEdge Corporation website.
41
+ <br class="hidden sm:block">
42
+ Componentes modulares, estado compartilhado e performance otimizada.
43
+ </p>
44
+ </div>
45
+
46
+ <!-- React App Container -->
47
+ <div class="max-w-4xl mx-auto">
48
+ <div class="relative">
49
+ <div class="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 rounded-3xl blur-3xl"></div>
50
+
51
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-3xl p-8">
52
+ <!-- React App will be mounted here -->
53
+ <div id="root" class="min-h-[400px] flex items-center justify-center">
54
+ <div class="text-center space-y-4">
55
+ <div class="w-16 h-16 bg-cyan-500/20 rounded-full flex items-center justify-center mx-auto animate-pulse">
56
+ <i data-lucide="loader-2" class="w-8 h-8 text-cyan-400 animate-spin"></i>
57
+ </div>
58
+ <p class="text-gray-400">Carregando aplicação React...</p>
59
+ </div>
60
+ </div>
61
+
62
+ <!-- Fallback for when React is not loaded -->
63
+ <noscript>
64
+ <div class="text-center py-8">
65
+ <i data-lucide="alert-triangle" class="w-16 h-16 text-yellow-400 mx-auto mb-4"></i>
66
+ <h3 class="text-xl font-bold text-white mb-2">JavaScript Necessário</h3>
67
+ <p class="text-gray-400">Esta página requer JavaScript para funcionar corretamente.</p>
68
+ </div>
69
+ </noscript>
70
+ </div>
71
+ </div>
72
+ </div>
73
+
74
+ <!-- Info Cards -->
75
+ <div class="grid sm:grid-cols-3 gap-6 lg:gap-8 mt-16 max-w-4xl mx-auto">
76
+ <!-- Info 1 -->
77
+ <div class="text-center">
78
+ <div class="w-12 h-12 bg-cyan-500/10 rounded-xl flex items-center justify-center mx-auto mb-4">
79
+ <i data-lucide="zap" class="w-6 h-6 text-cyan-400"></i>
80
+ </div>
81
+ <h3 class="text-white font-semibold mb-2">Performance</h3>
82
+ <p class="text-gray-400 text-sm">Componentes otimizados com lazy loading</p>
83
+ </div>
84
+
85
+ <!-- Info 2 -->
86
+ <div class="text-center">
87
+ <div class="w-12 h-12 bg-blue-500/10 rounded-xl flex items-center justify-center mx-auto mb-4">
88
+ <i data-lucide="code-2" class="w-6 h-6 text-blue-400"></i>
89
+ </div>
90
+ <h3 class="text-white font-semibold mb-2">Modular</h3>
91
+ <p class="text-gray-400 text-sm">Componentes reutilizáveis e manuteníveis</p>
92
+ </div>
93
+
94
+ <!-- Info 3 -->
95
+ <div class="text-center">
96
+ <div class="w-12 h-12 bg-purple-500/10 rounded-xl flex items-center justify-center mx-auto mb-4">
97
+ <i data-lucide="refresh-cw" class="w-6 h-6 text-purple-400"></i>
98
+ </div>
99
+ <h3 class="text-white font-semibold mb-2">Dinâmico</h3>
100
+ <p class="text-gray-400 text-sm">Estado reativo e interações fluidas</p>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Back to Home -->
105
+ <div class="pt-12">
106
+ <a href="index.php" class="inline-flex items-center gap-2 text-cyan-400 hover:text-cyan-300 transition-colors group">
107
+ <i data-lucide="arrow-left" class="w-5 h-5 group-hover:-translate-x-1 transition-transform"></i>
108
+ <span>Voltar ao início</span>
109
+ </a>
110
+ </div>
111
+
112
+ </div>
113
+ </div>
114
+ </section>
115
+
116
+ <!-- Load React App -->
117
+ <script>
118
+ // Load React app when DOM is ready
119
+ document.addEventListener('DOMContentLoaded', function() {
120
+ // Check if React bundle exists
121
+ fetch('/dist/main.js')
122
+ .then(response => {
123
+ if (response.ok) {
124
+ // Load React bundle
125
+ const script = document.createElement('script');
126
+ script.src = '/dist/main.js';
127
+ script.onload = function() {
128
+ console.log('React app loaded successfully');
129
+ };
130
+ script.onerror = function() {
131
+ console.error('Failed to load React app');
132
+ showFallback();
133
+ };
134
+ document.head.appendChild(script);
135
+ } else {
136
+ console.warn('React bundle not found, showing fallback');
137
+ showFallback();
138
+ }
139
+ })
140
+ .catch(error => {
141
+ console.error('Error checking React bundle:', error);
142
+ showFallback();
143
+ });
144
+ });
145
+
146
+ function showFallback() {
147
+ const root = document.getElementById('root');
148
+ if (root) {
149
+ root.innerHTML = `
150
+ <div class="text-center space-y-4">
151
+ <div class="w-16 h-16 bg-yellow-500/20 rounded-full flex items-center justify-center mx-auto">
152
+ <i data-lucide="alert-triangle" class="w-8 h-8 text-yellow-400"></i>
153
+ </div>
154
+ <h3 class="text-xl font-bold text-white">React App Indisponível</h3>
155
+ <p class="text-gray-400 text-sm">O aplicativo React não foi carregado. Execute <code class="bg-slate-800 px-2 py-1 rounded text-xs">npm run build</code> para gerar os arquivos.</p>
156
+ </div>
157
+ `;
158
+ }
159
+ }
160
+ </script>
161
+
162
+ <?php include 'components/footer.php'; ?>
163
+
164
+ <!-- SCRIPTS -->
165
+ <script src="https://unpkg.com/lucide@latest"></script>
166
+ <script>
167
+ document.addEventListener('DOMContentLoaded', () => {
168
+ // Initialize Lucide icons
169
+ lucide.createIcons();
170
+ });
171
+ </script>
172
+
173
+ <style>
174
+ /* Custom styles for React integration */
175
+ #root {
176
+ transition: opacity 0.3s ease;
177
+ }
178
+
179
+ #root.fade-in {
180
+ opacity: 1;
181
+ }
182
+
183
+ /* Loading animation */
184
+ @keyframes spin {
185
+ from { transform: rotate(0deg); }
186
+ to { transform: rotate(360deg); }
187
+ }
188
+
189
+ .animate-spin {
190
+ animation: spin 1s linear infinite;
191
+ }
192
+
193
+ /* Gradient animation */
194
+ @keyframes gradient-shift {
195
+ 0%, 100% {
196
+ background-position: 0% 50%;
197
+ }
198
+ 50% {
199
+ background-position: 100% 50%;
200
+ }
201
+ }
202
+
203
+ .bg-linear-to-r {
204
+ background-size: 200% 200%;
205
+ animation: gradient-shift 8s ease infinite;
206
+ }
207
+ </style>
react-fallback.html ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SoftEdge Corporation - React Fallback</title>
7
+ <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
8
+ <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
9
+ <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
10
+ <style>
11
+ body {
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ margin: 0;
14
+ padding: 20px;
15
+ background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
16
+ color: white;
17
+ min-height: 100vh;
18
+ }
19
+ .container {
20
+ max-width: 800px;
21
+ margin: 0 auto;
22
+ background: rgba(30, 41, 59, 0.8);
23
+ border-radius: 12px;
24
+ padding: 30px;
25
+ backdrop-filter: blur(10px);
26
+ border: 1px solid rgba(148, 163, 184, 0.1);
27
+ }
28
+ .header {
29
+ text-align: center;
30
+ margin-bottom: 30px;
31
+ }
32
+ .nav {
33
+ display: flex;
34
+ gap: 10px;
35
+ margin-bottom: 20px;
36
+ flex-wrap: wrap;
37
+ }
38
+ .nav-btn {
39
+ padding: 8px 16px;
40
+ background: rgba(6, 182, 212, 0.1);
41
+ border: 1px solid rgba(6, 182, 212, 0.3);
42
+ border-radius: 6px;
43
+ color: #06b6d4;
44
+ cursor: pointer;
45
+ transition: all 0.3s ease;
46
+ }
47
+ .nav-btn.active {
48
+ background: #06b6d4;
49
+ color: white;
50
+ }
51
+ .content {
52
+ background: rgba(15, 23, 42, 0.5);
53
+ border-radius: 8px;
54
+ padding: 20px;
55
+ min-height: 200px;
56
+ }
57
+ .feature-grid {
58
+ display: grid;
59
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
60
+ gap: 20px;
61
+ margin-top: 20px;
62
+ }
63
+ .feature-card {
64
+ background: rgba(30, 41, 59, 0.6);
65
+ padding: 20px;
66
+ border-radius: 8px;
67
+ border: 1px solid rgba(148, 163, 184, 0.1);
68
+ text-align: center;
69
+ }
70
+ .feature-card h3 {
71
+ color: #06b6d4;
72
+ margin-bottom: 10px;
73
+ }
74
+ </style>
75
+ </head>
76
+ <body>
77
+ <div id="root"></div>
78
+
79
+ <script type="text/babel">
80
+ const { useState, useEffect } = React;
81
+
82
+ function App() {
83
+ const [currentSection, setCurrentSection] = useState('home');
84
+ const [isVisible, setIsVisible] = useState(false);
85
+
86
+ useEffect(() => {
87
+ setTimeout(() => setIsVisible(true), 100);
88
+ }, []);
89
+
90
+ const sections = [
91
+ { id: 'home', label: 'Início', icon: '🏠' },
92
+ { id: 'services', label: 'Serviços', icon: '⚙️' },
93
+ { id: 'projects', label: 'Projetos', icon: '📁' },
94
+ { id: 'about', label: 'Sobre', icon: '👥' },
95
+ { id: 'contact', label: 'Contato', icon: '📧' }
96
+ ];
97
+
98
+ const renderContent = () => {
99
+ switch (currentSection) {
100
+ case 'home':
101
+ return (
102
+ <div>
103
+ <h2>🚀 Bem-vindo à SoftEdge Corporation</h2>
104
+ <p>Transformamos ideias em soluções digitais inovadoras.</p>
105
+ <div className="feature-grid">
106
+ <div className="feature-card">
107
+ <h3>⚡ Performance</h3>
108
+ <p>Soluções otimizadas para máxima velocidade</p>
109
+ </div>
110
+ <div className="feature-card">
111
+ <h3>🔒 Segurança</h3>
112
+ <p>Proteção avançada e melhores práticas</p>
113
+ </div>
114
+ <div className="feature-card">
115
+ <h3>📱 Responsivo</h3>
116
+ <p>Experiência perfeita em todos os dispositivos</p>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ );
121
+
122
+ case 'services':
123
+ return (
124
+ <div>
125
+ <h2>💼 Nossos Serviços</h2>
126
+ <div className="feature-grid">
127
+ <div className="feature-card">
128
+ <h3>💻 Desenvolvimento Web</h3>
129
+ <p>Sites, sistemas e aplicações web modernas</p>
130
+ </div>
131
+ <div className="feature-card">
132
+ <h3>📱 Apps Mobile</h3>
133
+ <p>Aplicativos nativos e híbridos</p>
134
+ </div>
135
+ <div className="feature-card">
136
+ <h3>🤖 IA & Automação</h3>
137
+ <p>Inteligência artificial e processos automatizados</p>
138
+ </div>
139
+ <div className="feature-card">
140
+ <h3>☁️ Cloud Solutions</h3>
141
+ <p>Migração e otimização para nuvem</p>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ );
146
+
147
+ case 'projects':
148
+ return (
149
+ <div>
150
+ <h2>📂 Nossos Projetos</h2>
151
+ <div className="feature-grid">
152
+ <div className="feature-card">
153
+ <h3>AKIRA IA</h3>
154
+ <p>Assistente virtual inteligente</p>
155
+ <div style={{marginTop: '10px'}}>
156
+ <span style={{background: 'rgba(6, 182, 212, 0.2)', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', color: '#06b6d4'}}>Python</span>
157
+ <span style={{background: 'rgba(168, 85, 247, 0.2)', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', color: '#a855f7', marginLeft: '5px'}}>TensorFlow</span>
158
+ </div>
159
+ </div>
160
+ <div className="feature-card">
161
+ <h3>ERP Gestão Total</h3>
162
+ <p>Sistema completo de gestão empresarial</p>
163
+ <div style={{marginTop: '10px'}}>
164
+ <span style={{background: 'rgba(239, 68, 68, 0.2)', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', color: '#ef4444'}}>Laravel</span>
165
+ <span style={{background: 'rgba(59, 130, 246, 0.2)', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', color: '#3b82f6', marginLeft: '5px'}}>Vue.js</span>
166
+ </div>
167
+ </div>
168
+ <div className="feature-card">
169
+ <h3>E-commerce ShopFast</h3>
170
+ <p>Plataforma de vendas online</p>
171
+ <div style={{marginTop: '10px'}}>
172
+ <span style={{background: 'rgba(0, 0, 0, 0.2)', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', color: '#ffffff'}}>Next.js</span>
173
+ <span style={{background: 'rgba(139, 92, 246, 0.2)', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', color: '#8b5cf6', marginLeft: '5px'}}>Stripe</span>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </div>
178
+ );
179
+
180
+ case 'about':
181
+ return (
182
+ <div>
183
+ <h2>👥 Sobre Nós</h2>
184
+ <p>Somos uma equipe apaixonada por tecnologia, criando soluções inovadoras desde 2023.</p>
185
+ <div style={{marginTop: '20px'}}>
186
+ <h3 style={{color: '#06b6d4', marginBottom: '15px'}}>Nossa Equipe</h3>
187
+ <div style={{display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))', gap: '15px'}}>
188
+ <div style={{textAlign: 'center'}}>
189
+ <div style={{width: '50px', height: '50px', background: 'rgba(6, 182, 212, 0.2)', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 10px', fontSize: '20px'}}>I</div>
190
+ <div><strong>Isaac Quarenta</strong></div>
191
+ <div style={{fontSize: '14px', color: '#94a3b8'}}>CEO & Developer</div>
192
+ </div>
193
+ <div style={{textAlign: 'center'}}>
194
+ <div style={{width: '50px', height: '50px', background: 'rgba(168, 85, 247, 0.2)', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 10px', fontSize: '20px'}}>J</div>
195
+ <div><strong>José Lopes</strong></div>
196
+ <div style={{fontSize: '14px', color: '#94a3b8'}}>Full Stack Dev</div>
197
+ </div>
198
+ <div style={{textAlign: 'center'}}>
199
+ <div style={{width: '50px', height: '50px', background: 'rgba(236, 72, 153, 0.2)', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 10px', fontSize: '20px'}}>S</div>
200
+ <div><strong>Stefânio Costa</strong></div>
201
+ <div style={{fontSize: '14px', color: '#94a3b8'}}>Designer & Frontend</div>
202
+ </div>
203
+ <div style={{textAlign: 'center'}}>
204
+ <div style={{width: '50px', height: '50px', background: 'rgba(34, 197, 94, 0.2)', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 10px', fontSize: '20px'}}>T</div>
205
+ <div><strong>Tiago Rodrigues</strong></div>
206
+ <div style={{fontSize: '14px', color: '#94a3b8'}}>DevOps & Backend</div>
207
+ </div>
208
+ </div>
209
+ </div>
210
+ </div>
211
+ );
212
+
213
+ case 'contact':
214
+ return (
215
+ <div>
216
+ <h2>📧 Entre em Contato</h2>
217
+ <p>Estamos prontos para transformar sua ideia em realidade!</p>
218
+ <div style={{marginTop: '20px', display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '20px'}}>
219
+ <div style={{background: 'rgba(6, 182, 212, 0.1)', padding: '20px', borderRadius: '8px', border: '1px solid rgba(6, 182, 212, 0.2)'}}>
220
+ <h3 style={{color: '#06b6d4', marginBottom: '10px'}}>💬 WhatsApp</h3>
221
+ <p style={{fontSize: '14px', color: '#94a3b8'}}>Converse conosco em tempo real</p>
222
+ <a href="https://whatsapp.com/channel/0029VawQLpGHltY2Y87fR83m" target="_blank" style={{color: '#06b6d4', textDecoration: 'none'}}>Entrar no canal →</a>
223
+ </div>
224
+ <div style={{background: 'rgba(168, 85, 247, 0.1)', padding: '20px', borderRadius: '8px', border: '1px solid rgba(168, 85, 247, 0.2)'}}>
225
+ <h3 style={{color: '#a855f7', marginBottom: '10px'}}>📧 Email</h3>
226
+ <p style={{fontSize: '14px', color: '#94a3b8'}}>Envie-nos uma mensagem</p>
227
+ <a href="mailto:softedgecorporation@gmail.com" style={{color: '#a855f7', textDecoration: 'none'}}>Enviar email →</a>
228
+ </div>
229
+ </div>
230
+ </div>
231
+ );
232
+
233
+ default:
234
+ return <div><h2>Seção não encontrada</h2></div>;
235
+ }
236
+ };
237
+
238
+ return (
239
+ <div className={`app ${isVisible ? 'visible' : ''}`} style={{opacity: isVisible ? 1 : 0, transition: 'opacity 0.5s ease'}}>
240
+ <div className="container">
241
+ <div className="header">
242
+ <h1 style={{color: '#06b6d4', marginBottom: '10px'}}>🚀 SoftEdge Corporation</h1>
243
+ <p style={{color: '#94a3b8'}}>React + PHP Integration Demo</p>
244
+ </div>
245
+
246
+ <nav className="nav">
247
+ {sections.map(section => (
248
+ <button
249
+ key={section.id}
250
+ className={`nav-btn ${currentSection === section.id ? 'active' : ''}`}
251
+ onClick={() => setCurrentSection(section.id)}
252
+ >
253
+ <span style={{marginRight: '5px'}}>{section.icon}</span>
254
+ {section.label}
255
+ </button>
256
+ ))}
257
+ </nav>
258
+
259
+ <div className="content">
260
+ {renderContent()}
261
+ </div>
262
+
263
+ <div style={{textAlign: 'center', marginTop: '30px', paddingTop: '20px', borderTop: '1px solid rgba(148, 163, 184, 0.1)'}}>
264
+ <p style={{color: '#94a3b8', fontSize: '14px'}}>
265
+ React + PHP = 💪 Potência Total • SoftEdge Corporation 2025
266
+ </p>
267
+ </div>
268
+ </div>
269
+ </div>
270
+ );
271
+ }
272
+
273
+ const root = ReactDOM.createRoot(document.getElementById('root'));
274
+ root.render(<App />);
275
+ </script>
276
+ </body>
277
+ </html>
register.php ADDED
File without changes
render.yaml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ services:
2
+ - type: web
3
+ name: softedge-corporation
4
+ runtime: docker
5
+ dockerfilePath: ./Dockerfile
6
+ healthCheckPath: /health.php
7
+ envVars:
8
+ - key: PORT
9
+ value: 10000
10
+ - key: RENDER
11
+ value: true
12
+ plan: starter
13
+ autoDeploy: true
14
+ buildFilter:
15
+ paths:
16
+ - "**"
17
+ ignoredPaths:
18
+ - "logs/**"
19
+ - ".git/**"
20
+ - "README.md"
21
+ - "*.md"
22
+ disk:
23
+ name: softedge-data
24
+ mountPath: /var/www/html/logs
25
+ sizeGB: 1
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Flask==2.3.3
2
+ Werkzeug==2.3.7
3
+ gunicorn==21.2.0
4
+ requests==2.31.0
servicos.php ADDED
@@ -0,0 +1,388 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__ . '/src/Bootstrap.php';
3
+ \SoftEdge\Env::load(__DIR__);
4
+ \SoftEdge\Bootstrap::init();
5
+ include 'components/header.php';
6
+ ?>
7
+
8
+ <!-- HERO SECTION -->
9
+ <section class="relative pt-32 pb-20 overflow-hidden">
10
+ <!-- Background -->
11
+ <div class="absolute inset-0 -z-10">
12
+ <div class="absolute inset-0 bg-linear-to-br from-slate-950 via-slate-900 to-slate-950"></div>
13
+ <div class="absolute inset-0 opacity-30">
14
+ <div class="absolute top-20 left-20 w-96 h-96 bg-purple-500/20 rounded-full blur-3xl"></div>
15
+ <div class="absolute bottom-20 right-20 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl"></div>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- Content -->
20
+ <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
21
+ <div class="space-y-6">
22
+ <div class="inline-block px-4 py-2 bg-slate-700 border border-slate-600 mb-4">
23
+ <span class="text-slate-300 text-sm font-medium uppercase tracking-wide">Nossos Serviços</span>
24
+ </div>
25
+
26
+ <h1 class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold leading-tight">
27
+ Transformamos suas ideias em
28
+ <span class="block text-slate-300">
29
+ soluções digitais
30
+ </span>
31
+ </h1>
32
+
33
+ <p class="text-base sm:text-lg md:text-xl text-slate-400 max-w-3xl mx-auto leading-relaxed">
34
+ Da consultoria ao desenvolvimento completo, oferecemos tudo o que você precisa para ter sucesso no mundo digital.
35
+ </p>
36
+ </div>
37
+ </div>
38
+ </section>
39
+
40
+ <!-- SERVIÇOS GRID -->
41
+ <main class="relative py-20 lg:py-32">
42
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
43
+
44
+ <div class="grid sm:grid-cols-2 lg:grid-cols-2 gap-6 lg:gap-8">
45
+
46
+ <!-- SERVIÇO 1 - DESENVOLVIMENTO FULL STACK -->
47
+ <div class="group relative">
48
+ <div class="absolute inset-0 bg-linear-to-br from-cyan-500/20 to-blue-500/20 rounded-3xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
49
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-3xl p-8 lg:p-10 transition-all duration-500 hover:border-cyan-500/30 h-full flex flex-col">
50
+
51
+ <!-- Icon -->
52
+ <div class="w-16 h-16 bg-linear-to-br from-cyan-500 to-blue-600 rounded-2xl flex items-center justify-center mb-6 shadow-lg group-hover:scale-110 transition-transform">
53
+ <i data-lucide="code-2" class="w-8 h-8 text-white"></i>
54
+ </div>
55
+
56
+ <!-- Title -->
57
+ <h3 class="text-2xl sm:text-3xl font-bold text-white mb-4">
58
+ Desenvolvimento Full Stack
59
+ </h3>
60
+
61
+ <!-- Description -->
62
+ <p class="text-gray-300 text-base leading-relaxed mb-6 grow">
63
+ Criamos aplicações web, mobile e desktop personalizadas para o seu negócio. Utilizamos as tecnologias mais modernas como React, Next.js, Node.js, Laravel, Flutter, PHP 8+, bancos SQL/NoSQL e muito mais.
64
+ </p>
65
+
66
+ <!-- Features List -->
67
+ <ul class="space-y-3">
68
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
69
+ <i data-lucide="check-circle" class="w-5 h-5 text-cyan-400 shrink-0 mt-0.5"></i>
70
+ <span>APIs REST & GraphQL profissionais</span>
71
+ </li>
72
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
73
+ <i data-lucide="check-circle" class="w-5 h-5 text-cyan-400 shrink-0 mt-0.5"></i>
74
+ <span>Progressive Web Apps (PWA) rápidos</span>
75
+ </li>
76
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
77
+ <i data-lucide="check-circle" class="w-5 h-5 text-cyan-400 shrink-0 mt-0.5"></i>
78
+ <span>Integração com serviços externos</span>
79
+ </li>
80
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
81
+ <i data-lucide="check-circle" class="w-5 h-5 text-cyan-400 shrink-0 mt-0.5"></i>
82
+ <span>Deploy automático e escalável</span>
83
+ </li>
84
+ </ul>
85
+ </div>
86
+ </div>
87
+
88
+ <!-- SERVIÇO 2 - SISTEMAS SOB MEDIDA -->
89
+ <div class="group relative">
90
+ <div class="absolute inset-0 bg-linear-to-br from-purple-500/20 to-pink-500/20 rounded-3xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
91
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-3xl p-8 lg:p-10 transition-all duration-500 hover:border-purple-500/30 h-full flex flex-col">
92
+
93
+ <!-- Icon -->
94
+ <div class="w-16 h-16 bg-linear-to-br from-purple-500 to-pink-600 rounded-2xl flex items-center justify-center mb-6 shadow-lg group-hover:scale-110 transition-transform">
95
+ <i data-lucide="layout-dashboard" class="w-8 h-8 text-white"></i>
96
+ </div>
97
+
98
+ <!-- Title -->
99
+ <h3 class="text-2xl sm:text-3xl font-bold text-white mb-4">
100
+ Sistemas Sob Medida
101
+ </h3>
102
+
103
+ <!-- Description -->
104
+ <p class="text-gray-300 text-base leading-relaxed mb-6 grow">
105
+ Desenvolvemos ERPs, CRMs, sistemas de gestão financeira, controle de estoque, portais internos e dashboards analíticos 100% personalizados para atender às necessidades específicas do seu negócio.
106
+ </p>
107
+
108
+ <!-- Features List -->
109
+ <ul class="space-y-3">
110
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
111
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-0.5"></i>
112
+ <span>Totalmente escalável e flexível</span>
113
+ </li>
114
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
115
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-0.5"></i>
116
+ <span>Multiplataforma (web + mobile + desktop)</span>
117
+ </li>
118
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
119
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-0.5"></i>
120
+ <span>Integração com ferramentas existentes</span>
121
+ </li>
122
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
123
+ <i data-lucide="check-circle" class="w-5 h-5 text-purple-400 shrink-0 mt-0.5"></i>
124
+ <span>Suporte técnico 24/7 incluído</span>
125
+ </li>
126
+ </ul>
127
+ </div>
128
+ </div>
129
+
130
+ <!-- SERVIÇO 3 - CONSULTORIA & PERFORMANCE -->
131
+ <div class="group relative">
132
+ <div class="absolute inset-0 bg-linear-to-br from-green-500/20 to-emerald-500/20 rounded-3xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
133
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-3xl p-8 lg:p-10 transition-all duration-500 hover:border-green-500/30 h-full flex flex-col">
134
+
135
+ <!-- Icon -->
136
+ <div class="w-16 h-16 bg-linear-to-br from-green-500 to-emerald-600 rounded-2xl flex items-center justify-center mb-6 shadow-lg group-hover:scale-110 transition-transform">
137
+ <i data-lucide="zap" class="w-8 h-8 text-white"></i>
138
+ </div>
139
+
140
+ <!-- Title -->
141
+ <h3 class="text-2xl sm:text-3xl font-bold text-white mb-4">
142
+ Consultoria & Performance
143
+ </h3>
144
+
145
+ <!-- Description -->
146
+ <p class="text-gray-300 text-base leading-relaxed mb-6 grow">
147
+ Realizamos auditoria técnica completa, otimização de velocidade (Core Web Vitals 100), SEO técnico, migração para cloud e modernização de sistemas legados para melhorar a performance do seu negócio.
148
+ </p>
149
+
150
+ <!-- Features List -->
151
+ <ul class="space-y-3">
152
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
153
+ <i data-lucide="check-circle" class="w-5 h-5 text-green-400 shrink-0 mt-0.5"></i>
154
+ <span>Score +95 no Google Lighthouse</span>
155
+ </li>
156
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
157
+ <i data-lucide="check-circle" class="w-5 h-5 text-green-400 shrink-0 mt-0.5"></i>
158
+ <span>Redução significativa de custos de servidor</span>
159
+ </li>
160
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
161
+ <i data-lucide="check-circle" class="w-5 h-5 text-green-400 shrink-0 mt-0.5"></i>
162
+ <span>Estratégia digital completa e assertiva</span>
163
+ </li>
164
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
165
+ <i data-lucide="check-circle" class="w-5 h-5 text-green-400 shrink-0 mt-0.5"></i>
166
+ <span>Treinamento personalizado para sua equipe</span>
167
+ </li>
168
+ </ul>
169
+ </div>
170
+ </div>
171
+
172
+ <!-- SERVIÇO 4 - IA E AUTOMAÇÃO (NOVO!) -->
173
+ <div class="group relative">
174
+ <div class="absolute inset-0 bg-linear-to-br from-orange-500/20 to-red-500/20 rounded-3xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
175
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-3xl p-8 lg:p-10 transition-all duration-500 hover:border-orange-500/30 h-full flex flex-col">
176
+
177
+ <!-- Icon + Badge -->
178
+ <div class="flex items-center gap-3 mb-6">
179
+ <div class="w-16 h-16 bg-linear-to-br from-orange-500 to-red-600 rounded-2xl flex items-center justify-center shadow-lg group-hover:scale-110 transition-transform">
180
+ <i data-lucide="brain" class="w-8 h-8 text-white"></i>
181
+ </div>
182
+ <span class="px-3 py-1 bg-orange-500/20 border border-orange-500/30 rounded-full text-orange-400 text-xs font-semibold uppercase">
183
+ Novo
184
+ </span>
185
+ </div>
186
+
187
+ <!-- Title -->
188
+ <h3 class="text-2xl sm:text-3xl font-bold text-white mb-4">
189
+ IA & Automação
190
+ </h3>
191
+
192
+ <!-- Description -->
193
+ <p class="text-gray-300 text-base leading-relaxed mb-6 grow">
194
+ Desenvolvemos soluções inteligentes com Inteligência Artificial: chatbots para WhatsApp, assistentes virtuais, análise preditiva, automação de processos e modelos de IA personalizados para otimizar seu negócio.
195
+ </p>
196
+
197
+ <!-- Features List -->
198
+ <ul class="space-y-3">
199
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
200
+ <i data-lucide="check-circle" class="w-5 h-5 text-orange-400 shrink-0 mt-0.5"></i>
201
+ <span>Chatbots inteligentes para WhatsApp Business</span>
202
+ </li>
203
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
204
+ <i data-lucide="check-circle" class="w-5 h-5 text-orange-400 shrink-0 mt-0.5"></i>
205
+ <span>Assistentes virtuais com processamento de linguagem</span>
206
+ </li>
207
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
208
+ <i data-lucide="check-circle" class="w-5 h-5 text-orange-400 shrink-0 mt-0.5"></i>
209
+ <span>Análise preditiva e machine learning</span>
210
+ </li>
211
+ <li class="flex items-start gap-3 text-gray-400 text-sm">
212
+ <i data-lucide="check-circle" class="w-5 h-5 text-orange-400 shrink-0 mt-0.5"></i>
213
+ <span>Automação de processos repetitivos (RPA)</span>
214
+ </li>
215
+ </ul>
216
+ </div>
217
+ </div>
218
+
219
+ </div>
220
+
221
+ <!-- SEÇÃO DE DESTAQUE -->
222
+ <div class="mt-20 lg:mt-32">
223
+ <div class="relative">
224
+ <div class="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-purple-500/10 to-blue-500/10 rounded-3xl blur-3xl"></div>
225
+
226
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-3xl p-8 lg:p-12">
227
+ <div class="grid lg:grid-cols-2 gap-8 lg:gap-12 items-center">
228
+
229
+ <!-- Left Content -->
230
+ <div>
231
+ <div class="inline-block px-4 py-2 bg-cyan-500/10 rounded-full border border-cyan-500/20 mb-6">
232
+ <span class="text-cyan-400 text-sm font-semibold uppercase tracking-wider">Processo Transparente</span>
233
+ </div>
234
+
235
+ <h2 class="text-3xl sm:text-4xl md:text-5xl font-bold text-white mb-6 leading-tight">
236
+ Como trabalhamos com você
237
+ </h2>
238
+
239
+ <p class="text-gray-300 text-lg leading-relaxed mb-8">
240
+ Nosso processo é colaborativo e transparente. Trabalhamos lado a lado com você em cada etapa do projeto, garantindo que sua visão se torne realidade.
241
+ </p>
242
+
243
+ <a href="feedback.php"
244
+ class="inline-flex items-center gap-3 bg-linear-to-r from-cyan-500 to-blue-600 text-white font-semibold text-lg px-8 py-4 rounded-full shadow-lg hover:shadow-cyan-500/50 hover:scale-105 transition-all duration-300 group">
245
+ Começar Agora
246
+ <i data-lucide="arrow-right" class="w-5 h-5 group-hover:translate-x-1 transition-transform"></i>
247
+ </a>
248
+ </div>
249
+
250
+ <!-- Right Content - Steps -->
251
+ <div class="space-y-6">
252
+ <!-- Step 1 -->
253
+ <div class="flex gap-4">
254
+ <div class="shrink-0 w-12 h-12 bg-cyan-500/10 rounded-xl flex items-center justify-center border border-cyan-500/20">
255
+ <span class="text-cyan-400 font-bold text-lg">1</span>
256
+ </div>
257
+ <div>
258
+ <h4 class="text-white font-semibold text-lg mb-2">Consulta Inicial</h4>
259
+ <p class="text-gray-400 text-sm leading-relaxed">Entendemos seu negócio, objetivos e desafios para criar a melhor solução.</p>
260
+ </div>
261
+ </div>
262
+
263
+ <!-- Step 2 -->
264
+ <div class="flex gap-4">
265
+ <div class="shrink-0 w-12 h-12 bg-blue-500/10 rounded-xl flex items-center justify-center border border-blue-500/20">
266
+ <span class="text-blue-400 font-bold text-lg">2</span>
267
+ </div>
268
+ <div>
269
+ <h4 class="text-white font-semibold text-lg mb-2">Planejamento</h4>
270
+ <p class="text-gray-400 text-sm leading-relaxed">Criamos um roadmap detalhado com prazos, custos e entregas definidas.</p>
271
+ </div>
272
+ </div>
273
+
274
+ <!-- Step 3 -->
275
+ <div class="flex gap-4">
276
+ <div class="shrink-0 w-12 h-12 bg-purple-500/10 rounded-xl flex items-center justify-center border border-purple-500/20">
277
+ <span class="text-purple-400 font-bold text-lg">3</span>
278
+ </div>
279
+ <div>
280
+ <h4 class="text-white font-semibold text-lg mb-2">Desenvolvimento</h4>
281
+ <p class="text-gray-400 text-sm leading-relaxed">Construímos sua solução com código limpo, testes e validações constantes.</p>
282
+ </div>
283
+ </div>
284
+
285
+ <!-- Step 4 -->
286
+ <div class="flex gap-4">
287
+ <div class="shrink-0 w-12 h-12 bg-green-500/10 rounded-xl flex items-center justify-center border border-green-500/20">
288
+ <span class="text-green-400 font-bold text-lg">4</span>
289
+ </div>
290
+ <div>
291
+ <h4 class="text-white font-semibold text-lg mb-2">Entrega & Suporte</h4>
292
+ <p class="text-gray-400 text-sm leading-relaxed">Lançamos seu projeto e fornecemos suporte contínuo para garantir o sucesso.</p>
293
+ </div>
294
+ </div>
295
+ </div>
296
+
297
+ </div>
298
+ </div>
299
+ </div>
300
+ </div>
301
+
302
+ <!-- CTA FINAL -->
303
+ <div class="text-center mt-20 lg:mt-32">
304
+ <h2 class="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-6 leading-tight">
305
+ Pronto para transformar
306
+ <span class="block text-slate-300">
307
+ seu negócio?
308
+ </span>
309
+ </h2>
310
+
311
+ <p class="text-lg sm:text-xl text-gray-300 max-w-2xl mx-auto mb-10">
312
+ Entre em contato hoje mesmo e descubra como podemos ajudar você a alcançar seus objetivos.
313
+ </p>
314
+
315
+ <div class="flex flex-col sm:flex-row items-center justify-center gap-4">
316
+ <a href="feedback.php"
317
+ class="inline-flex items-center justify-center gap-3 w-full sm:w-auto bg-slate-700 hover:bg-slate-600 border border-slate-600 text-slate-200 font-medium text-lg px-10 py-4 rounded-lg transition-all duration-300">
318
+ Iniciar Projeto
319
+ <i data-lucide="arrow-right" class="w-5 h-5"></i>
320
+ </a>
321
+
322
+ <a href="projetos.php"
323
+ class="inline-flex items-center justify-center gap-3 w-full sm:w-auto bg-slate-800/50 hover:bg-slate-700/50 border border-slate-600 text-slate-300 font-medium text-lg px-10 py-4 rounded-lg transition-all duration-300">
324
+ Ver Portfolio
325
+ <i data-lucide="folder-open" class="w-5 h-5"></i>
326
+ </a>
327
+ </div>
328
+ </div>
329
+
330
+ </div>
331
+ </main>
332
+
333
+ <?php include 'components/footer.php'; ?>
334
+
335
+ <!-- SCRIPTS -->
336
+ <script src="https://unpkg.com/lucide@latest"></script>
337
+ <script>
338
+ document.addEventListener('DOMContentLoaded', () => {
339
+ // Initialize Lucide icons
340
+ lucide.createIcons();
341
+
342
+ // Fade in animations on scroll
343
+ const observerOptions = {
344
+ threshold: 0.1,
345
+ rootMargin: '0px 0px -50px 0px'
346
+ };
347
+
348
+ const observer = new IntersectionObserver((entries) => {
349
+ entries.forEach(entry => {
350
+ if (entry.isIntersecting) {
351
+ entry.target.style.opacity = '1';
352
+ entry.target.style.transform = 'translateY(0)';
353
+ }
354
+ });
355
+ }, observerOptions);
356
+
357
+ // Observe all service cards and sections
358
+ document.querySelectorAll('.group, section').forEach((el, index) => {
359
+ el.style.opacity = '0';
360
+ el.style.transform = 'translateY(20px)';
361
+ el.style.transition = `opacity 0.6s ease ${index * 0.1}s, transform 0.6s ease ${index * 0.1}s`;
362
+ observer.observe(el);
363
+ });
364
+ });
365
+ </script>
366
+
367
+ <style>
368
+ /* Gradient animation */
369
+ @keyframes gradient-shift {
370
+ 0%, 100% {
371
+ background-position: 0% 50%;
372
+ }
373
+ 50% {
374
+ background-position: 100% 50%;
375
+ }
376
+ }
377
+
378
+ .bg-linear-to-r,
379
+ .bg-linear-to-br {
380
+ background-size: 200% 200%;
381
+ animation: gradient-shift 8s ease infinite;
382
+ }
383
+
384
+ /* Smooth hover transitions */
385
+ .group {
386
+ will-change: transform;
387
+ }
388
+ </style>
sobre.php ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__ . '/src/Bootstrap.php';
3
+ \SoftEdge\Env::load(__DIR__);
4
+ \SoftEdge\Bootstrap::init();
5
+ include 'components/header.php';
6
+ ?>
7
+
8
+ <!-- HERO SECTION -->
9
+ <section class="relative min-h-[90vh] flex items-center justify-center overflow-hidden">
10
+ <!-- Background -->
11
+ <div class="absolute inset-0 -z-10">
12
+ <div class="absolute inset-0 bg-linear-to-br from-slate-950 via-slate-900 to-slate-950"></div>
13
+ <div class="absolute inset-0 opacity-30">
14
+ <div class="absolute top-20 left-20 w-96 h-96 bg-cyan-500/20 rounded-full blur-3xl"></div>
15
+ <div class="absolute bottom-20 right-20 w-96 h-96 bg-blue-500/20 rounded-full blur-3xl"></div>
16
+ </div>
17
+ </div>
18
+
19
+ <!-- Content -->
20
+ <div class="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
21
+ <div class="space-y-8">
22
+ <h1 class="text-5xl sm:text-6xl md:text-7xl lg:text-8xl font-bold leading-tight">
23
+ Do sonho<br>
24
+ <span class="text-slate-300">
25
+ à realidade lógica
26
+ </span>
27
+ </h1>
28
+
29
+ <p class="text-lg sm:text-xl md:text-2xl text-slate-400 max-w-3xl mx-auto leading-relaxed">
30
+ Começamos com uma ideia simples.<br class="hidden sm:block">
31
+ Hoje criamos softwares que as pessoas amam usar.
32
+ </p>
33
+ </div>
34
+ </div>
35
+
36
+ <!-- Scroll indicator -->
37
+ <div class="absolute bottom-8 left-1/2 -translate-x-1/2 animate-bounce">
38
+ <i data-lucide="chevron-down" class="w-8 h-8 text-white/40"></i>
39
+ </div>
40
+ </section>
41
+
42
+ <!-- MAIN CONTENT -->
43
+ <main class="relative py-20 lg:py-32">
44
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
45
+
46
+ <!-- NOSSA HISTÓRIA -->
47
+ <div class="grid lg:grid-cols-2 gap-12 lg:gap-20 items-center mb-32">
48
+
49
+ <!-- Texto -->
50
+ <div class="space-y-8">
51
+ <div class="inline-block px-4 py-2 bg-cyan-500/10 rounded-full border border-cyan-500/20 mb-4">
52
+ <span class="text-cyan-400 text-sm font-semibold uppercase tracking-wider">Nossa História</span>
53
+ </div>
54
+
55
+ <div class="space-y-6 text-gray-300 text-base sm:text-lg leading-relaxed">
56
+ <p>
57
+ Tudo começou em <span class="text-cyan-400 font-semibold">2023</span>, quando quatro amigos decidiram que o mundo precisava de softwares mais <span class="text-white font-medium">humanos</span>.
58
+ </p>
59
+
60
+ <p>
61
+ <span class="text-white font-bold text-xl">Isaac Quarenta</span> <span class="text-gray-400 text-sm">(CEO)</span> juntou forças com os co-fundadores
62
+ <span class="text-cyan-300 font-medium">José Lopes</span>,
63
+ <span class="text-blue-300 font-medium">Stefânio Costa</span> e
64
+ <span class="text-purple-300 font-medium">Tiago Rodrigues</span>.
65
+ </p>
66
+
67
+ <p>
68
+ Juntos criaram a <span class="bg-linear-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent font-bold text-xl">SoftEdge</span> — uma empresa que transforma ideias em experiências digitais e softwares légitmos.
69
+ </p>
70
+
71
+ <div class="pt-6 mt-8 border-t border-white/10">
72
+ <p class="text-xl sm:text-2xl font-semibold text-cyan-400 leading-relaxed">
73
+ Começamos com um sonho.<br>
74
+ Hoje desenvolvemos realidades lógicas e softwares mais amáveis.
75
+ </p>
76
+ </div>
77
+ </div>
78
+ </div>
79
+
80
+ <!-- Imagem da Equipe -->
81
+ <div class="relative">
82
+ <div class="relative group">
83
+ <!-- Card Container -->
84
+ <div class="relative overflow-hidden rounded-3xl bg-linear-to-br from-cyan-500/10 to-blue-500/10 p-1 transition-all duration-500 hover:scale-[1.02]">
85
+ <div class="relative overflow-hidden rounded-3xl bg-slate-900/80 backdrop-blur-xl">
86
+
87
+ <!-- Image -->
88
+ <div class="relative aspect-square overflow-hidden">
89
+ <img src="/assets/placeholder.svg"
90
+ alt="Equipe SoftEdge Corporation - Isaac, José, Stefânio e Tiago"
91
+ class="w-full h-full object-cover transition-transform duration-700 group-hover:scale-110">
92
+
93
+ <!-- Overlay Gradient -->
94
+ <div class="absolute inset-0 bg-linear-to-t from-slate-900 via-slate-900/40 to-transparent"></div>
95
+
96
+ <!-- Text Overlay -->
97
+ <div class="absolute bottom-0 left-0 right-0 p-8 text-center">
98
+ <h3 class="text-2xl sm:text-3xl font-bold text-white mb-2">Nossa Equipe</h3>
99
+ <p class="text-gray-300 text-sm sm:text-base">Isaac • José • Stefâncio • Tiago</p>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ <!-- Decorative Elements -->
106
+ <div class="absolute -top-4 -right-4 w-24 h-24 bg-cyan-500/20 rounded-full blur-2xl"></div>
107
+ <div class="absolute -bottom-4 -left-4 w-24 h-24 bg-blue-500/20 rounded-full blur-2xl"></div>
108
+ </div>
109
+ </div>
110
+ </div>
111
+
112
+ <!-- NÚMEROS IMPACTANTES -->
113
+ <div class="mb-32">
114
+ <div class="text-center mb-16">
115
+ <div class="inline-block px-4 py-2 bg-cyan-500/10 rounded-full border border-cyan-500/20 mb-4">
116
+ <span class="text-cyan-400 text-sm font-semibold uppercase tracking-wider">Nossos Números</span>
117
+ </div>
118
+ <h2 class="text-3xl sm:text-4xl md:text-5xl font-bold text-white">
119
+ Resultados que inspiram
120
+ </h2>
121
+ </div>
122
+
123
+ <div class="grid grid-cols-2 lg:grid-cols-4 gap-6 lg:gap-8">
124
+ <!-- Stat 1 -->
125
+ <div class="relative group">
126
+ <div class="absolute inset-0 bg-linear-to-br from-cyan-500/20 to-blue-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
127
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-2xl p-8 text-center transition-all duration-500 hover:border-cyan-500/30">
128
+ <div class="text-4xl sm:text-5xl md:text-6xl font-bold bg-linear-to-br from-cyan-400 to-cyan-600 bg-clip-text text-transparent mb-3">
129
+ 70+
130
+ </div>
131
+ <p class="text-gray-300 text-sm sm:text-base">Projetos entregues</p>
132
+ </div>
133
+ </div>
134
+
135
+ <!-- Stat 2 -->
136
+ <div class="relative group">
137
+ <div class="absolute inset-0 bg-linear-to-br from-blue-500/20 to-purple-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
138
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-2xl p-8 text-center transition-all duration-500 hover:border-blue-500/30">
139
+ <div class="text-4xl sm:text-5xl md:text-6xl font-bold bg-linear-to-br from-blue-400 to-blue-600 bg-clip-text text-transparent mb-3">
140
+ 4.9★
141
+ </div>
142
+ <p class="text-gray-300 text-sm sm:text-base">Satisfação média</p>
143
+ </div>
144
+ </div>
145
+
146
+ <!-- Stat 3 -->
147
+ <div class="relative group">
148
+ <div class="absolute inset-0 bg-linear-to-br from-purple-500/20 to-pink-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
149
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-2xl p-8 text-center transition-all duration-500 hover:border-purple-500/30">
150
+ <div class="text-4xl sm:text-5xl md:text-6xl font-bold bg-linear-to-br from-purple-400 to-purple-600 bg-clip-text text-transparent mb-3">
151
+ 24/7
152
+ </div>
153
+ <p class="text-gray-300 text-sm sm:text-base">Suporte dedicado</p>
154
+ </div>
155
+ </div>
156
+
157
+ <!-- Stat 4 -->
158
+ <div class="relative group">
159
+ <div class="absolute inset-0 bg-linear-to-br from-green-500/20 to-emerald-500/20 rounded-2xl blur-xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
160
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/5 rounded-2xl p-8 text-center transition-all duration-500 hover:border-green-500/30">
161
+ <div class="text-4xl sm:text-5xl md:text-6xl font-bold bg-linear-to-br from-green-400 to-green-600 bg-clip-text text-transparent mb-3">
162
+ 100%
163
+ </div>
164
+ <p class="text-gray-300 text-sm sm:text-base">Código limpo</p>
165
+ </div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+
170
+ <!-- CTA SECTION -->
171
+ <div class="relative">
172
+ <!-- Background -->
173
+ <div class="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10 rounded-3xl blur-3xl"></div>
174
+
175
+ <!-- Content -->
176
+ <div class="relative bg-slate-900/60 backdrop-blur-xl border border-white/10 rounded-3xl p-12 lg:p-16 text-center">
177
+ <h2 class="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold text-white mb-6 leading-tight">
178
+ Pronto para criar algo<br class="hidden sm:block">
179
+ <span class="bg-linear-to-r from-cyan-400 to-blue-500 bg-clip-text text-transparent">
180
+ incrível juntos?
181
+ </span>
182
+ </h2>
183
+
184
+ <p class="text-gray-300 text-lg max-w-2xl mx-auto mb-10">
185
+ Vamos transformar sua ideia em realidade. Entre em contato e descubra como podemos ajudar.
186
+ </p>
187
+
188
+ <a href="feedback.php"
189
+ class="inline-flex items-center gap-3 bg-slate-700 hover:bg-slate-600 border border-slate-600 text-slate-200 font-medium text-lg px-8 py-4 rounded-lg transition-all duration-300">
190
+ Falar conosco
191
+ <i data-lucide="arrow-right" class="w-5 h-5"></i>
192
+ </a>
193
+ </div>
194
+ </div>
195
+
196
+ </div>
197
+ </main>
198
+
199
+ <?php include 'components/footer.php'; ?>
200
+
201
+ <!-- SCRIPTS -->
202
+ <script src="https://unpkg.com/lucide@latest"></script>
203
+ <script>
204
+ document.addEventListener('DOMContentLoaded', () => {
205
+ // Initialize Lucide icons
206
+ lucide.createIcons();
207
+
208
+ // Smooth scroll behavior
209
+ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
210
+ anchor.addEventListener('click', function (e) {
211
+ e.preventDefault();
212
+ const target = document.querySelector(this.getAttribute('href'));
213
+ if (target) {
214
+ target.scrollIntoView({
215
+ behavior: 'smooth',
216
+ block: 'start'
217
+ });
218
+ }
219
+ });
220
+ });
221
+
222
+ // Intersection Observer for fade-in animations
223
+ const observerOptions = {
224
+ threshold: 0.1,
225
+ rootMargin: '0px 0px -100px 0px'
226
+ };
227
+
228
+ const observer = new IntersectionObserver((entries) => {
229
+ entries.forEach(entry => {
230
+ if (entry.isIntersecting) {
231
+ entry.target.style.opacity = '1';
232
+ entry.target.style.transform = 'translateY(0)';
233
+ }
234
+ });
235
+ }, observerOptions);
236
+
237
+ // Observe all sections
238
+ document.querySelectorAll('section, main > div > div').forEach(el => {
239
+ el.style.opacity = '0';
240
+ el.style.transform = 'translateY(30px)';
241
+ el.style.transition = 'opacity 0.8s ease, transform 0.8s ease';
242
+ observer.observe(el);
243
+ });
244
+ });
245
+ </script>
246
+
247
+ <style>
248
+ /* Smooth scrolling */
249
+ html {
250
+ scroll-behavior: smooth;
251
+ }
252
+
253
+ /* Image hover effects */
254
+ img {
255
+ will-change: transform;
256
+ }
257
+
258
+ /* Gradient animation */
259
+ @keyframes gradient-shift {
260
+ 0%, 100% {
261
+ background-position: 0% 50%;
262
+ }
263
+ 50% {
264
+ background-position: 100% 50%;
265
+ }
266
+ }
267
+
268
+ .bg-linear-to-r {
269
+ background-size: 200% 200%;
270
+ animation: gradient-shift 8s ease infinite;
271
+ }
272
+
273
+ /* Custom scrollbar */
274
+ ::-webkit-scrollbar {
275
+ width: 10px;
276
+ }
277
+
278
+ ::-webkit-scrollbar-track {
279
+ background: #0f172a;
280
+ }
281
+
282
+ ::-webkit-scrollbar-thumb {
283
+ background: linear-gradient(180deg, #06b6d4, #3b82f6);
284
+ border-radius: 5px;
285
+ }
286
+
287
+ ::-webkit-scrollbar-thumb:hover {
288
+ background: linear-gradient(180deg, #0891b2, #2563eb);
289
+ }
290
+ </style>
test-react.php ADDED
File without changes
test.html ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="pt-BR">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SoftEdge Corporation - Test</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ background: linear-gradient(135deg, #0f172a, #1e293b);
11
+ color: white;
12
+ margin: 0;
13
+ padding: 0;
14
+ min-height: 100vh;
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: center;
18
+ }
19
+ .container {
20
+ text-align: center;
21
+ max-width: 600px;
22
+ padding: 2rem;
23
+ }
24
+ .logo {
25
+ font-size: 3rem;
26
+ margin-bottom: 1rem;
27
+ }
28
+ .status {
29
+ background: rgba(34, 197, 94, 0.1);
30
+ border: 1px solid #22c55e;
31
+ border-radius: 0.5rem;
32
+ padding: 1rem;
33
+ margin: 1rem 0;
34
+ }
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div class="container">
39
+ <div class="logo">🚀</div>
40
+ <h1>SoftEdge Corporation</h1>
41
+ <p>Website em funcionamento!</p>
42
+ <div class="status">
43
+ <strong>✅ Status: Online</strong><br>
44
+ <small>Deployed successfully on Hugging Face Spaces</small>
45
+ </div>
46
+ <p>Se você está vendo esta página, o deployment está funcionando corretamente.</p>
47
+ </div>
48
+ </body>
49
+ </html>
webpack.config.js ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const path = require('path');
2
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3
+ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
4
+ const TerserPlugin = require('terser-webpack-plugin');
5
+
6
+ const isProduction = process.env.NODE_ENV === 'production';
7
+
8
+ module.exports = {
9
+ mode: isProduction ? 'production' : 'development',
10
+ entry: './src/react/index.js',
11
+
12
+ output: {
13
+ path: path.resolve(__dirname, 'dist'),
14
+ filename: (pathData) => {
15
+ return pathData.chunk.name === 'main'
16
+ ? 'static/js/bundle.js'
17
+ : 'static/js/[name].[contenthash:8].js';
18
+ },
19
+ chunkFilename: 'static/js/chunk.[id].[contenthash:8].js',
20
+ publicPath: '/',
21
+ clean: true,
22
+ },
23
+
24
+ module: {
25
+ rules: [
26
+ {
27
+ test: /\.(js|jsx)$/,
28
+ exclude: /node_modules/,
29
+ use: {
30
+ loader: 'babel-loader',
31
+ options: {
32
+ presets: [
33
+ ['@babel/preset-env', {
34
+ targets: {
35
+ browsers: ['> 0.25%', 'not dead'],
36
+ },
37
+ modules: false,
38
+ }],
39
+ ['@babel/preset-react', {
40
+ runtime: 'automatic',
41
+ }],
42
+ ],
43
+ plugins: [
44
+ '@babel/plugin-proposal-class-properties',
45
+ '@babel/plugin-proposal-object-rest-spread',
46
+ ],
47
+ },
48
+ },
49
+ },
50
+ {
51
+ test: /\.css$/i,
52
+ use: [
53
+ isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
54
+ {
55
+ loader: 'css-loader',
56
+ options: {
57
+ importLoaders: 1,
58
+ modules: {
59
+ auto: true,
60
+ localIdentName: isProduction
61
+ ? '[hash:base64:8]'
62
+ : '[name]__[local]__[hash:base64:4]',
63
+ },
64
+ },
65
+ },
66
+ {
67
+ loader: 'postcss-loader',
68
+ options: {
69
+ postcssOptions: {
70
+ plugins: [
71
+ 'autoprefixer',
72
+ isProduction && 'cssnano',
73
+ ].filter(Boolean),
74
+ },
75
+ },
76
+ },
77
+ ],
78
+ },
79
+ {
80
+ test: /\.(png|jpe?g|gif|svg|webp)$/i,
81
+ type: 'asset/resource',
82
+ generator: {
83
+ filename: 'static/media/[name].[hash:8][ext]',
84
+ },
85
+ },
86
+ {
87
+ test: /\.(woff|woff2|eot|ttf|otf)$/i,
88
+ type: 'asset/resource',
89
+ generator: {
90
+ filename: 'static/fonts/[name].[hash:8][ext]',
91
+ },
92
+ },
93
+ ],
94
+ },
95
+
96
+ plugins: [
97
+ ...(isProduction ? [
98
+ new MiniCssExtractPlugin({
99
+ filename: 'static/css/[name].[contenthash:8].css',
100
+ chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
101
+ }),
102
+ ] : []),
103
+ ],
104
+
105
+ optimization: {
106
+ minimize: isProduction,
107
+ minimizer: [
108
+ new TerserPlugin({
109
+ terserOptions: {
110
+ compress: {
111
+ drop_console: isProduction,
112
+ drop_debugger: isProduction,
113
+ },
114
+ },
115
+ }),
116
+ new CssMinimizerPlugin(),
117
+ ],
118
+ splitChunks: {
119
+ chunks: 'all',
120
+ cacheGroups: {
121
+ vendor: {
122
+ test: /[\\/]node_modules[\\/]/,
123
+ name: 'vendor',
124
+ chunks: 'all',
125
+ enforce: true,
126
+ },
127
+ },
128
+ },
129
+ },
130
+
131
+ resolve: {
132
+ extensions: ['.js', '.jsx', '.json'],
133
+ alias: {
134
+ '@': path.resolve(__dirname, 'src/react'),
135
+ '@components': path.resolve(__dirname, 'src/react/components'),
136
+ '@utils': path.resolve(__dirname, 'src/react/utils'),
137
+ '@assets': path.resolve(__dirname, 'src/react/assets'),
138
+ },
139
+ },
140
+
141
+ devServer: {
142
+ static: {
143
+ directory: path.join(__dirname, 'dist'),
144
+ },
145
+ compress: true,
146
+ port: 3000,
147
+ hot: true,
148
+ open: true,
149
+ historyApiFallback: true,
150
+ proxy: {
151
+ '/api': {
152
+ target: 'http://localhost:8080',
153
+ changeOrigin: true,
154
+ secure: false,
155
+ },
156
+ },
157
+ headers: {
158
+ 'Access-Control-Allow-Origin': '*',
159
+ 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
160
+ 'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
161
+ },
162
+ },
163
+
164
+ devtool: isProduction ? 'source-map' : 'eval-cheap-module-source-map',
165
+
166
+ performance: {
167
+ hints: isProduction ? 'warning' : false,
168
+ maxEntrypointSize: 512000,
169
+ maxAssetSize: 512000,
170
+ },
171
+
172
+ stats: {
173
+ colors: true,
174
+ children: false,
175
+ chunks: false,
176
+ chunkModules: false,
177
+ modules: false,
178
+ reasons: false,
179
+ errorDetails: true,
180
+ assets: true,
181
+ version: false,
182
+ timings: true,
183
+ },
184
+ };