your code was almost good (even if blocking - if you don't have anything else to do that might be OK), you just forgot to set the pwmPin back to 0 when the 5s were done.
In the "solution code", the loop will call that endlessly (well for each cycle of the loop)
when the first 5s have elapsed and until the next button press and you get an extra 5s if you press the button while the motor is running which might or might not be part of the requirements.
A state machine approach (Here is a small introduction to the topic: Yet another Finite State Machine introduction) is a typical way to address those needs.
here is a state machine example
const byte buttonPin = 2;
const byte ledPin = 13;
const unsigned long duration = 5000;
enum {WAITING_FOR_PRESS, RUNNING} state = WAITING_FOR_PRESS;
unsigned long startTime;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
}
void loop() {
switch (state) {
case WAITING_FOR_PRESS:
if (digitalRead(buttonPin) == LOW) {
digitalWrite(ledPin, HIGH);
Serial.println("STARTING THE MOTOR");
startTime = millis();
state = RUNNING;
}
break;
case RUNNING:
if (millis() - startTime >= duration) {
digitalWrite(ledPin, LOW);
Serial.println("STOPPING THE MOTOR");
state = WAITING_FOR_PRESS;
}
break;
}
}
if you wanted to be able to prolong the duration to the next 5s during the run, you would just add a new event in the RUNNING case to respond to.
if (digitalRead(buttonPin) == LOW) startTime = millis(); // restart the chrono
this way the code exposes a clear vision of the state of the system (idle or running) and it's easy to extend the code to respond to specific events that might be specific to various states without making spaghetti code.