Skip to content

Commit dced39b

Browse files
development improve (#21)
* feat(version): add version on client * add version bump on github worflow * add version on footer * add update version script * chore(livePreview): add toggle button * chore(livePreview): allow more lib on livePreview
1 parent d9730b5 commit dced39b

File tree

9 files changed

+355
-46
lines changed

9 files changed

+355
-46
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Version Bump
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
jobs:
9+
version-bump:
10+
runs-on: ubuntu-latest
11+
12+
permissions:
13+
contents: write
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # Required to get all tags
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v4
23+
with:
24+
node-version: '20'
25+
26+
- name: Configure Git
27+
run: |
28+
git config --local user.email "github-actions[bot]@users.noreply.github.com"
29+
git config --local user.name "github-actions[bot]"
30+
31+
- name: Bump version and push tag
32+
id: bump_version
33+
uses: mathieudutour/github-tag-action@v6.1
34+
with:
35+
github_token: ${{ secrets.GITHUB_TOKEN }}
36+
default_bump: patch
37+
release_branches: main
38+
dry_run: false
39+
40+
- name: Update package.json with new version
41+
run: |
42+
npm version ${{ steps.bump_version.outputs.new_tag }} --no-git-tag-version
43+
44+
- name: Commit version bump
45+
run: |
46+
git add package.json
47+
git commit -m "chore: bump version to ${{ steps.bump_version.outputs.new_tag }}"
48+
git push
49+
50+
- name: Create GitHub Release
51+
uses: ncipollo/release-action@v1
52+
with:
53+
tag: ${{ steps.bump_version.outputs.new_tag }}
54+
name: Release ${{ steps.bump_version.outputs.new_tag }}
55+
body: ${{ steps.bump_version.outputs.changelog }}
56+
generateReleaseNotes: true

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
"private": true,
66
"scripts": {
77
"dev": "next dev --turbopack",
8-
"build": "next build",
8+
"build": "node scripts/update-version.js && next build",
99
"start": "next start",
1010
"lint": "next lint",
1111
"prebuild": "papi",
12-
"update-chains": "node scripts/update-chains.js"
12+
"update-chains": "node scripts/update-chains.js",
13+
"update-version": "node scripts/update-version.js",
14+
"postversion": "node scripts/update-version.js"
1315
},
1416
"dependencies": {
1517
"@babel/standalone": "^7.27.0",

scripts/update-version.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Script to update version and git hash automatically
5+
*/
6+
7+
const fs = require('fs');
8+
const path = require('path');
9+
const { execSync } = require('child_process');
10+
11+
12+
const packageJsonPath = path.join(process.cwd(), 'package.json');
13+
const packageJson = require(packageJsonPath);
14+
15+
16+
const currentVersion = packageJson.version;
17+
18+
19+
let gitHash = 'unknown';
20+
let gitBranch = 'unknown';
21+
try {
22+
gitHash = execSync('git rev-parse --short HEAD').toString().trim();
23+
gitBranch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
24+
} catch (error) {
25+
console.warn('Unable to get git information:', error.message);
26+
}
27+
28+
29+
const buildTime = new Date().toISOString();
30+
31+
32+
const versionInfo = {
33+
version: currentVersion,
34+
gitHash,
35+
gitBranch,
36+
buildTime,
37+
environment: process.env.NODE_ENV || 'development'
38+
};
39+
40+
41+
const versionFilePath = path.join(process.cwd(), 'src/version.json');
42+
fs.writeFileSync(versionFilePath, JSON.stringify(versionInfo, null, 2));
43+
44+
console.log('Version info updated:', versionInfo);
45+
46+
47+
const envFilePath = path.join(process.cwd(), '.env.local');
48+
const envContent = `NEXT_PUBLIC_VERSION=${currentVersion}
49+
NEXT_PUBLIC_GIT_HASH=${gitHash}
50+
NEXT_PUBLIC_BUILD_TIME=${buildTime}
51+
`;
52+
53+
54+
if (fs.existsSync(envFilePath)) {
55+
let existingContent = fs.readFileSync(envFilePath, 'utf8');
56+
57+
58+
existingContent = existingContent.replace(/NEXT_PUBLIC_VERSION=.*/g, '');
59+
existingContent = existingContent.replace(/NEXT_PUBLIC_GIT_HASH=.*/g, '');
60+
existingContent = existingContent.replace(/NEXT_PUBLIC_BUILD_TIME=.*/g, '');
61+
62+
63+
fs.writeFileSync(envFilePath, existingContent.trim() + '\n' + envContent);
64+
} else {
65+
fs.writeFileSync(envFilePath, envContent);
66+
}
67+
68+
console.log('Environment variables updated');

src/app/api/version/route.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { NextResponse } from 'next/server';
2+
import fs from 'fs';
3+
import path from 'path';
4+
5+
export const runtime = 'nodejs';
6+
export const dynamic = 'force-dynamic';
7+
8+
export async function GET() {
9+
try {
10+
11+
const versionFilePath = path.join(process.cwd(), 'src/version.json');
12+
13+
if (fs.existsSync(versionFilePath)) {
14+
const versionInfo = JSON.parse(fs.readFileSync(versionFilePath, 'utf8'));
15+
return NextResponse.json(versionInfo);
16+
}
17+
18+
return NextResponse.json({
19+
version: process.env.NEXT_PUBLIC_VERSION || "0.0.0",
20+
gitHash: process.env.NEXT_PUBLIC_GIT_HASH || "unknown",
21+
gitBranch: "main",
22+
buildTime: process.env.NEXT_PUBLIC_BUILD_TIME || new Date().toISOString(),
23+
environment: process.env.NODE_ENV || "development",
24+
});
25+
} catch (error) {
26+
console.error('Error fetching version info:', error);
27+
return NextResponse.json({
28+
version: "0.0.0",
29+
gitHash: "unknown",
30+
gitBranch: "main",
31+
buildTime: new Date().toISOString(),
32+
environment: process.env.NODE_ENV || "development",
33+
});
34+
}
35+
}

src/components/LivePreview/index.tsx

Lines changed: 91 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import React, {
1515
import { ErrorBoundary } from "react-error-boundary";
1616
import * as ts from "typescript";
1717
import type { Network } from "@/lib/types/network";
18+
import { MultiAddress, paseo, roc, wnd } from "@polkadot-api/descriptors";
19+
import { getWsProvider } from "polkadot-api/ws-provider/web";
20+
import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat";
21+
import { createClient } from "polkadot-api";
1822

1923
const ALLOWED_MODULES: Record<string, unknown> = {
2024
react: React,
@@ -23,6 +27,10 @@ const ALLOWED_MODULES: Record<string, unknown> = {
2327
jsx: React.createElement,
2428
jsxs: React.createElement,
2529
},
30+
"polkadot-api/ws-provider/web": { getWsProvider },
31+
"polkadot-api/polkadot-sdk-compat": { withPolkadotSdkCompat },
32+
"@polkadot-api/descriptors": { paseo, roc, wnd, MultiAddress },
33+
"polkadot-api": { createClient },
2634
};
2735

2836
const COMPILER_OPTIONS: ts.CompilerOptions = {
@@ -284,7 +292,7 @@ const evaluateComponent = (code: string) => {
284292
const component = normalizeComponent(result as Record<string, unknown>);
285293
if (!component) {
286294
throw new Error(
287-
`No valid component found. Exports analysis:\n${analyzeExports(result as Record<string, unknown>)}`,
295+
`No valid React component found. Please ensure your code exports a valid React component.\n\nExport analysis:\n${analyzeExports(result as Record<string, unknown>)}\n\nA valid React component can be:\n- A function component: const MyComponent = () => <div>Hello</div>\n- A class component: class MyComponent extends React.Component { ... }\n- Exported as default: export default MyComponent\n- A memo, forwardRef, or lazy component`,
288296
);
289297
}
290298
return { component, originalCode };
@@ -301,41 +309,84 @@ const ErrorFallback: React.FC<{ error: Error; originalCode?: string }> = ({
301309
<div
302310
style={{
303311
padding: "20px",
304-
backgroundColor: "rgba(255, 0, 0, 0.1)",
305-
borderRadius: "8px",
312+
backgroundColor: "rgba(255, 59, 48, 0.05)",
313+
borderRadius: "12px",
314+
border: "1px solid rgba(255, 59, 48, 0.2)",
306315
color: "#333",
307316
}}
308317
>
309-
<h3 style={{ color: "#d32f2f", marginTop: 0 }}>Erro no Componente</h3>
318+
<h3 style={{
319+
color: "#ff3b30",
320+
marginTop: 0,
321+
marginBottom: "12px",
322+
fontSize: "18px",
323+
fontWeight: 600,
324+
}}>
325+
Component Error
326+
</h3>
310327
<pre
311328
style={{
312-
backgroundColor: "#f5f5f5",
313-
padding: "15px",
314-
borderRadius: "6px",
329+
backgroundColor: "#f8f9fa",
330+
padding: "16px",
331+
borderRadius: "8px",
315332
overflowX: "auto",
333+
margin: "0 0 16px",
334+
fontSize: "14px",
335+
lineHeight: "1.5",
336+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
316337
}}
317338
>
318339
<code>{error.message}</code>
319340
</pre>
320341
{originalCode && (
321-
<details>
322-
<summary>Código Original</summary>
342+
<details style={{ marginTop: "16px" }}>
343+
<summary style={{
344+
cursor: "pointer",
345+
color: "#007aff",
346+
fontWeight: 500,
347+
padding: "8px 0",
348+
}}>
349+
View Original Code
350+
</summary>
323351
<pre
324352
style={{
325-
backgroundColor: "#f5f5f5",
326-
padding: "15px",
327-
borderRadius: "6px",
353+
backgroundColor: "#f8f9fa",
354+
padding: "16px",
355+
borderRadius: "8px",
328356
maxHeight: "300px",
329357
overflow: "auto",
358+
marginTop: "8px",
359+
fontSize: "14px",
360+
lineHeight: "1.5",
361+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
330362
}}
331363
>
332364
<code>{originalCode}</code>
333365
</pre>
334366
</details>
335367
)}
336-
<details style={{ marginTop: "15px" }}>
337-
<summary>Pilha de Erro Completa</summary>
338-
<pre style={{ whiteSpace: "pre-wrap", wordBreak: "break-word" }}>
368+
<details style={{ marginTop: "16px" }}>
369+
<summary style={{
370+
cursor: "pointer",
371+
color: "#007aff",
372+
fontWeight: 500,
373+
padding: "8px 0",
374+
}}>
375+
View Stack Trace
376+
</summary>
377+
<pre
378+
style={{
379+
whiteSpace: "pre-wrap",
380+
wordBreak: "break-word",
381+
backgroundColor: "#f8f9fa",
382+
padding: "16px",
383+
borderRadius: "8px",
384+
marginTop: "8px",
385+
fontSize: "14px",
386+
lineHeight: "1.5",
387+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
388+
}}
389+
>
339390
{error.stack}
340391
</pre>
341392
</details>
@@ -354,7 +405,7 @@ const LivePreview: React.FC<LivePreviewProps> = ({
354405
code,
355406
width = "100%",
356407
height = "auto",
357-
fallbackMessage = "Carregando Componente...",
408+
fallbackMessage = "Loading component...",
358409
}) => {
359410
const [componentData, setComponentData] = useState<{
360411
Component: ComponentType;
@@ -388,12 +439,14 @@ const LivePreview: React.FC<LivePreviewProps> = ({
388439
const containerStyle: React.CSSProperties = {
389440
width,
390441
height,
391-
border: "1px solid #ddd",
392-
borderRadius: "8px",
442+
border: "1px solid #e0e0e0",
443+
borderRadius: "12px",
393444
padding: "20px",
394-
backgroundColor: "rgba(255, 255, 255, 0.7)",
445+
backgroundColor: "rgba(255, 255, 255, 0.8)",
446+
backdropFilter: "blur(10px)",
395447
overflow: "auto",
396448
position: "relative",
449+
boxShadow: "0 2px 8px rgba(0, 0, 0, 0.05)",
397450
};
398451

399452
return (
@@ -408,14 +461,30 @@ const LivePreview: React.FC<LivePreviewProps> = ({
408461
)}
409462
>
410463
{loading ? (
411-
<div>{fallbackMessage}</div>
464+
<div style={{
465+
textAlign: "center",
466+
color: "#666",
467+
padding: "20px",
468+
fontFamily: "system-ui, -apple-system, sans-serif",
469+
}}>
470+
{fallbackMessage}
471+
</div>
412472
) : error ? (
413473
<ErrorFallback
414474
error={error}
415475
originalCode={componentData?.originalCode}
416476
/>
417477
) : componentData?.Component ? (
418-
<Suspense fallback={<div>{fallbackMessage}</div>}>
478+
<Suspense fallback={
479+
<div style={{
480+
textAlign: "center",
481+
color: "#666",
482+
padding: "20px",
483+
fontFamily: "system-ui, -apple-system, sans-serif",
484+
}}>
485+
{fallbackMessage}
486+
</div>
487+
}>
419488
{createElement(componentData.Component)}
420489
</Suspense>
421490
) : null}
@@ -424,4 +493,4 @@ const LivePreview: React.FC<LivePreviewProps> = ({
424493
);
425494
};
426495

427-
export default LivePreview;
496+
export default LivePreview;

0 commit comments

Comments
 (0)