baraqex 1.0.50 → 1.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/basic-app/.eslintignore +5 -0
- package/templates/basic-app/.eslintrc.json +25 -0
- package/templates/basic-app/README.md +166 -0
- package/templates/basic-app/esbuild.config.js +37 -0
- package/templates/basic-app/favicon.ico +0 -0
- package/templates/basic-app/index.html +13 -0
- package/templates/basic-app/main.css +3 -0
- package/templates/basic-app/package.json +29 -20
- package/templates/basic-app/postcss.config.js +6 -0
- package/templates/basic-app/public/logo.png +0 -0
- package/templates/basic-app/src/main.css +77 -0
- package/templates/basic-app/src/main.tsx +465 -0
- package/templates/basic-app/tailwind.config.js +38 -0
- package/templates/basic-app/tsconfig.json +13 -0
- package/templates/basic-app/vite.config.ts +8 -0
- package/templates/wasm/src/App.tsx +5 -5
- package/templates/basic-app/public/index.html +0 -13
- package/templates/basic-app/public/styles.css +0 -158
- package/templates/basic-app/server.js +0 -15
- package/templates/basic-app/src/App.jsx +0 -68
package/package.json
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": true,
|
|
3
|
+
"env": {
|
|
4
|
+
"browser": true,
|
|
5
|
+
"es2020": true
|
|
6
|
+
},
|
|
7
|
+
"extends": [
|
|
8
|
+
"eslint:recommended",
|
|
9
|
+
"plugin:@typescript-eslint/recommended"
|
|
10
|
+
],
|
|
11
|
+
"ignorePatterns": ["dist", ".eslintrc.json"],
|
|
12
|
+
"parser": "@typescript-eslint/parser",
|
|
13
|
+
"plugins": [
|
|
14
|
+
"@typescript-eslint",
|
|
15
|
+
"react-refresh"
|
|
16
|
+
],
|
|
17
|
+
"rules": {
|
|
18
|
+
"react-refresh/only-export-components": [
|
|
19
|
+
"warn",
|
|
20
|
+
{ "allowConstantExport": true }
|
|
21
|
+
],
|
|
22
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
23
|
+
"@typescript-eslint/ban-ts-comment": "off"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Baraqex Basic App Template
|
|
2
|
+
|
|
3
|
+
A comprehensive demonstration of the Baraqex framework featuring all major capabilities and beautiful Tailwind CSS styling.
|
|
4
|
+
|
|
5
|
+
## 🚀 What's Included
|
|
6
|
+
|
|
7
|
+
This template showcases:
|
|
8
|
+
|
|
9
|
+
- **State Management**: useState, useEffect, useMemo, useRef hooks
|
|
10
|
+
- **Error Boundaries**: useErrorBoundary for graceful error handling
|
|
11
|
+
- **Context API**: createContext and useContext for state sharing
|
|
12
|
+
- **Interactive Components**: Counter, Todo List, Error Testing
|
|
13
|
+
- **Responsive Design**: Tailwind CSS with dark/light mode
|
|
14
|
+
- **Performance Optimizations**: Memoization and efficient re-rendering
|
|
15
|
+
|
|
16
|
+
## 🎯 Features Demo
|
|
17
|
+
|
|
18
|
+
### Counter Component
|
|
19
|
+
- State management with useState
|
|
20
|
+
- Effect tracking with useEffect
|
|
21
|
+
- Performance optimization with useMemo
|
|
22
|
+
- Render counting with useRef
|
|
23
|
+
|
|
24
|
+
### Todo List Component
|
|
25
|
+
- Complex state operations (add, toggle, delete)
|
|
26
|
+
- Form handling and validation
|
|
27
|
+
- Progress tracking
|
|
28
|
+
- List rendering optimization
|
|
29
|
+
|
|
30
|
+
### Error Boundary Test
|
|
31
|
+
- Error boundary implementation
|
|
32
|
+
- Graceful error recovery
|
|
33
|
+
- User-friendly error messages
|
|
34
|
+
|
|
35
|
+
### Context API Demo
|
|
36
|
+
- Theme switching across components
|
|
37
|
+
- Global state management
|
|
38
|
+
- Provider/Consumer pattern
|
|
39
|
+
|
|
40
|
+
## 🎨 Styling
|
|
41
|
+
|
|
42
|
+
- **Tailwind CSS**: Utility-first CSS framework
|
|
43
|
+
- **Custom Components**: Reusable button, card, and input styles
|
|
44
|
+
- **Responsive Design**: Mobile-first approach
|
|
45
|
+
- **Dark Mode**: Full theme switching support
|
|
46
|
+
- **Animations**: Smooth transitions and hover effects
|
|
47
|
+
|
|
48
|
+
## 📁 Project Structure
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
src/
|
|
52
|
+
├── main.tsx # Main application component
|
|
53
|
+
├── main.css # Tailwind CSS imports and custom styles
|
|
54
|
+
└── App.jsx # Alternative app component structure
|
|
55
|
+
|
|
56
|
+
public/
|
|
57
|
+
├── logo.png # Baraqex logo (add your own)
|
|
58
|
+
└── index.html # HTML template
|
|
59
|
+
|
|
60
|
+
dist/
|
|
61
|
+
├── bundle.js # Compiled JavaScript
|
|
62
|
+
└── main.css # Compiled CSS
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 🛠️ Development
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Install dependencies
|
|
69
|
+
npm install
|
|
70
|
+
|
|
71
|
+
# Start development server with hot reload
|
|
72
|
+
npm run dev
|
|
73
|
+
|
|
74
|
+
# Build for production
|
|
75
|
+
npm run build
|
|
76
|
+
|
|
77
|
+
# Preview production build
|
|
78
|
+
npm run preview
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 📖 About Baraqex
|
|
82
|
+
|
|
83
|
+
Baraqex is a powerful full-stack framework built on Frontend Hamroun that provides:
|
|
84
|
+
|
|
85
|
+
- ⚡ **Reactive State Management**: Intuitive hooks API
|
|
86
|
+
- 🌐 **Server-Side Rendering**: SEO-friendly and fast loading
|
|
87
|
+
- 🔄 **WebAssembly Support**: High-performance computing
|
|
88
|
+
- 🛡️ **Built-in Security**: Authentication and validation
|
|
89
|
+
- 📦 **Zero Configuration**: Works out of the box
|
|
90
|
+
- 🎯 **TypeScript Ready**: Full type safety support
|
|
91
|
+
|
|
92
|
+
## 🔧 Customization
|
|
93
|
+
|
|
94
|
+
### Adding Components
|
|
95
|
+
|
|
96
|
+
Create new components following the established pattern:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
import { jsx, useState } from 'baraqex';
|
|
100
|
+
|
|
101
|
+
function MyComponent() {
|
|
102
|
+
const [state, setState] = useState('initial');
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<div className="card">
|
|
106
|
+
<h3>My Component</h3>
|
|
107
|
+
<p>State: {state}</p>
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Styling Guidelines
|
|
114
|
+
|
|
115
|
+
Use the established Tailwind classes and custom components:
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
// Buttons
|
|
119
|
+
<button className="btn btn-primary">Primary Action</button>
|
|
120
|
+
<button className="btn btn-secondary">Secondary Action</button>
|
|
121
|
+
|
|
122
|
+
// Cards
|
|
123
|
+
<div className="card">Content here</div>
|
|
124
|
+
|
|
125
|
+
// Inputs
|
|
126
|
+
<input className="input" placeholder="Enter text..." />
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Adding New Features
|
|
130
|
+
|
|
131
|
+
1. Create component in `src/`
|
|
132
|
+
2. Import and use in `main.tsx`
|
|
133
|
+
3. Add to navigation if needed
|
|
134
|
+
4. Test error boundaries
|
|
135
|
+
5. Ensure responsive design
|
|
136
|
+
|
|
137
|
+
## 🚀 Deployment
|
|
138
|
+
|
|
139
|
+
The built application can be deployed to any static hosting service:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Build production files
|
|
143
|
+
npm run build
|
|
144
|
+
|
|
145
|
+
# Deploy the dist/ folder contents
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Deployment Options:**
|
|
149
|
+
- Vercel: `vercel --prod`
|
|
150
|
+
- Netlify: Drag & drop the project folder
|
|
151
|
+
- GitHub Pages: Push to `gh-pages` branch
|
|
152
|
+
- Any static host: Upload `dist/` contents
|
|
153
|
+
|
|
154
|
+
## 📚 Learn More
|
|
155
|
+
|
|
156
|
+
- [Baraqex Documentation](https://www.baraqex.tech/docs)
|
|
157
|
+
- [Frontend Hamroun Hooks](https://frontend-hamroun.com/hooks)
|
|
158
|
+
- [Tailwind CSS Docs](https://tailwindcss.com/docs)
|
|
159
|
+
|
|
160
|
+
## 🤝 Contributing
|
|
161
|
+
|
|
162
|
+
This template is part of the Baraqex framework. Contributions welcome!
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
**Happy coding with Baraqex! 🚀**
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
|
|
3
|
+
const isWatch = process.argv.includes('--watch');
|
|
4
|
+
|
|
5
|
+
const config = {
|
|
6
|
+
entryPoints: ['src/main.tsx'],
|
|
7
|
+
bundle: true,
|
|
8
|
+
outfile: 'dist/bundle.js',
|
|
9
|
+
format: 'esm',
|
|
10
|
+
platform: 'browser',
|
|
11
|
+
target: 'es2020',
|
|
12
|
+
minify: !isWatch,
|
|
13
|
+
sourcemap: isWatch,
|
|
14
|
+
define: {
|
|
15
|
+
'process.env.NODE_ENV': isWatch ? '"development"' : '"production"'
|
|
16
|
+
},
|
|
17
|
+
external: [],
|
|
18
|
+
loader: {
|
|
19
|
+
'.tsx': 'tsx',
|
|
20
|
+
'.ts': 'tsx',
|
|
21
|
+
'.jsx': 'jsx',
|
|
22
|
+
'.js': 'jsx',
|
|
23
|
+
'.css': 'css'
|
|
24
|
+
},
|
|
25
|
+
// Don't transform JSX since we're using jsx() function calls
|
|
26
|
+
jsx: 'preserve'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
if (isWatch) {
|
|
30
|
+
const ctx = await esbuild.context(config);
|
|
31
|
+
await ctx.watch();
|
|
32
|
+
console.log('👀 Watching for changes...');
|
|
33
|
+
console.log('📦 Bundle will be rebuilt automatically');
|
|
34
|
+
} else {
|
|
35
|
+
await esbuild.build(config);
|
|
36
|
+
console.log('✅ Build complete');
|
|
37
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
|
7
|
+
<title>My Frontend App</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body class="bg-gray-100 min-h-screen">
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
},
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"typescript": "^
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "finall",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
11
|
+
"lint:fix": "eslint src --ext ts,tsx --fix"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"baraqex": "^1.0.50",
|
|
15
|
+
"frontend-hamroun": "latest"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
19
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
20
|
+
"autoprefixer": "^10.4.14",
|
|
21
|
+
"eslint": "^8.45.0",
|
|
22
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
23
|
+
"eslint-plugin-react-refresh": "^0.4.3",
|
|
24
|
+
"postcss": "^8.4.27",
|
|
25
|
+
"tailwindcss": "^3.3.3",
|
|
26
|
+
"typescript": "^5.0.0",
|
|
27
|
+
"vite": "^4.4.9"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
/* Custom base styles */
|
|
6
|
+
@layer base {
|
|
7
|
+
* {
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
body {
|
|
12
|
+
margin: 0;
|
|
13
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
14
|
+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
15
|
+
sans-serif;
|
|
16
|
+
-webkit-font-smoothing: antialiased;
|
|
17
|
+
-moz-osx-font-smoothing: grayscale;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Custom component styles */
|
|
22
|
+
@layer components {
|
|
23
|
+
.btn {
|
|
24
|
+
@apply px-4 py-2 rounded-md transition-colors font-medium inline-flex items-center justify-center cursor-pointer border-none outline-none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.btn:focus {
|
|
28
|
+
@apply ring-2 ring-offset-2 ring-primary-500;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.btn-primary {
|
|
32
|
+
@apply bg-primary-500 hover:bg-primary-600 text-white;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.btn-secondary {
|
|
36
|
+
@apply bg-gray-500 hover:bg-gray-600 text-white;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.btn-danger {
|
|
40
|
+
@apply bg-red-500 hover:bg-red-600 text-white;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.card {
|
|
44
|
+
@apply bg-white rounded-lg shadow-lg p-6;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.input {
|
|
48
|
+
@apply px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500 w-full;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Additional utility classes */
|
|
53
|
+
@layer utilities {
|
|
54
|
+
.text-primary-600 {
|
|
55
|
+
color: theme('colors.primary.600');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.bg-primary-500 {
|
|
59
|
+
background-color: theme('colors.primary.500');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.bg-primary-600 {
|
|
63
|
+
background-color: theme('colors.primary.600');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.hover\:bg-primary-600:hover {
|
|
67
|
+
background-color: theme('colors.primary.600');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.ring-primary-500 {
|
|
71
|
+
--tw-ring-color: theme('colors.primary.500');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.border-primary-500 {
|
|
75
|
+
border-color: theme('colors.primary.500');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { jsx, render, useState, useEffect, useMemo, useRef, useErrorBoundary, createContext, useContext } from 'baraqex';
|
|
2
|
+
import './main.css';
|
|
3
|
+
|
|
4
|
+
// JSX type declarations
|
|
5
|
+
declare global {
|
|
6
|
+
namespace JSX {
|
|
7
|
+
interface IntrinsicElements {
|
|
8
|
+
[elemName: string]: any;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Create a theme context
|
|
14
|
+
const ThemeContext = createContext<'light' | 'dark'>('light');
|
|
15
|
+
|
|
16
|
+
// Simple Counter Component with Tailwind styles
|
|
17
|
+
function Counter() {
|
|
18
|
+
const [count, setCount] = useState(0);
|
|
19
|
+
const renderCount = useRef(0);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
renderCount.current += 1;
|
|
23
|
+
}, [count]);
|
|
24
|
+
|
|
25
|
+
const doubled = useMemo(() => count * 2, [count]);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div className="card max-w-sm mx-auto">
|
|
29
|
+
<h2 className="text-2xl font-bold text-gray-800 mb-4 text-center">
|
|
30
|
+
Counter Example
|
|
31
|
+
</h2>
|
|
32
|
+
<div className="text-center">
|
|
33
|
+
<div className="text-4xl font-bold text-primary-600 mb-6">
|
|
34
|
+
{count}
|
|
35
|
+
</div>
|
|
36
|
+
<div className="mb-4">
|
|
37
|
+
<p className="text-sm text-gray-600 mb-2">Doubled: {doubled}</p>
|
|
38
|
+
<p className="text-sm text-gray-600">Renders: {renderCount.current}</p>
|
|
39
|
+
</div>
|
|
40
|
+
<div className="space-x-2">
|
|
41
|
+
<button
|
|
42
|
+
onClick={() => setCount(count + 1)}
|
|
43
|
+
className="btn btn-primary"
|
|
44
|
+
>
|
|
45
|
+
Increment
|
|
46
|
+
</button>
|
|
47
|
+
<button
|
|
48
|
+
onClick={() => setCount(count - 1)}
|
|
49
|
+
className="btn btn-secondary"
|
|
50
|
+
>
|
|
51
|
+
Decrement
|
|
52
|
+
</button>
|
|
53
|
+
<button
|
|
54
|
+
onClick={() => setCount(0)}
|
|
55
|
+
className="btn btn-danger"
|
|
56
|
+
>
|
|
57
|
+
Reset
|
|
58
|
+
</button>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Todo Item Component
|
|
66
|
+
function TodoItem({ todo, onToggle, onDelete }: {
|
|
67
|
+
todo: { id: number; text: string; completed: boolean };
|
|
68
|
+
onToggle: (id: number) => void;
|
|
69
|
+
onDelete: (id: number) => void;
|
|
70
|
+
}) {
|
|
71
|
+
return (
|
|
72
|
+
<div className={`flex items-center justify-between p-3 rounded-md border transition-colors ${
|
|
73
|
+
todo.completed ? 'bg-green-50 border-green-200' : 'bg-gray-50 border-gray-200'
|
|
74
|
+
}`}>
|
|
75
|
+
<div className="flex items-center space-x-3">
|
|
76
|
+
<button
|
|
77
|
+
onClick={() => onToggle(todo.id)}
|
|
78
|
+
className={`w-5 h-5 rounded border-2 flex items-center justify-center transition-colors ${
|
|
79
|
+
todo.completed
|
|
80
|
+
? 'bg-green-500 border-green-500 text-white'
|
|
81
|
+
: 'border-gray-300 hover:border-green-500'
|
|
82
|
+
}`}
|
|
83
|
+
>
|
|
84
|
+
{todo.completed && '✓'}
|
|
85
|
+
</button>
|
|
86
|
+
<span className={`transition-colors ${todo.completed ? 'line-through text-gray-500' : 'text-gray-800'}`}>
|
|
87
|
+
{todo.text}
|
|
88
|
+
</span>
|
|
89
|
+
</div>
|
|
90
|
+
<button
|
|
91
|
+
onClick={() => onDelete(todo.id)}
|
|
92
|
+
className="text-red-500 hover:text-red-700 px-2 py-1 rounded transition-colors"
|
|
93
|
+
>
|
|
94
|
+
Delete
|
|
95
|
+
</button>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Todo List Component
|
|
101
|
+
function TodoList() {
|
|
102
|
+
const [todos, setTodos] = useState<{ id: number; text: string; completed: boolean }[]>([
|
|
103
|
+
{ id: 1, text: 'Learn Baraqex Framework', completed: false },
|
|
104
|
+
{ id: 2, text: 'Build something awesome', completed: false },
|
|
105
|
+
{ id: 3, text: 'Deploy to production', completed: false }
|
|
106
|
+
]);
|
|
107
|
+
const [newTodo, setNewTodo] = useState('');
|
|
108
|
+
|
|
109
|
+
const addTodo = () => {
|
|
110
|
+
if (newTodo.trim()) {
|
|
111
|
+
setTodos([...todos, {
|
|
112
|
+
id: Date.now(),
|
|
113
|
+
text: newTodo.trim(),
|
|
114
|
+
completed: false
|
|
115
|
+
}]);
|
|
116
|
+
setNewTodo('');
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const toggleTodo = (id: number) => {
|
|
121
|
+
setTodos(todos.map((todo: { id: number; completed: any; }) =>
|
|
122
|
+
todo.id === id ? { ...todo, completed: !todo.completed } : todo
|
|
123
|
+
));
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const deleteTodo = (id: number) => {
|
|
127
|
+
setTodos(todos.filter((todo: { id: number; }) => todo.id !== id));
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const completedCount = todos.filter((todo: { completed: any; }) => todo.completed).length;
|
|
131
|
+
const totalCount = todos.length;
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<div className="card max-w-md mx-auto">
|
|
135
|
+
<h2 className="text-2xl font-bold text-gray-800 mb-4 text-center">
|
|
136
|
+
Todo List
|
|
137
|
+
</h2>
|
|
138
|
+
|
|
139
|
+
<div className="mb-4">
|
|
140
|
+
<div className="flex space-x-2 mb-2">
|
|
141
|
+
<input
|
|
142
|
+
type="text"
|
|
143
|
+
value={newTodo}
|
|
144
|
+
onChange={(e: { target: { value: any; }; }) => setNewTodo(e.target.value)}
|
|
145
|
+
onKeyPress={(e: { key: string; }) => e.key === 'Enter' && addTodo()}
|
|
146
|
+
placeholder="Add a new todo..."
|
|
147
|
+
className="input flex-1"
|
|
148
|
+
/>
|
|
149
|
+
<button
|
|
150
|
+
onClick={addTodo}
|
|
151
|
+
className="btn btn-primary"
|
|
152
|
+
>
|
|
153
|
+
Add
|
|
154
|
+
</button>
|
|
155
|
+
</div>
|
|
156
|
+
<div className="text-sm text-gray-600 text-center">
|
|
157
|
+
{completedCount} of {totalCount} completed
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<div className="space-y-2">
|
|
162
|
+
{todos.map((todo: { id: Number; text?: string; completed?: boolean; }) => (
|
|
163
|
+
<TodoItem
|
|
164
|
+
key={todo.id}
|
|
165
|
+
todo={todo}
|
|
166
|
+
onToggle={toggleTodo}
|
|
167
|
+
onDelete={deleteTodo}
|
|
168
|
+
/>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
{todos.length === 0 && (
|
|
173
|
+
<p className="text-gray-500 text-center py-4">
|
|
174
|
+
No todos yet. Add one above!
|
|
175
|
+
</p>
|
|
176
|
+
)}
|
|
177
|
+
</div>
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Error boundary test component
|
|
182
|
+
function BuggyComponent() {
|
|
183
|
+
const [shouldError, setShouldError] = useState(false);
|
|
184
|
+
|
|
185
|
+
if (shouldError) {
|
|
186
|
+
throw new Error("Test error from BuggyComponent");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<div className="card max-w-sm mx-auto">
|
|
191
|
+
<h3 className="text-lg font-semibold text-gray-800 mb-4 text-center">
|
|
192
|
+
Error Boundary Test
|
|
193
|
+
</h3>
|
|
194
|
+
<p className="text-sm text-gray-600 mb-4 text-center">
|
|
195
|
+
Click the button below to test error handling
|
|
196
|
+
</p>
|
|
197
|
+
<div className="text-center">
|
|
198
|
+
<button
|
|
199
|
+
onClick={() => setShouldError(true)}
|
|
200
|
+
className="btn btn-danger"
|
|
201
|
+
>
|
|
202
|
+
Trigger Error
|
|
203
|
+
</button>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Context test component
|
|
210
|
+
function ContextConsumer() {
|
|
211
|
+
const theme = useContext(ThemeContext);
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<div className="card max-w-sm mx-auto">
|
|
215
|
+
<h3 className="text-lg font-semibold text-gray-800 mb-4 text-center">
|
|
216
|
+
Context API Test
|
|
217
|
+
</h3>
|
|
218
|
+
<div className={`p-4 rounded-md border text-center ${
|
|
219
|
+
theme === 'dark' ? 'border-gray-600 bg-gray-700 text-white' : 'border-gray-300 bg-gray-50'
|
|
220
|
+
}`}>
|
|
221
|
+
<p className="text-sm mb-2">Current theme: <strong>{theme}</strong></p>
|
|
222
|
+
<p className="text-xs text-gray-500">
|
|
223
|
+
Theme is provided by Context API
|
|
224
|
+
</p>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Main App Component
|
|
231
|
+
function App() {
|
|
232
|
+
const [activeTab, setActiveTab] = useState('counter');
|
|
233
|
+
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
234
|
+
const [error, resetError] = useErrorBoundary();
|
|
235
|
+
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
document.title = `Baraqex Demo - ${activeTab.charAt(0).toUpperCase() + activeTab.slice(1)}`;
|
|
238
|
+
}, [activeTab]);
|
|
239
|
+
|
|
240
|
+
if (error) {
|
|
241
|
+
return (
|
|
242
|
+
<div className="min-h-screen bg-gradient-to-br from-red-50 to-red-100 flex items-center justify-center">
|
|
243
|
+
<div className="card max-w-md mx-auto text-center">
|
|
244
|
+
<div className="text-6xl mb-4">🚨</div>
|
|
245
|
+
<h1 className="text-2xl font-bold text-red-600 mb-4">Oops! Something went wrong</h1>
|
|
246
|
+
<p className="text-gray-600 mb-4">
|
|
247
|
+
{error.message || 'An unexpected error occurred'}
|
|
248
|
+
</p>
|
|
249
|
+
<button
|
|
250
|
+
onClick={resetError}
|
|
251
|
+
className="btn btn-primary"
|
|
252
|
+
>
|
|
253
|
+
Try Again
|
|
254
|
+
</button>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<ThemeContext.Provider value={theme}>
|
|
262
|
+
<div className={`min-h-screen transition-colors ${
|
|
263
|
+
theme === 'dark'
|
|
264
|
+
? 'bg-gradient-to-br from-gray-900 to-gray-800'
|
|
265
|
+
: 'bg-gradient-to-br from-blue-50 to-indigo-100'
|
|
266
|
+
}`}>
|
|
267
|
+
<div className="container mx-auto px-4 py-8">
|
|
268
|
+
|
|
269
|
+
{/* Header with Logo */}
|
|
270
|
+
<header className="text-center mb-12">
|
|
271
|
+
<div className="flex items-center justify-center mb-6">
|
|
272
|
+
<img
|
|
273
|
+
src="/logo.png"
|
|
274
|
+
alt="Baraqex Logo"
|
|
275
|
+
className="w-16 h-16 mr-4 rounded-lg shadow-lg"
|
|
276
|
+
onError={(e: { target: { style: { display: string; }; nextElementSibling: { style: { display: string; }; }; }; }) => {
|
|
277
|
+
// Fallback to emoji if logo doesn't exist
|
|
278
|
+
e.target.style.display = 'none';
|
|
279
|
+
e.target.nextElementSibling.style.display = 'block';
|
|
280
|
+
}}
|
|
281
|
+
/>
|
|
282
|
+
<div className="text-6xl" style={{display: 'none'}}>🚀</div>
|
|
283
|
+
<div>
|
|
284
|
+
<h1 className={`text-5xl font-bold mb-2 ${theme === 'dark' ? 'text-white' : 'text-gray-800'}`}>
|
|
285
|
+
Baraqex
|
|
286
|
+
</h1>
|
|
287
|
+
<p className={`text-xl ${theme === 'dark' ? 'text-gray-300' : 'text-gray-600'}`}>
|
|
288
|
+
Powered by Frontend Hamroun
|
|
289
|
+
</p>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
{/* About Baraqex */}
|
|
294
|
+
<div className="card max-w-4xl mx-auto mb-8">
|
|
295
|
+
<h2 className="text-2xl font-bold text-gray-800 mb-6 text-center">
|
|
296
|
+
Welcome to Baraqex Framework! 🎉
|
|
297
|
+
</h2>
|
|
298
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 text-left">
|
|
299
|
+
<div>
|
|
300
|
+
<h3 className="text-lg font-semibold text-primary-600 mb-3">🚀 What is Baraqex?</h3>
|
|
301
|
+
<p className="text-gray-700 leading-relaxed mb-4">
|
|
302
|
+
Baraqex is a powerful, modern full-stack framework built on top of the Frontend Hamroun library.
|
|
303
|
+
It provides everything you need to build high-performance web applications with ease.
|
|
304
|
+
</p>
|
|
305
|
+
<p className="text-gray-700 leading-relaxed">
|
|
306
|
+
From simple SPAs to complex server-side rendered applications with WebAssembly integration,
|
|
307
|
+
Baraqex has you covered with a developer-friendly API and excellent performance.
|
|
308
|
+
</p>
|
|
309
|
+
</div>
|
|
310
|
+
<div>
|
|
311
|
+
<h3 className="text-lg font-semibold text-primary-600 mb-3">✨ Key Features</h3>
|
|
312
|
+
<ul className="space-y-2 text-gray-700">
|
|
313
|
+
<li className="flex items-center">
|
|
314
|
+
<span className="text-green-500 mr-2">✓</span>
|
|
315
|
+
Reactive state management with hooks
|
|
316
|
+
</li>
|
|
317
|
+
<li className="flex items-center">
|
|
318
|
+
<span className="text-green-500 mr-2">✓</span>
|
|
319
|
+
Server-side rendering (SSR) support
|
|
320
|
+
</li>
|
|
321
|
+
<li className="flex items-center">
|
|
322
|
+
<span className="text-green-500 mr-2">✓</span>
|
|
323
|
+
WebAssembly (WASM) integration
|
|
324
|
+
</li>
|
|
325
|
+
<li className="flex items-center">
|
|
326
|
+
<span className="text-green-500 mr-2">✓</span>
|
|
327
|
+
Built-in authentication & database support
|
|
328
|
+
</li>
|
|
329
|
+
<li className="flex items-center">
|
|
330
|
+
<span className="text-green-500 mr-2">✓</span>
|
|
331
|
+
TypeScript support out of the box
|
|
332
|
+
</li>
|
|
333
|
+
<li className="flex items-center">
|
|
334
|
+
<span className="text-green-500 mr-2">✓</span>
|
|
335
|
+
Production-ready with optimized builds
|
|
336
|
+
</li>
|
|
337
|
+
</ul>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
|
|
341
|
+
<div className="mt-8 text-center">
|
|
342
|
+
<button
|
|
343
|
+
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
|
|
344
|
+
className={`btn ${theme === 'dark' ? 'bg-yellow-400 text-gray-900 hover:bg-yellow-300' : 'bg-gray-800 text-white hover:bg-gray-700'}`}
|
|
345
|
+
>
|
|
346
|
+
🌙 Toggle {theme === 'light' ? 'Dark' : 'Light'} Mode
|
|
347
|
+
</button>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
</header>
|
|
351
|
+
|
|
352
|
+
{/* Tab Navigation */}
|
|
353
|
+
<div className="flex justify-center mb-8">
|
|
354
|
+
<div className="bg-white rounded-lg shadow-sm p-1 flex space-x-1 overflow-x-auto">
|
|
355
|
+
{[
|
|
356
|
+
{ id: 'counter', label: 'Counter', icon: '🔢' },
|
|
357
|
+
{ id: 'todos', label: 'Todo List', icon: '✅' },
|
|
358
|
+
{ id: 'error', label: 'Error Test', icon: '🚨' },
|
|
359
|
+
{ id: 'context', label: 'Context', icon: '🔄' }
|
|
360
|
+
].map(tab => (
|
|
361
|
+
<button
|
|
362
|
+
key={tab.id}
|
|
363
|
+
onClick={() => setActiveTab(tab.id)}
|
|
364
|
+
className={`px-4 py-2 rounded-md transition-colors whitespace-nowrap ${
|
|
365
|
+
activeTab === tab.id
|
|
366
|
+
? 'bg-primary-500 text-white'
|
|
367
|
+
: 'text-gray-600 hover:text-gray-800 hover:bg-gray-100'
|
|
368
|
+
}`}
|
|
369
|
+
>
|
|
370
|
+
<span className="mr-2">{tab.icon}</span>
|
|
371
|
+
{tab.label}
|
|
372
|
+
</button>
|
|
373
|
+
))}
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
|
|
377
|
+
{/* Tab Content */}
|
|
378
|
+
<div className="flex justify-center mb-12">
|
|
379
|
+
{activeTab === 'counter' && <Counter />}
|
|
380
|
+
{activeTab === 'todos' && <TodoList />}
|
|
381
|
+
{activeTab === 'error' && <BuggyComponent />}
|
|
382
|
+
{activeTab === 'context' && <ContextConsumer />}
|
|
383
|
+
</div>
|
|
384
|
+
|
|
385
|
+
{/* Footer */}
|
|
386
|
+
<footer className="text-center">
|
|
387
|
+
<div className="card max-w-4xl mx-auto">
|
|
388
|
+
<h3 className="text-xl font-semibold text-gray-800 mb-6">
|
|
389
|
+
🎯 Framework Capabilities Demo
|
|
390
|
+
</h3>
|
|
391
|
+
|
|
392
|
+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
|
393
|
+
<div className="text-center">
|
|
394
|
+
<div className="text-3xl mb-2">⚡</div>
|
|
395
|
+
<h4 className="font-semibold text-gray-800 mb-2">State Management</h4>
|
|
396
|
+
<p className="text-sm text-gray-600">
|
|
397
|
+
useState, useEffect, useMemo, and useRef hooks working seamlessly
|
|
398
|
+
</p>
|
|
399
|
+
</div>
|
|
400
|
+
<div className="text-center">
|
|
401
|
+
<div className="text-3xl mb-2">🎨</div>
|
|
402
|
+
<h4 className="font-semibold text-gray-800 mb-2">Tailwind CSS</h4>
|
|
403
|
+
<p className="text-sm text-gray-600">
|
|
404
|
+
Utility-first CSS framework integrated for rapid UI development
|
|
405
|
+
</p>
|
|
406
|
+
</div>
|
|
407
|
+
<div className="text-center">
|
|
408
|
+
<div className="text-3xl mb-2">🛡️</div>
|
|
409
|
+
<h4 className="font-semibold text-gray-800 mb-2">Error Boundaries</h4>
|
|
410
|
+
<p className="text-sm text-gray-600">
|
|
411
|
+
Graceful error handling with useErrorBoundary hook
|
|
412
|
+
</p>
|
|
413
|
+
</div>
|
|
414
|
+
<div className="text-center">
|
|
415
|
+
<div className="text-3xl mb-2">🔄</div>
|
|
416
|
+
<h4 className="font-semibold text-gray-800 mb-2">Context API</h4>
|
|
417
|
+
<p className="text-sm text-gray-600">
|
|
418
|
+
Share state across components with createContext and useContext
|
|
419
|
+
</p>
|
|
420
|
+
</div>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<div className="border-t pt-6">
|
|
424
|
+
<h4 className="font-semibold text-gray-800 mb-4">🚀 Ready to build something amazing?</h4>
|
|
425
|
+
<p className="text-gray-600 mb-4">
|
|
426
|
+
Edit <code className="bg-gray-100 px-2 py-1 rounded text-sm">src/main.tsx</code> to customize this app,
|
|
427
|
+
or create new components to expand your application.
|
|
428
|
+
</p>
|
|
429
|
+
<div className="flex justify-center space-x-4">
|
|
430
|
+
<a
|
|
431
|
+
href="https://www.baraqex.tech/docs"
|
|
432
|
+
target="_blank"
|
|
433
|
+
rel="noopener noreferrer"
|
|
434
|
+
className="text-primary-600 hover:text-primary-800 font-medium"
|
|
435
|
+
>
|
|
436
|
+
📚 Documentation
|
|
437
|
+
</a>
|
|
438
|
+
<a
|
|
439
|
+
href="https://github.com/mohamedx2/baraqex"
|
|
440
|
+
target="_blank"
|
|
441
|
+
rel="noopener noreferrer"
|
|
442
|
+
className="text-primary-600 hover:text-primary-800 font-medium"
|
|
443
|
+
>
|
|
444
|
+
🐙 GitHub
|
|
445
|
+
</a>
|
|
446
|
+
<a
|
|
447
|
+
href="https://www.baraqex.tech/examples"
|
|
448
|
+
target="_blank"
|
|
449
|
+
rel="noopener noreferrer"
|
|
450
|
+
className="text-primary-600 hover:text-primary-800 font-medium"
|
|
451
|
+
>
|
|
452
|
+
🎯 Examples
|
|
453
|
+
</a>
|
|
454
|
+
</div>
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
</footer>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
</ThemeContext.Provider>
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Mount the app
|
|
465
|
+
render(<App />, document.getElementById('root'));
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** @type {import('tailwindcss').Config} */
|
|
2
|
+
export default {
|
|
3
|
+
content: [
|
|
4
|
+
"./index.html",
|
|
5
|
+
"./src/**/*.{js,ts,jsx,tsx}",
|
|
6
|
+
],
|
|
7
|
+
theme: {
|
|
8
|
+
extend: {
|
|
9
|
+
colors: {
|
|
10
|
+
primary: {
|
|
11
|
+
50: '#eff6ff',
|
|
12
|
+
100: '#dbeafe',
|
|
13
|
+
200: '#bfdbfe',
|
|
14
|
+
300: '#93c5fd',
|
|
15
|
+
400: '#60a5fa',
|
|
16
|
+
500: '#3b82f6',
|
|
17
|
+
600: '#2563eb',
|
|
18
|
+
700: '#1d4ed8',
|
|
19
|
+
800: '#1e40af',
|
|
20
|
+
900: '#1e3a8a',
|
|
21
|
+
950: '#172554',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
container: {
|
|
25
|
+
center: true,
|
|
26
|
+
padding: '1rem',
|
|
27
|
+
screens: {
|
|
28
|
+
sm: '640px',
|
|
29
|
+
md: '768px',
|
|
30
|
+
lg: '1024px',
|
|
31
|
+
xl: '1280px',
|
|
32
|
+
'2xl': '1400px',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
plugins: [],
|
|
38
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"jsx": "preserve",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"skipLibCheck": true
|
|
11
|
+
},
|
|
12
|
+
"include": ["src"]
|
|
13
|
+
}
|
|
@@ -151,7 +151,7 @@ export default function App() {
|
|
|
151
151
|
<input
|
|
152
152
|
type="text"
|
|
153
153
|
value={name}
|
|
154
|
-
onChange={(e) => setName(e.target.value)}
|
|
154
|
+
onChange={(e: { target: { value: string | ((prev: string) => string); }; }) => setName(e.target.value)}
|
|
155
155
|
placeholder="Enter your name"
|
|
156
156
|
/>
|
|
157
157
|
<button onClick={handleHello}>Say Hello</button>
|
|
@@ -166,13 +166,13 @@ export default function App() {
|
|
|
166
166
|
<input
|
|
167
167
|
type="number"
|
|
168
168
|
value={inputA}
|
|
169
|
-
onChange={(e) => setInputA(Number(e.target.value))}
|
|
169
|
+
onChange={(e: { target: { value: any; }; }) => setInputA(Number(e.target.value))}
|
|
170
170
|
placeholder="First number"
|
|
171
171
|
/>
|
|
172
172
|
<input
|
|
173
173
|
type="number"
|
|
174
174
|
value={inputB}
|
|
175
|
-
onChange={(e) => setInputB(Number(e.target.value))}
|
|
175
|
+
onChange={(e: { target: { value: any; }; }) => setInputB(Number(e.target.value))}
|
|
176
176
|
placeholder="Second number"
|
|
177
177
|
/>
|
|
178
178
|
</div>
|
|
@@ -190,7 +190,7 @@ export default function App() {
|
|
|
190
190
|
<input
|
|
191
191
|
type="number"
|
|
192
192
|
value={fibInput}
|
|
193
|
-
onChange={(e) => setFibInput(Number(e.target.value))}
|
|
193
|
+
onChange={(e: { target: { value: any; }; }) => setFibInput(Number(e.target.value))}
|
|
194
194
|
placeholder="Fibonacci number"
|
|
195
195
|
min="0"
|
|
196
196
|
max="40"
|
|
@@ -207,7 +207,7 @@ export default function App() {
|
|
|
207
207
|
<input
|
|
208
208
|
type="number"
|
|
209
209
|
value={primeInput}
|
|
210
|
-
onChange={(e) => setPrimeInput(Number(e.target.value))}
|
|
210
|
+
onChange={(e: { target: { value: any; }; }) => setPrimeInput(Number(e.target.value))}
|
|
211
211
|
placeholder="Number to check"
|
|
212
212
|
min="1"
|
|
213
213
|
/>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Baraqex Basic App</title>
|
|
7
|
-
<link rel="stylesheet" href="/styles.css">
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="app-root"></div>
|
|
11
|
-
<script src="/src/App.jsx" type="module"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
* {
|
|
2
|
-
margin: 0;
|
|
3
|
-
padding: 0;
|
|
4
|
-
box-sizing: border-box;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
body {
|
|
8
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
9
|
-
line-height: 1.6;
|
|
10
|
-
color: #333;
|
|
11
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
12
|
-
min-height: 100vh;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.app {
|
|
16
|
-
max-width: 800px;
|
|
17
|
-
margin: 0 auto;
|
|
18
|
-
padding: 20px;
|
|
19
|
-
background: white;
|
|
20
|
-
border-radius: 10px;
|
|
21
|
-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
|
22
|
-
margin-top: 20px;
|
|
23
|
-
margin-bottom: 20px;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.app-header {
|
|
27
|
-
text-align: center;
|
|
28
|
-
margin-bottom: 40px;
|
|
29
|
-
padding-bottom: 20px;
|
|
30
|
-
border-bottom: 2px solid #f0f0f0;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.app-header h1 {
|
|
34
|
-
color: #667eea;
|
|
35
|
-
font-size: 2.5rem;
|
|
36
|
-
margin-bottom: 10px;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.counter-section {
|
|
40
|
-
text-align: center;
|
|
41
|
-
margin-bottom: 40px;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.counter-display {
|
|
45
|
-
margin: 30px 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.count-value {
|
|
49
|
-
font-size: 4rem;
|
|
50
|
-
font-weight: bold;
|
|
51
|
-
color: #667eea;
|
|
52
|
-
display: inline-block;
|
|
53
|
-
padding: 20px 40px;
|
|
54
|
-
border: 3px solid #667eea;
|
|
55
|
-
border-radius: 50px;
|
|
56
|
-
background: linear-gradient(45deg, #f8f9ff, #ffffff);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.counter-controls {
|
|
60
|
-
display: flex;
|
|
61
|
-
gap: 15px;
|
|
62
|
-
justify-content: center;
|
|
63
|
-
flex-wrap: wrap;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.btn {
|
|
67
|
-
padding: 12px 24px;
|
|
68
|
-
border: none;
|
|
69
|
-
border-radius: 6px;
|
|
70
|
-
font-size: 1rem;
|
|
71
|
-
cursor: pointer;
|
|
72
|
-
transition: all 0.3s ease;
|
|
73
|
-
font-weight: 600;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.btn-primary {
|
|
77
|
-
background: #667eea;
|
|
78
|
-
color: white;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.btn-primary:hover {
|
|
82
|
-
background: #5a6fd8;
|
|
83
|
-
transform: translateY(-2px);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
.btn-secondary {
|
|
87
|
-
background: #6c757d;
|
|
88
|
-
color: white;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.btn-secondary:hover {
|
|
92
|
-
background: #5a6268;
|
|
93
|
-
transform: translateY(-2px);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.btn-danger {
|
|
97
|
-
background: #dc3545;
|
|
98
|
-
color: white;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.btn-danger:hover {
|
|
102
|
-
background: #c82333;
|
|
103
|
-
transform: translateY(-2px);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.info-section {
|
|
107
|
-
background: #f8f9fa;
|
|
108
|
-
padding: 30px;
|
|
109
|
-
border-radius: 8px;
|
|
110
|
-
margin-bottom: 30px;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.info-section h3 {
|
|
114
|
-
color: #667eea;
|
|
115
|
-
margin-bottom: 15px;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.info-section ul {
|
|
119
|
-
list-style: none;
|
|
120
|
-
padding-left: 0;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.info-section li {
|
|
124
|
-
margin-bottom: 8px;
|
|
125
|
-
font-size: 1.1rem;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.app-footer {
|
|
129
|
-
text-align: center;
|
|
130
|
-
padding-top: 20px;
|
|
131
|
-
border-top: 1px solid #f0f0f0;
|
|
132
|
-
color: #666;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
@media (max-width: 768px) {
|
|
136
|
-
.app {
|
|
137
|
-
margin: 10px;
|
|
138
|
-
padding: 15px;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.app-header h1 {
|
|
142
|
-
font-size: 2rem;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.count-value {
|
|
146
|
-
font-size: 3rem;
|
|
147
|
-
padding: 15px 30px;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.counter-controls {
|
|
151
|
-
flex-direction: column;
|
|
152
|
-
align-items: center;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.btn {
|
|
156
|
-
width: 200px;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { createServer } from '../../dist/server/index.js';
|
|
2
|
-
|
|
3
|
-
const server = createServer({
|
|
4
|
-
port: process.env.PORT || 3000,
|
|
5
|
-
staticDir: './public',
|
|
6
|
-
enableCors: true
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
server.start().then(() => {
|
|
10
|
-
console.log('🚀 Baraqex Basic App server started successfully!');
|
|
11
|
-
console.log('📱 Visit http://localhost:3000 to see your app');
|
|
12
|
-
}).catch(error => {
|
|
13
|
-
console.error('❌ Failed to start server:', error);
|
|
14
|
-
process.exit(1);
|
|
15
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { jsx, useState, useEffect } from 'baraqex';
|
|
2
|
-
|
|
3
|
-
export default function App() {
|
|
4
|
-
const [count, setCount] = useState(0);
|
|
5
|
-
const [message, setMessage] = useState('Welcome to Baraqex!');
|
|
6
|
-
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
console.log('App component mounted');
|
|
9
|
-
}, []);
|
|
10
|
-
|
|
11
|
-
const increment = () => {
|
|
12
|
-
setCount(prev => prev + 1);
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const decrement = () => {
|
|
16
|
-
setCount(prev => prev - 1);
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const resetCount = () => {
|
|
20
|
-
setCount(0);
|
|
21
|
-
setMessage('Counter reset!');
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<div className="app">
|
|
26
|
-
<header className="app-header">
|
|
27
|
-
<h1>{message}</h1>
|
|
28
|
-
<p>This is a basic Baraqex application template.</p>
|
|
29
|
-
</header>
|
|
30
|
-
|
|
31
|
-
<main className="app-main">
|
|
32
|
-
<div className="counter-section">
|
|
33
|
-
<h2>Interactive Counter</h2>
|
|
34
|
-
<div className="counter-display">
|
|
35
|
-
<span className="count-value">{count}</span>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<div className="counter-controls">
|
|
39
|
-
<button onClick={decrement} className="btn btn-secondary">
|
|
40
|
-
- Decrease
|
|
41
|
-
</button>
|
|
42
|
-
<button onClick={increment} className="btn btn-primary">
|
|
43
|
-
+ Increase
|
|
44
|
-
</button>
|
|
45
|
-
<button onClick={resetCount} className="btn btn-danger">
|
|
46
|
-
Reset
|
|
47
|
-
</button>
|
|
48
|
-
</div>
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
<div className="info-section">
|
|
52
|
-
<h3>Features Included:</h3>
|
|
53
|
-
<ul>
|
|
54
|
-
<li>✅ Modern JSX components</li>
|
|
55
|
-
<li>✅ State management with hooks</li>
|
|
56
|
-
<li>✅ Event handling</li>
|
|
57
|
-
<li>✅ Component lifecycle</li>
|
|
58
|
-
<li>✅ Responsive design</li>
|
|
59
|
-
</ul>
|
|
60
|
-
</div>
|
|
61
|
-
</main>
|
|
62
|
-
|
|
63
|
-
<footer className="app-footer">
|
|
64
|
-
<p>Built with ❤️ using Baraqex Framework</p>
|
|
65
|
-
</footer>
|
|
66
|
-
</div>
|
|
67
|
-
);
|
|
68
|
-
}
|