Switch to NextJS

This commit is contained in:
Lncvrt committed 2025-08-06 22:32:06 -07:00
1 parent 8c1ff8d1fc
commit 8d8758d04d
32 files changed
+2722 -840

No files matched your search

+39 -19
View File
@@ -1,24 +1,44 @@
# Logs
logs
*.log
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
.pnpm-debug.log*
node_modules
dist
dist-ssr
*.local
# env files (can opt-in for committing if needed)
.env*
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# vscode project settings
.vscode/settings.json
-11
View File
@@ -1,11 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/editor/main.tsx"></script>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import { FlatCompat } from '@eslint/eslintrc'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname
})
const eslintConfig = [
...compat.extends('next/core-web-vitals', 'next/typescript')
]
export default eslintConfig
-11
View File
@@ -1,11 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/newproject/main.tsx"></script>
</body>
</html>
+13
View File
@@ -0,0 +1,13 @@
import type { NextConfig } from 'next'
const isProd = process.env.NODE_ENV === 'production'
const internalHost = process.env.TAURI_DEV_HOST || 'localhost'
const nextConfig: NextConfig = {
output: 'export',
images: {
unoptimized: true
},
assetPrefix: isProd ? undefined : `http://${internalHost}:3000`
}
export default nextConfig
+10 -8
View File
@@ -4,30 +4,32 @@
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint",
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.7.0",
"@tauri-apps/plugin-dialog": "2.3.2",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1"
},
"devDependencies": {
"@fontsource/ubuntu": "5.2.6",
"@eslint/eslintrc": "3.3.1",
"@fortawesome/fontawesome-svg-core": "7.0.0",
"@fortawesome/free-solid-svg-icons": "7.0.0",
"@fortawesome/react-fontawesome": "0.2.3",
"@tailwindcss/postcss": "4.1.11",
"@tauri-apps/cli": "2.7.1",
"@types/node": "24.2.0",
"@types/react": "19.1.9",
"@types/react-dom": "19.1.7",
"@vitejs/plugin-react": "4.7.0",
"postcss": "8.5.6",
"eslint": "9.32.0",
"eslint-config-next": "15.4.6",
"tailwindcss": "4.1.11",
"typescript": "5.9.2",
"vite": "7.0.6"
"typescript": "5.9.2"
}
}
+4 -4
View File
@@ -1,5 +1,5 @@
export default {
plugins: {
'@tailwindcss/postcss': {}
}
const config = {
plugins: ['@tailwindcss/postcss']
}
export default config
-11
View File
@@ -1,11 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/projectmanager/main.tsx"></script>
</body>
</html>
View File
File renamed without changes.
+11 -3
View File
@@ -9,11 +9,19 @@ async fn create_project(project_type: String, project_folder: String, project_na
let project_type_str: &str = project_type.as_str();
match project_type_str {
"website" => {
let _ = fs::write(format!("{}/index.php", project_root), "<h1>this will be updated later</h1>").await;
let _ = fs::write(
format!("{}/index.php", project_root),
"<h1>this will be updated later</h1>",
)
.await;
}
"webserver" => {
let _ = fs::write(format!("{}/index.php", project_root), "<h1>this will be updated later</h1>").await;
let _ = fs::write(
format!("{}/index.php", project_root),
"<h1>this will be updated later</h1>",
)
.await;
}
_ => {}
@@ -35,7 +43,7 @@ pub fn run() {
tauri::webview::WebviewWindowBuilder::new(
app,
"main",
tauri::WebviewUrl::App("projectmanager.html".into()),
tauri::WebviewUrl::App("projectmanager/projects".into()),
)
.resizable(false)
.maximizable(false)
+2 -2
View File
@@ -5,9 +5,9 @@
"identifier": "xyz.lncvrt.php-fly",
"build": {
"beforeDevCommand": "yarn dev",
"devUrl": "http://localhost:1420",
"beforeBuildCommand": "yarn build",
"frontendDist": "../dist"
"devUrl": "http://localhost:3000",
"frontendDist": "../out"
},
"bundle": {
"active": true,
-1
View File
@@ -1,7 +1,6 @@
@import 'tailwindcss';
body {
font-family: 'Ubuntu', sans-serif;
@apply bg-[rgb(16,16,24)] text-white select-none;
}
+22
View File
@@ -0,0 +1,22 @@
'use client'
import React from 'react'
import './Globals.css'
import { Ubuntu } from 'next/font/google'
const ubuntu = Ubuntu({
weight: ['400'],
subsets: ['latin']
})
const Layout = ({ children }: { children: React.ReactNode }) => {
return (
<>
<html lang='en' className={ubuntu.className}>
<body>{children}</body>
</html>
</>
)
}
export default Layout
File renamed without changes.
@@ -1,10 +1,12 @@
'use client'
import { useEffect, useState } from 'react'
import OptionButtons from '../components/OptionButtons'
import './Home.css'
import OptionButtons from '@/components/OptionButtons'
import './NewProject_page.css'
import { documentDir } from '@tauri-apps/api/path'
import { open } from '@tauri-apps/plugin-dialog'
export default function Home () {
export default function NewProject_page () {
const [projectType, setProjectType] = useState<string>('empty')
const [projectFolder, setProjectFolder] = useState<string>('')
const [projectName, setProjectName] = useState<string>('')
@@ -49,6 +51,7 @@ export default function Home () {
<OptionButtons
buttons={[
<button
key='emptybutton'
onClick={() => setProjectType('empty')}
className='projecttypebutton'
disabled={projectType == 'empty'}
@@ -56,6 +59,7 @@ export default function Home () {
Empty
</button>,
<button
key='websitebutton'
onClick={() => setProjectType('website')}
className='projecttypebutton'
disabled={projectType == 'website'}
@@ -63,6 +67,7 @@ export default function Home () {
Website
</button>,
<button
key='webserverbutton'
onClick={() => setProjectType('webserver')}
className='projecttypebutton'
disabled={projectType == 'webserver'}
+66
View File
@@ -0,0 +1,66 @@
'use client'
import { useEffect, useState } from 'react'
import './ProjectManager_layout.css'
import { app } from '@tauri-apps/api'
import Image from 'next/image'
export default function Layout ({ children }: { children: React.ReactNode }) {
const [version, setVersion] = useState<string | null>(null)
const [rotation, setRotation] = useState<number>(0)
useEffect(() => {
;(async () => {
const tempVersion = await app.getVersion()
setVersion(tempVersion)
})()
}, [])
return (
<>
<div className='flex'>
<div className='sidebar'>
<Image
src='/Icon.png'
width={64}
height={64}
alt='CodeFly Logo'
className='m-2 transition-transform duration-[1.5s]'
draggable={false}
style={{
rotate: `${rotation}deg`
}}
onClick={() => {
setRotation(rotation + 1800)
}}
onContextMenu={() => {
setRotation(rotation - 1800)
}}
></Image>
<button
onClick={() =>
(window.location.pathname = '/projectmanager/projects')
}
>
Projects
</button>
<button
onClick={() =>
(window.location.pathname = '/projectmanager/settings')
}
>
Settings
</button>
{version != null && (
<p className='mt-auto mr-auto ml-2 mb-2 text-gray-400'>
PHP Fly v{version}
</p>
)}
</div>
<div className='relative z-0 flex-1'>
<main>{children}</main>
</div>
</div>
</>
)
}
@@ -1,5 +1,7 @@
'use client'
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
import './Projects.css'
import './ProjecftManager_projects.css'
export default function Projects () {
return (
@@ -15,7 +17,7 @@ export default function Projects () {
if (!mainWindow) return
const popup = new WebviewWindow('new_project_popup', {
title: 'PHP Fly: New Project',
url: '/newproject.html',
url: '/newproject',
width: 600,
height: 500,
resizable: false,
@@ -1,3 +1,5 @@
'use client'
export default function Settings () {
return (
<>
File renamed without changes.
@@ -1,3 +1,5 @@
'use client'
import { JSX } from 'react'
import './OptionButtons.css'
@@ -8,11 +10,9 @@ type OptionButtonsProps = {
export default function OptionButtons ({ buttons, name }: OptionButtonsProps) {
return (
<>
<div className='container'>
<h2 style={{ display: name == null ? 'none' : 'block' }}>{name}</h2>
<div className='flex gap-2'>{buttons}</div>
</div>
</>
)
}
-16
View File
@@ -1,16 +0,0 @@
import ReactDOM from 'react-dom/client'
import '@fontsource/ubuntu'
import '../Globals.css'
import Home from './routes/Home'
export default function App () {
return (
<>
<Home />
</>
)
}
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<App />
)
-3
View File
@@ -1,3 +0,0 @@
export default function Home () {
return <></>
}
-16
View File
@@ -1,16 +0,0 @@
import ReactDOM from 'react-dom/client'
import '@fontsource/ubuntu'
import '../Globals.css'
import Home from './routes/Home'
export default function App () {
return (
<>
<Home />
</>
)
}
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<App />
)
-50
View File
@@ -1,50 +0,0 @@
import './Sidebar.css'
import Icon from '../../Icon.png'
import { app } from '@tauri-apps/api'
import { useEffect, useState } from 'react'
export default function Sidebar () {
const [version, setVersion] = useState<string | null>(null)
const [rotation, setRotation] = useState<number>(0)
useEffect(() => {
;(async () => {
const tempVersion = await app.getVersion()
setVersion(tempVersion)
})()
}, [])
return (
<>
<div className='sidebar'>
<img
src={Icon}
width={64}
height={64}
className='m-2 transition-transform duration-[1.5s]'
draggable={false}
style={{
rotate: `${rotation}deg`
}}
onClick={() => {
setRotation(rotation + 1800)
}}
onContextMenu={() => {
setRotation(rotation - 1800)
}}
></img>
<button onClick={() => (window.location.hash = 'projects')}>
Projects
</button>
<button onClick={() => (window.location.hash = 'settings')}>
Settings
</button>
{version != null && (
<p className='mt-auto mr-auto ml-2 mb-2 text-gray-400'>
PHP Fly v{version}
</p>
)}
</div>
</>
)
}
-47
View File
@@ -1,47 +0,0 @@
import ReactDOM from 'react-dom/client'
import '@fontsource/ubuntu'
import '../Globals.css'
import Sidebar from './componets/Sidebar'
import { useEffect, useState } from 'react'
import Projects from './routes/Projects'
import Settings from './routes/Settings'
export default function App () {
const [hash, setHash] = useState(window.location.hash || '#projects')
useEffect(() => {
const onHashChange = () => setHash(window.location.hash || '#projects')
window.addEventListener('hashchange', onHashChange)
return () => window.removeEventListener('hashchange', onHashChange)
}, [])
useEffect(() => {
const handler = (e: MouseEvent) => e.preventDefault()
document.addEventListener('contextmenu', handler)
return () => document.removeEventListener('contextmenu', handler)
}, [])
function renderContent () {
if (hash === '#projects') {
return <Projects />
} else if (hash === '#settings') {
return <Settings />
}
return null
}
return (
<>
<div className='flex'>
<Sidebar />
<div className='relative z-0 flex-1'>
<main>{renderContent()}</main>
</div>
</div>
</>
)
}
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<App />
)
-1
View File
@@ -1 +0,0 @@
/// <reference types="vite/client" />
+32 -17
View File
@@ -1,25 +1,40 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"target": "ES2017",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
/* Bundler mode */
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
-10
View File
@@ -1,10 +0,0 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
-41
View File
@@ -1,41 +0,0 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// @ts-expect-error process is a nodejs global
const host = process.env.TAURI_DEV_HOST
// https://vitejs.dev/config/
export default defineConfig(async () => ({
plugins: [react()],
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
//
// 1. prevent vite from obscuring rust errors
clearScreen: false,
// 2. tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true,
host: host || false,
hmr: host
? {
protocol: 'ws',
host,
port: 1421
}
: undefined,
watch: {
// 3. tell vite to ignore watching `src-tauri`
ignored: ['**/src-tauri/**']
}
},
build: {
rollupOptions: {
input: {
editor: './editor.html',
projectmanager: './projectmanager.html',
newproject: './newproject.html'
}
}
}
}))
+2491 -562
View File
File diff suppressed because it is too large. Load diff