@@ -1237,6 +1237,63 @@ const StackBuilder = () => {
1237
1237
}
1238
1238
} ;
1239
1239
1240
+ const isOptionCompatible = (
1241
+ currentStack : StackState ,
1242
+ category : keyof typeof TECH_OPTIONS ,
1243
+ optionId : string ,
1244
+ ) : boolean => {
1245
+ const simulatedStack : StackState = JSON . parse ( JSON . stringify ( currentStack ) ) ;
1246
+
1247
+ const updateArrayCategory = ( arr : string [ ] , cat : string ) : string [ ] => {
1248
+ const isAlreadySelected = arr . includes ( optionId ) ;
1249
+
1250
+ if ( cat === "webFrontend" || cat === "nativeFrontend" ) {
1251
+ if ( isAlreadySelected ) {
1252
+ return optionId === "none" ? arr : [ "none" ] ;
1253
+ }
1254
+ if ( optionId === "none" ) return [ "none" ] ;
1255
+ return [ optionId ] ;
1256
+ }
1257
+
1258
+ const next : string [ ] = isAlreadySelected
1259
+ ? arr . filter ( ( id ) => id !== optionId )
1260
+ : [ ...arr . filter ( ( id ) => id !== "none" ) , optionId ] ;
1261
+
1262
+ if ( next . length === 0 ) return [ "none" ] ;
1263
+ return [ ...new Set ( next ) ] ;
1264
+ } ;
1265
+
1266
+ if (
1267
+ category === "webFrontend" ||
1268
+ category === "nativeFrontend" ||
1269
+ category === "addons" ||
1270
+ category === "examples"
1271
+ ) {
1272
+ const currentArr = Array . isArray ( simulatedStack [ category ] )
1273
+ ? [ ...( simulatedStack [ category ] as string [ ] ) ]
1274
+ : [ ] ;
1275
+ ( simulatedStack [ category ] as string [ ] ) = updateArrayCategory (
1276
+ currentArr ,
1277
+ category ,
1278
+ ) ;
1279
+ } else {
1280
+ ( simulatedStack [ category ] as string ) = optionId ;
1281
+ }
1282
+
1283
+ const { adjustedStack } = analyzeStackCompatibility ( simulatedStack ) ;
1284
+ const finalStack = adjustedStack ?? simulatedStack ;
1285
+
1286
+ if (
1287
+ category === "webFrontend" ||
1288
+ category === "nativeFrontend" ||
1289
+ category === "addons" ||
1290
+ category === "examples"
1291
+ ) {
1292
+ return ( finalStack [ category ] as string [ ] ) . includes ( optionId ) ;
1293
+ }
1294
+ return finalStack [ category ] === optionId ;
1295
+ } ;
1296
+
1240
1297
return (
1241
1298
< TooltipProvider >
1242
1299
< div
@@ -1493,6 +1550,12 @@ const StackBuilder = () => {
1493
1550
isSelected = currentValue === tech . id ;
1494
1551
}
1495
1552
1553
+ const isDisabled = ! isOptionCompatible (
1554
+ stack ,
1555
+ categoryKey as keyof typeof TECH_OPTIONS ,
1556
+ tech . id ,
1557
+ ) ;
1558
+
1496
1559
return (
1497
1560
< Tooltip key = { tech . id } delayDuration = { 100 } >
1498
1561
< TooltipTrigger asChild >
@@ -1501,7 +1564,9 @@ const StackBuilder = () => {
1501
1564
"relative cursor-pointer rounded border p-2 transition-all" ,
1502
1565
isSelected
1503
1566
? "border-primary bg-primary/10"
1504
- : "border-border hover:border-muted hover:bg-muted" ,
1567
+ : isDisabled
1568
+ ? "border-destructive/30 bg-destructive/5 opacity-50 hover:opacity-75"
1569
+ : "border-border hover:border-muted hover:bg-muted" ,
1505
1570
) }
1506
1571
whileHover = { { scale : 1.02 } }
1507
1572
whileTap = { { scale : 0.98 } }
0 commit comments