Use this command in a command block or chat (with cheats enabled):
/give @p minecraft:bread{display:{Name:'{"text":"Sandwich","italic":false,"color":"gold"}',Lore:['{"text":"A tasty sandwich!","color":"gray"}']},CustomModelData:1} 1
This gives you a piece of bread renamed to “Sandwich” with lore and optional custom model data (used for custom textures via resource pack).
You can simulate crafting by detecting items in a chest and replacing them
# Detect if player puts bread + cooked beef + bread in a chest
execute if block ~ ~-1 ~ minecraft:chest{Items:[{id:"minecraft:bread"},{id:"minecraft:cooked_beef"},{id:"minecraft:bread"}]} run replaceitem block ~ ~-1 ~ slot.container.0 minecraft:bread{display:{Name:'{"text":"Sandwich"}'}} 1
Extra
You can place an item frame and put your sandwich in it like a decoration
/summon item_frame ~ ~ ~ {Item:{id:"minecraft:bread",Count:1b,tag:{display:{Name:'{"text":"Sandwich"}'}}}}
You can also:
Use a resource pack to make the “Sandwich” have a unique texture via CustomModelData.
Create a data pack that lets you craft it with real recipes.
Or use Minecraft mods (like CraftTweaker or Create) for real sandwich logic