Help me to think like a [better] coder

The solution depends on whether or not you want to specify the delay precisely or you can get away with just one minute/two minutes. If you need to specify it, say, down to the seconds, the best way would be to look into function pointers... (you can google that).

If you only care about distinguishing between 1 and 2 minute delays, that would be an overkill.

#define DIT 0
#define DAH 1
#define DELAY_1M 2
#define DELAY_2M 3
#define END 4


int pattern1[]={DIT, DIT, DAH, DELAY_1M, END};
int pattern1[]={DIT, DAH, DAH, DELAY_2M, DIT, END};

int* currentPattern=pattern1;


void pickPattern()
{
    //logic to check the buttons and see which pattern to pick, sets the global int* currentPattern.  Leave it alone (current pattern) if no button is pressed
    //if it's setting a new pattern (button is pressed), reset index to 0.
}


int index;

begin()
{
    index=0;
}

loop()
{
    
   pickPattern();
    if(currentPattern[index]!=END)
     {
           do_stuff(currentPattern[index]);
           index++;
     }
   else
    { 
        index=0;
    }

}

void doStuff(int stuff)//what a name!
{
switch(stuff)
{
case DIT:
dit();
break;
case DAH:
dah();
break;
case DELAY_1M:
del_1();
break;
//(...)
}
}

void del_1()
{
    for(int i=0;i<240;i++)//240*0.25 seconds=1 minute
    {
        delay(250);
        pickPattern();//see if we want to change the pattern 4 times a second. Or lower the delay and boost the for loop target number (240 now) accordingly. This could be done more enegantly using millis(), but this is okay too.
    }
}

Keep in mind this is pretty much a pseudocode...