✨ Landing
This commit is contained in:
		| @@ -1,5 +1,5 @@ | ||||
| appId: com.electron.app | ||||
| productName: matrix-terminal | ||||
| appId: dev.solsynth.matrix | ||||
| productName: MatrixTerminal | ||||
| directories: | ||||
|   buildResources: build | ||||
| files: | ||||
| @@ -12,7 +12,7 @@ files: | ||||
| asarUnpack: | ||||
|   - resources/** | ||||
| win: | ||||
|   executableName: matrix-terminal | ||||
|   executableName: MatrixTerminal | ||||
| nsis: | ||||
|   artifactName: ${name}-${version}-setup.${ext} | ||||
|   shortcutName: ${productName} | ||||
| @@ -33,7 +33,7 @@ linux: | ||||
|     - AppImage | ||||
|     - snap | ||||
|     - deb | ||||
|   maintainer: electronjs.org | ||||
|   maintainer: solsynth.dev | ||||
|   category: Utility | ||||
| appImage: | ||||
|   artifactName: ${name}-${version}.${ext} | ||||
|   | ||||
| @@ -4,17 +4,17 @@ import react from '@vitejs/plugin-react' | ||||
|  | ||||
| export default defineConfig({ | ||||
|   main: { | ||||
|     plugins: [externalizeDepsPlugin()] | ||||
|     plugins: [externalizeDepsPlugin()], | ||||
|   }, | ||||
|   preload: { | ||||
|     plugins: [externalizeDepsPlugin()] | ||||
|     plugins: [externalizeDepsPlugin()], | ||||
|   }, | ||||
|   renderer: { | ||||
|     resolve: { | ||||
|       alias: { | ||||
|         '@renderer': resolve('src/renderer/src') | ||||
|       } | ||||
|         '@renderer': resolve('src/renderer/src'), | ||||
|       }, | ||||
|     }, | ||||
|     plugins: [react()] | ||||
|   } | ||||
|     plugins: [react()], | ||||
|   }, | ||||
| }) | ||||
|   | ||||
| @@ -28,7 +28,9 @@ | ||||
|     "@fontsource/roboto": "^5.1.1", | ||||
|     "@mui/icons-material": "^6.3.1", | ||||
|     "@mui/material": "^6.3.1", | ||||
|     "electron-updater": "^6.3.9" | ||||
|     "electron-updater": "^6.3.9", | ||||
|     "react-router": "^7.1.1", | ||||
|     "solar-js-sdk": "^0.1.2" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@electron-toolkit/eslint-config-prettier": "^2.0.0", | ||||
|   | ||||
| @@ -12,14 +12,16 @@ function createWindow(): void { | ||||
|     minHeight: 640, | ||||
|     show: false, | ||||
|     autoHideMenuBar: true, | ||||
|     title: 'MatrixTerminal', | ||||
|     ...(process.platform === 'linux' ? { icon } : {}), | ||||
|     webPreferences: { | ||||
|       preload: join(__dirname, '../preload/index.js'), | ||||
|       sandbox: false | ||||
|     } | ||||
|       sandbox: false, | ||||
|     }, | ||||
|   }) | ||||
|  | ||||
|   mainWindow.on('ready-to-show', () => { | ||||
|     mainWindow.title = 'MatrixTerminal' | ||||
|     mainWindow.show() | ||||
|   }) | ||||
|  | ||||
| @@ -42,7 +44,7 @@ function createWindow(): void { | ||||
| // Some APIs can only be used after this event occurs. | ||||
| app.whenReady().then(() => { | ||||
|   // Set app user model id for windows | ||||
|   electronApp.setAppUserModelId('com.electron') | ||||
|   electronApp.setAppUserModelId('dev.solsynth.matrix') | ||||
|  | ||||
|   // Default open or close DevTools by F12 in development | ||||
|   // and ignore CommandOrControl + R in production. | ||||
|   | ||||
| @@ -2,11 +2,11 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <title>Electron</title> | ||||
|     <title>MatrixTerminal</title> | ||||
|     <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP --> | ||||
|     <meta | ||||
|       http-equiv="Content-Security-Policy" | ||||
|       content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:" | ||||
|       content="connect-src 'self' * 'unsafe-eval'" | ||||
|     /> | ||||
|   </head> | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,20 @@ | ||||
| import { CssBaseline, ThemeProvider, createTheme } from '@mui/material' | ||||
| import { BrowserRouter, Route, Routes } from 'react-router' | ||||
| import { MaAppBar } from '@renderer/components/MaAppBar' | ||||
| import Landing from '@renderer/pages/Landing' | ||||
|  | ||||
| import { useUserStore } from 'solar-js-sdk' | ||||
| import { useEffect } from 'react' | ||||
|  | ||||
| function App(): JSX.Element { | ||||
|   // const ipcHandle = (): void => window.electron.ipcRenderer.send('ping') | ||||
|  | ||||
|   const userStore = useUserStore() | ||||
|  | ||||
|   useEffect(() => { | ||||
|     userStore.fetchUser() | ||||
|   }, []) | ||||
|  | ||||
|   const appTheme = createTheme({ | ||||
|     cssVariables: true, | ||||
|     colorSchemes: { | ||||
| @@ -21,8 +33,15 @@ function App(): JSX.Element { | ||||
|  | ||||
|   return ( | ||||
|     <ThemeProvider theme={appTheme}> | ||||
|       <CssBaseline /> | ||||
|       <span className="text-2xl">Hello, World!</span> | ||||
|       <BrowserRouter> | ||||
|         <CssBaseline /> | ||||
|  | ||||
|         <MaAppBar /> | ||||
|  | ||||
|         <Routes> | ||||
|           <Route path="/" element={<Landing />} /> | ||||
|         </Routes> | ||||
|       </BrowserRouter> | ||||
|     </ThemeProvider> | ||||
|   ) | ||||
| } | ||||
|   | ||||
							
								
								
									
										56
									
								
								src/renderer/src/components/MaAppBar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/renderer/src/components/MaAppBar.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| import { | ||||
|   AppBar, | ||||
|   Toolbar, | ||||
|   IconButton, | ||||
|   Typography, | ||||
|   Drawer, | ||||
|   List, | ||||
|   ListItem, | ||||
|   ListItemButton, | ||||
|   ListItemIcon, | ||||
|   ListItemText, | ||||
| } from '@mui/material' | ||||
| import { useState } from 'react' | ||||
|  | ||||
| import GamepadIcon from '@mui/icons-material/Gamepad' | ||||
|  | ||||
| export function MaAppBar(): JSX.Element { | ||||
|   const [open, setOpen] = useState(false) | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       <Drawer open={open} onClose={() => setOpen(false)} sx={{ width: '320px' }}> | ||||
|         <List sx={{ width: '320px' }}> | ||||
|           {['Inbox', 'Starred', 'Send email', 'Drafts'].map((text) => ( | ||||
|             <ListItem key={text} disablePadding> | ||||
|               <ListItemButton> | ||||
|                 <ListItemIcon> | ||||
|                   <GamepadIcon /> | ||||
|                 </ListItemIcon> | ||||
|                 <ListItemText primary={text} /> | ||||
|               </ListItemButton> | ||||
|             </ListItem> | ||||
|           ))} | ||||
|         </List> | ||||
|       </Drawer> | ||||
|  | ||||
|       <AppBar position="static"> | ||||
|         <Toolbar> | ||||
|           <IconButton | ||||
|             size="large" | ||||
|             edge="start" | ||||
|             color="inherit" | ||||
|             aria-label="menu" | ||||
|             sx={{ mr: 2 }} | ||||
|             onClick={() => setOpen(true)} | ||||
|           > | ||||
|             <GamepadIcon /> | ||||
|           </IconButton> | ||||
|           <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}> | ||||
|             Matrix | ||||
|           </Typography> | ||||
|         </Toolbar> | ||||
|       </AppBar> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
| @@ -8,5 +8,5 @@ import App from './App' | ||||
| ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( | ||||
|   <React.StrictMode> | ||||
|     <App /> | ||||
|   </React.StrictMode> | ||||
|   </React.StrictMode>, | ||||
| ) | ||||
|   | ||||
							
								
								
									
										81
									
								
								src/renderer/src/pages/Landing.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/renderer/src/pages/Landing.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| import { | ||||
|   Box, | ||||
|   Container, | ||||
|   Typography, | ||||
|   Grid2 as Grid, | ||||
|   Card, | ||||
|   CardContent, | ||||
|   CardMedia, | ||||
|   CardActionArea, | ||||
|   Avatar, | ||||
| } from '@mui/material' | ||||
| import { useEffect, useState } from 'react' | ||||
| import { MaProduct, getAttachmentUrl, sni } from 'solar-js-sdk' | ||||
|  | ||||
| export default function Landing(): JSX.Element { | ||||
|   const [products, setProducts] = useState<MaProduct[]>([]) | ||||
|  | ||||
|   async function fetchProducts(): Promise<void> { | ||||
|     const { data: resp } = await sni.get<{ data: MaProduct[] }>('/cgi/ma/products', { | ||||
|       params: { | ||||
|         take: 10, | ||||
|       }, | ||||
|     }) | ||||
|     setProducts(resp.data) | ||||
|   } | ||||
|  | ||||
|   useEffect(() => { | ||||
|     fetchProducts() | ||||
|   }, []) | ||||
|  | ||||
|   return ( | ||||
|     <Container sx={{ py: 8, display: 'flex', flexDirection: 'column', gap: 2 }}> | ||||
|       <Box> | ||||
|         <Typography variant="h4" component="div" sx={{ mb: 2 }}> | ||||
|           Matrix Marketplace | ||||
|         </Typography> | ||||
|       </Box> | ||||
|  | ||||
|       <Grid container columns={{ xs: 1, sm: 2, md: 3 }} spacing={2}> | ||||
|         {products.map((p) => ( | ||||
|           <Grid size={1} key={p.id}> | ||||
|             <Card> | ||||
|               <CardActionArea> | ||||
|                 {p.previews && ( | ||||
|                   <CardMedia | ||||
|                     sx={{ aspectRatio: 16 / 5 }} | ||||
|                     image={getAttachmentUrl(p.previews[0])} | ||||
|                     title="green iguana" | ||||
|                   /> | ||||
|                 )} | ||||
|                 <CardContent> | ||||
|                   {p.icon && ( | ||||
|                     <Avatar | ||||
|                       variant="rounded" | ||||
|                       src={getAttachmentUrl(p.icon)} | ||||
|                       sx={{ | ||||
|                         width: 48, | ||||
|                         height: 48, | ||||
|                         border: 1, | ||||
|                         borderColor: 'divider', | ||||
|                         borderRadius: 4, | ||||
|                         mb: 0.75, | ||||
|                         mx: '-4px', | ||||
|                       }} | ||||
|                     /> | ||||
|                   )} | ||||
|                   <Typography variant="h5" component="div"> | ||||
|                     {p.name} | ||||
|                   </Typography> | ||||
|                   <Typography variant="body2" component="div"> | ||||
|                     {p.description} | ||||
|                   </Typography> | ||||
|                 </CardContent> | ||||
|               </CardActionArea> | ||||
|             </Card> | ||||
|           </Grid> | ||||
|         ))} | ||||
|       </Grid> | ||||
|     </Container> | ||||
|   ) | ||||
| } | ||||
| @@ -6,4 +6,3 @@ module.exports = { | ||||
|   }, | ||||
|   plugins: [], | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user