LWJGL Binding texture to vertices

Hello, I started with lwjgl and openGL and I have problems binding a texture to a simple quad. The texture is stretched, that the whole quad has a uniform color, no matter what the texture is. I suspect that I use VAOs and VBOs incorrectly, but I don’t see my mistake:

First, the two shaders, which should be correct:
Vertex Shader:

#version 410

in vec3 position;
in vec2 textureCoords;

out vec2 pass_textureCoords;

void main(void){

    gl_Position = vec4(position,1.0);
    pass_textureCoords = textureCoords;
}

Fragment Shader:

#version 410

uniform sampler2D textureSampler;

in vec2 pass_textureCoords;

out vec4 out_Colour;

void main(void){
    out_Colour = texture(textureSampler,pass_textureCoords);
}

My vertices, indices and texture coordinates.

        float[] vertices = {
                -0.5f, 0.5f, 0f,  
                -0.5f, -0.5f, 0f,   
                0.5f, -0.5f, 0f,    
                0.5f, 0.5f, 0f     
        };

        int[] indices = {
                0, 1, 2,
                2, 3, 0
        };
        
        float[] textureCoords = {
                0,0,
                0,1,
                1,1,
                1,0
        };

How I load the texture:

    private int load(String path) {
        IntBuffer width = BufferUtils.createIntBuffer(1);
        IntBuffer height = BufferUtils.createIntBuffer(1);
        IntBuffer components = BufferUtils.createIntBuffer(1);
        ByteBuffer data = stbi_load(path,width,height,components,4);

        if (data == null)
            throw new RuntimeException("Could not load texture!");

        textureID = glGenTextures();

        this.width = width.get();
        this.height = height.get();

        glBindTexture(GL_TEXTURE_2D,textureID);

        glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

        glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,this.width,this.height,0,GL_RGBA,GL_UNSIGNED_BYTE,data);

        stbi_image_free(data);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        return textureID;
    }

How I create the VAOs and VBOs and store the indices, vertices and texture coordinates (I suppose that the error is here or/and in the renderer:)
I start by creating a VAO:

    private int createVAO(){
        int vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);
        return vaoID;
    }

I store the vertex coordinates first in a Buffer, and then in a VBO:


        FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
        buffer.put(data);
        buffer.flip(); //we finished writing, and prepare to read the data

        int vboID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER,vboID);
        FloatBuffer buffer = storeDataInFloatBuffer(data);
        glBufferData(GL_ARRAY_BUFFER,buffer,GL_STATIC_DRAW); //static data, we won't edit it
        glVertexAttribPointer(0,3, GL_FLOAT,false,0,0);
        glBindBuffer(GL_ARRAY_BUFFER,0);//unbind VBO
        glBindVertexArray(0);

I store the indices:

        int vboIndicesID = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vboIndicesID);
        IntBuffer buffer = storeDataInIntBuffer(indices); //the same as the FloatBuffer above
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,buffer,GL_STATIC_DRAW);
        glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);

and finally, I store my texture coordinates, with the same method as I use for the vertex coordinates, except for one line:


        glVertexAttribPointer(1,2, GL_FLOAT,false,0,0);

I finish by unbinding the VAO:

        glBindVertexArray(0);

The rendering part:
I bind the texture, I bind the VAO, I enable the VAO (although I’m not completely sure what this step does in the code), I then bind the VBO of the vertices and draw them using drawElements. At the end, I unbind everything:

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D,texturedModel.getTexture().getTextureID());

        // Bind to the VAO that has all the information about the vertices
        glBindVertexArray(model.getVaoID());
        glEnableVertexAttribArray(0);

        // Bind to the index VBO that has all the information about the order of the vertices
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.getVboIndicesID());
        
        // Draw the vertices
        glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);

        // Put everything back to default (deselect)
        glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        glDisableVertexAttribArray(0);

        glBindVertexArray(0);

Can anybody help me out here, what is wrong with this setup of storing data in VBOs and VAOs, as well as loading a texture? Thank you!