mirror of
https://github.com/raidendotai/cofounder
synced 2025-01-22 10:36:17 +00:00
redux boilerplate placeholder
This commit is contained in:
parent
b88615fe5e
commit
b127f30724
@ -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
|
||||
|
@ -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 = ""
|
||||
|
@ -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
|
||||
|
@ -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';`;
|
||||
|
@ -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",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 61 KiB |
@ -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<string>) {
|
||||
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<RecipePreview[]>) => {
|
||||
state.latestRecipes = action.payload;
|
||||
state.loadingLatestRecipes = false;
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
fetchLatestRecipes.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
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<RecipePreview[]>) => {
|
||||
state.allRecipes = state.allRecipes
|
||||
? [...state.allRecipes, ...action.payload]
|
||||
: action.payload;
|
||||
state.loadingAllRecipes = false;
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
fetchAllRecipes.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
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<RecipeDetails>) => {
|
||||
state.recipeDetails = action.payload;
|
||||
state.loadingRecipeDetails = false;
|
||||
},
|
||||
);
|
||||
builder.addCase(
|
||||
fetchRecipeDetails.rejected,
|
||||
(state, action: PayloadAction<any>) => {
|
||||
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<typeof store.getState>;
|
||||
export type AppDispatch = typeof store.dispatch;
|
||||
|
||||
// Hook to access the redux store within a component
|
||||
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
||||
export const useAppSelector: (selector: (state: RootState) => any) => any =
|
||||
useSelector;
|
||||
|
||||
export default store;
|
||||
// Export the store as default
|
||||
export default store;
|
Loading…
Reference in New Issue
Block a user