diff --git a/README.md b/README.md index d0415fc..4c9554a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -![cofounder-og](https://github.com/user-attachments/assets/a9cda40f-0bf8-423b-815d-d8d6891f7ce3) +![cofounder-og-black](https://github.com/user-attachments/assets/b4e51f02-59e4-4540-ac14-e1f40e20a658) # Cofounder | Early alpha release @@ -12,7 +12,7 @@ -https://github.com/user-attachments/assets/b78d25aa-7cd3-49ee-a6f8-a952a77c8096 +https://github.com/user-attachments/assets/cfd09250-d21e-49fc-a29b-fa0c661abfc0 @@ -149,9 +149,8 @@ archi/v1 is as follows : --- -# Some Credits +# Credits -- Cover art edited from image found in [patriciaklein.de](https://patriciaklein.de) - Demo design systems built using Figma renders / UI kits from: * blocks.pm by Hexa Plugin (see `cofounder/api/system/presets`) * google material diff --git a/cofounder/api/.env b/cofounder/api/.env index 8171cd2..8ee2800 100644 --- a/cofounder/api/.env +++ b/cofounder/api/.env @@ -28,6 +28,9 @@ DESIGNER_DESIGN_SYSTEM = "presets/shadcn" #"presets/shadcn" # enables : code review after code generated , augment features like searching for external apis to implement in server , ... SWARM_ENABLE = TRUE +# OPTIONAL +COFOUNDER_NICKNAME = "Cofounder" + #STATE_CLOUD = TRUE # persist on cloud (firebase + cloudstorage) #FIREBASE_SERVICE_KEY_PATH = "" #GOOGLECLOUDSTORAGE_SERVICE_KEY_PATH = "" diff --git a/cofounder/api/system/functions/ux/datamap.js b/cofounder/api/system/functions/ux/datamap.js index 6ca95a2..1316f53 100644 --- a/cofounder/api/system/functions/ux/datamap.js +++ b/cofounder/api/system/functions/ux/datamap.js @@ -210,7 +210,7 @@ async function uxDatamapViews({ context, data }) { let tasks = []; - const UVs = Object.keys(uxsitemap.structure.views.unique); + const UVs = Object.keys(uxsitemap?.structure?.views?.unique) || {}; if (UVs.length) { _chunkify(UVs, 5).map((uniqueViewsIdsChunk) => { let filteredUxSitemap = { views: { unique: {} } }; @@ -227,7 +227,8 @@ async function uxDatamapViews({ context, data }) { }); }); } - const GVs = Object.keys(uxsitemap.structure.views.shared); + + const GVs = Object.keys(uxsitemap?.structure?.views?.shared) || {}; if (GVs.length) { tasks.push({ uxsitemap: { views: { shared: uxsitemap.structure.views.shared } }, // filtered ux sitemap with all shared views diff --git a/cofounder/api/system/functions/webapp/root.js b/cofounder/api/system/functions/webapp/root.js index 3007f7b..5a33bcd 100644 --- a/cofounder/api/system/functions/webapp/root.js +++ b/cofounder/api/system/functions/webapp/root.js @@ -10,8 +10,8 @@ async function promptRoot({ context, data }) { const { uxsitemap, uxdatamap, webapp } = data; const viewsImportHead = [ - ...Object.keys(uxsitemap.structure.views.shared), - ...Object.keys(uxsitemap.structure.views.unique), + ...( Object.keys(uxsitemap?.structure?.views?.shared) || {} ), + ...( Object.keys(uxsitemap?.structure?.views?.unique) || {} ), ] .map((viewId) => { return `import ${viewId} from '@/components/views/${viewId}.tsx';`; diff --git a/cofounder/api/system/functions/webapp/view.js b/cofounder/api/system/functions/webapp/view.js index 91a484a..9e0d356 100644 --- a/cofounder/api/system/functions/webapp/view.js +++ b/cofounder/api/system/functions/webapp/view.js @@ -16,7 +16,7 @@ async function webappViewGenerateMulti({ context, data }) { }; const tasks = [ - ...Object.keys(views.unique).map((viewId) => { + ...( Object.keys(views?.unique) || {} ).map((viewId) => { return { task: { type: "view", @@ -28,7 +28,7 @@ async function webappViewGenerateMulti({ context, data }) { }, }; }), - ...Object.keys(views.shared).map((viewId) => { + ...( Object.keys(views?.shared) || {} ).map((viewId) => { return { task: { type: "view", diff --git a/cofounder/boilerplate/vitereact-boilerplate/src/assets/cofounder.webp b/cofounder/boilerplate/vitereact-boilerplate/src/assets/cofounder.webp index dbb11d4..91965d5 100644 Binary files a/cofounder/boilerplate/vitereact-boilerplate/src/assets/cofounder.webp and b/cofounder/boilerplate/vitereact-boilerplate/src/assets/cofounder.webp differ diff --git a/cofounder/boilerplate/vitereact-boilerplate/src/store/main.tsx b/cofounder/boilerplate/vitereact-boilerplate/src/store/main.tsx index e396e38..741a92f 100644 --- a/cofounder/boilerplate/vitereact-boilerplate/src/store/main.tsx +++ b/cofounder/boilerplate/vitereact-boilerplate/src/store/main.tsx @@ -1,197 +1,9 @@ -import { - configureStore, - createSlice, - createAsyncThunk, - PayloadAction, -} from "@reduxjs/toolkit"; -import { useDispatch, useSelector } from "react-redux"; // Importing useDispatch and useSelector from react-redux +import { configureStore } from "@reduxjs/toolkit"; -// Define types directly here as any -type RecipePreview = any; -type RecipeDetails = any; - -interface AppState { - searchQuery: string; - latestRecipes: RecipePreview[] | null; - loadingLatestRecipes: boolean; - latestRecipesError: string | null; - allRecipes: RecipePreview[] | null; - loadingAllRecipes: boolean; - allRecipesError: string | null; - recipeDetails: RecipeDetails | null; - loadingRecipeDetails: boolean; - recipeDetailsError: string | null; -} - -// Initial state definition -const initialState: AppState = { - searchQuery: "", - latestRecipes: null, - loadingLatestRecipes: false, - latestRecipesError: null, - allRecipes: null, - loadingAllRecipes: false, - allRecipesError: null, - recipeDetails: null, - loadingRecipeDetails: false, - recipeDetailsError: null, -}; - -// Asynchronous Actions (Thunks) -export const fetchLatestRecipes = createAsyncThunk( - "recipes/fetchLatestRecipes", - async (_, { rejectWithValue }) => { - try { - const response = await fetch("http://localhost:1337/api/v1/recipes/latest"); - if (!response.ok) { - throw new Error("Failed to fetch latest recipes"); - } - const data: RecipePreview[] = await response.json(); - return data; - } catch (error) { - return rejectWithValue( - error instanceof Error ? error.message : "Unknown error", - ); - } - }, -); - -export const fetchAllRecipes = createAsyncThunk( - "recipes/fetchAllRecipes", - async ( - { offset = 0, limit = 20 }: { offset?: number; limit?: number }, - { rejectWithValue }, - ) => { - try { - const response = await fetch( - `http://localhost:1337/api/v1/recipes?offset=${offset}&limit=${limit}`, - ); - if (!response.ok) { - throw new Error("Failed to fetch recipes"); - } - const data: RecipePreview[] = await response.json(); - return data; - } catch (error) { - return rejectWithValue( - error instanceof Error ? error.message : "Unknown error", - ); - } - }, -); - -export const fetchRecipeDetails = createAsyncThunk( - "recipes/fetchRecipeDetails", - async (id: number, { rejectWithValue }) => { - try { - const response = await fetch(`http://localhost:1337/api/v1/recipes/${id}`); - if (!response.ok) { - throw new Error("Failed to fetch recipe details"); - } - const data: RecipeDetails = await response.json(); - return data; - } catch (error) { - return rejectWithValue( - error instanceof Error ? error.message : "Unknown error", - ); - } - }, -); - -// Slice -const recipeSlice = createSlice({ - name: "recipes", - initialState, - reducers: { - setSearchQuery(state, action: PayloadAction) { - state.searchQuery = action.payload; - }, - resetAllRecipes(state) { - state.allRecipes = null; - state.allRecipesError = null; - state.loadingAllRecipes = false; - }, - }, - extraReducers: (builder) => { - // Latest Recipes - builder.addCase(fetchLatestRecipes.pending, (state) => { - state.loadingLatestRecipes = true; - state.latestRecipesError = null; - }); - builder.addCase( - fetchLatestRecipes.fulfilled, - (state, action: PayloadAction) => { - state.latestRecipes = action.payload; - state.loadingLatestRecipes = false; - }, - ); - builder.addCase( - fetchLatestRecipes.rejected, - (state, action: PayloadAction) => { - state.loadingLatestRecipes = false; - state.latestRecipesError = action.payload; - }, - ); - - // All Recipes - builder.addCase(fetchAllRecipes.pending, (state) => { - state.loadingAllRecipes = true; - state.allRecipesError = null; - }); - builder.addCase( - fetchAllRecipes.fulfilled, - (state, action: PayloadAction) => { - state.allRecipes = state.allRecipes - ? [...state.allRecipes, ...action.payload] - : action.payload; - state.loadingAllRecipes = false; - }, - ); - builder.addCase( - fetchAllRecipes.rejected, - (state, action: PayloadAction) => { - state.loadingAllRecipes = false; - state.allRecipesError = action.payload; - }, - ); - - // Recipe Details - builder.addCase(fetchRecipeDetails.pending, (state) => { - state.loadingRecipeDetails = true; - state.recipeDetailsError = null; - }); - builder.addCase( - fetchRecipeDetails.fulfilled, - (state, action: PayloadAction) => { - state.recipeDetails = action.payload; - state.loadingRecipeDetails = false; - }, - ); - builder.addCase( - fetchRecipeDetails.rejected, - (state, action: PayloadAction) => { - state.loadingRecipeDetails = false; - state.recipeDetailsError = action.payload; - }, - ); - }, +// Create a Redux store +const store = configureStore({ + reducer: {}, // Empty reducer to prevent crashing }); -// Exports -export const { setSearchQuery, resetAllRecipes } = recipeSlice.actions; - -export const store = configureStore({ - reducer: { - recipes: recipeSlice.reducer, - }, -}); - -// Infer the `RootState` and `AppDispatch` types from the store itself -export type RootState = ReturnType; -export type AppDispatch = typeof store.dispatch; - -// Hook to access the redux store within a component -export const useAppDispatch = () => useDispatch(); -export const useAppSelector: (selector: (state: RootState) => any) => any = - useSelector; - -export default store; +// Export the store as default +export default store; \ No newline at end of file