Switch to NextJS
This commit is contained in:
32 files changed
+2726
-844
No files matched your search
+39
-19
@@ -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
@@ -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>
|
||||
@@ -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
|
||||
@@ -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>
|
||||
@@ -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
@@ -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
@@ -1,5 +1,5 @@
|
||||
export default {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {}
|
||||
}
|
||||
const config = {
|
||||
plugins: ['@tailwindcss/postcss']
|
||||
}
|
||||
|
||||
export default config
|
||||
@@ -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>
|
||||
File renamed without changes.
+11
-3
@@ -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)
|
||||
|
||||
@@ -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,7 +1,6 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
body {
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
@apply bg-[rgb(16,16,24)] text-white select-none;
|
||||
}
|
||||
|
||||
@@ -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'}
|
||||
File renamed without changes.
@@ -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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
File renamed without changes.
@@ -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>
|
||||
</>
|
||||
<div className='container'>
|
||||
<h2 style={{ display: name == null ? 'none' : 'block' }}>{name}</h2>
|
||||
<div className='flex gap-2'>{buttons}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -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 />
|
||||
)
|
||||
@@ -1,3 +0,0 @@
|
||||
export default function Home () {
|
||||
return <></>
|
||||
}
|
||||
@@ -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 />
|
||||
)
|
||||
@@ -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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -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 />
|
||||
)
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
/// <reference types="vite/client" />
|
||||
+32
-17
@@ -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"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
Reference in new issue
Block a user